Add more internal errors to wuffs_aux Cbor, Json
diff --git a/internal/cgen/auxiliary/cbor.cc b/internal/cgen/auxiliary/cbor.cc
index 3beba20..4591195 100644
--- a/internal/cgen/auxiliary/cbor.cc
+++ b/internal/cgen/auxiliary/cbor.cc
@@ -57,7 +57,7 @@
// Prepare the low-level CBOR decoder.
wuffs_cbor__decoder::unique_ptr dec = wuffs_cbor__decoder::alloc();
if (!dec) {
- ret_error_message = "wuffs_aux::CborDecoder: out of memory";
+ ret_error_message = "wuffs_aux::DecodeCbor: out of memory";
goto done;
}
for (size_t i = 0; i < quirks.len; i++) {
@@ -72,7 +72,7 @@
wuffs_base__status tok_status = wuffs_base__make_status(nullptr);
// Prepare other state.
- uint32_t depth = 0;
+ int32_t depth = 0;
std::string str;
int64_t extension_category = 0;
uint64_t extension_detail = 0;
@@ -99,17 +99,17 @@
goto done;
} else if (cursor_index != io_buf->meta.ri) {
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: bad cursor_index";
+ "wuffs_aux::DecodeCbor: internal error: bad cursor_index";
goto done;
} else if (io_buf->meta.closed) {
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: io_buf is closed";
+ "wuffs_aux::DecodeCbor: internal error: io_buf is closed";
goto done;
}
io_buf->compact();
if (io_buf->meta.wi >= io_buf->data.len) {
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: io_buf is full";
+ "wuffs_aux::DecodeCbor: internal error: io_buf is full";
goto done;
}
cursor_index = io_buf->meta.ri;
@@ -121,11 +121,19 @@
if (WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: bad WORKBUF_LEN";
+ "wuffs_aux::DecodeCbor: internal error: bad WORKBUF_LEN";
goto done;
}
wuffs_base__slice_u8 work_buf = wuffs_base__empty_slice_u8();
tok_status = dec->decode_tokens(&tok_buf, io_buf, work_buf);
+ if ((tok_buf.meta.ri > tok_buf.meta.wi) ||
+ (tok_buf.meta.wi > tok_buf.data.len) ||
+ (io_buf->meta.ri > io_buf->meta.wi) ||
+ (io_buf->meta.wi > io_buf->data.len)) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: bad buffer indexes";
+ goto done;
+ }
}
wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];
@@ -133,7 +141,7 @@
if ((io_buf->meta.ri < cursor_index) ||
((io_buf->meta.ri - cursor_index) < token_len)) {
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: bad token indexes";
+ "wuffs_aux::DecodeCbor: internal error: bad token indexes";
goto done;
}
uint8_t* token_ptr = io_buf->data.ptr + cursor_index;
@@ -169,7 +177,7 @@
}
}
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: bad extended token";
+ "wuffs_aux::DecodeCbor: internal error: bad extended token";
goto done;
}
@@ -184,10 +192,20 @@
goto done;
}
depth++;
+ if (depth > WUFFS_CBOR__DECODER_DEPTH_MAX_INCL) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: bad depth";
+ goto done;
+ }
continue;
}
ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
depth--;
+ if (depth < 0) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: bad depth";
+ goto done;
+ }
goto parsed_a_value;
}
@@ -324,7 +342,7 @@
fail:
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: unexpected token";
+ "wuffs_aux::DecodeCbor: internal error: unexpected token";
goto done;
parsed_a_value:
diff --git a/internal/cgen/auxiliary/json.cc b/internal/cgen/auxiliary/json.cc
index 64326d6..82281f1 100644
--- a/internal/cgen/auxiliary/json.cc
+++ b/internal/cgen/auxiliary/json.cc
@@ -34,9 +34,10 @@
sync_io::Input& input,
IOBuffer& buffer) {}
-const char DecodeJson_BadJsonPointer[] =
+const char DecodeJson_BadJsonPointer[] = //
"wuffs_aux::DecodeJson: bad JSON Pointer";
-const char DecodeJson_NoMatch[] = "wuffs_aux::DecodeJson: no match";
+const char DecodeJson_NoMatch[] = //
+ "wuffs_aux::DecodeJson: no match";
// --------
@@ -73,6 +74,14 @@
} \
tok_status = \
dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8()); \
+ if ((tok_buf.meta.ri > tok_buf.meta.wi) || \
+ (tok_buf.meta.wi > tok_buf.data.len) || \
+ (io_buf->meta.ri > io_buf->meta.wi) || \
+ (io_buf->meta.wi > io_buf->data.len)) { \
+ ret_error_message = \
+ "wuffs_aux::DecodeJson: internal error: bad buffer indexes"; \
+ goto done; \
+ } \
} \
wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++]; \
uint64_t token_len = token.length(); \
@@ -91,7 +100,8 @@
namespace {
// DecodeJson_SplitJsonPointer returns ("bar", 8) for ("/foo/bar/b~1z/qux", 5,
-// etc). It returns a 0 size_t when s has invalid JSON Pointer syntax.
+// etc). It returns a 0 size_t when s has invalid JSON Pointer syntax or i is
+// out of bounds.
//
// The string returned is unescaped. If calling it again, this time with i=8,
// the "b~1z" substring would be returned as "b/z".
@@ -100,6 +110,9 @@
size_t i,
bool allow_tilde_n_tilde_r_tilde_t) {
std::string fragment;
+ if (i > s.size()) {
+ return std::make_pair(std::string(), 0);
+ }
while (i < s.size()) {
char c = s[i];
if (c == '/') {
@@ -306,8 +319,8 @@
continue;
}
- // Undo the last part of WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN, so that
- // we're only peeking at the next token.
+ // Undo the last part of WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN, so
+ // that we're only peeking at the next token.
tok_buf.meta.ri--;
cursor_index -= static_cast<size_t>(token_len);
@@ -377,7 +390,7 @@
dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());
// Prepare other state.
- uint32_t depth = 0;
+ int32_t depth = 0;
std::string str;
// Walk the (optional) JSON Pointer.
@@ -420,10 +433,20 @@
goto done;
}
depth++;
+ if (depth > WUFFS_JSON__DECODER_DEPTH_MAX_INCL) {
+ ret_error_message =
+ "wuffs_aux::DecodeJson: internal error: bad depth";
+ goto done;
+ }
continue;
}
ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
depth--;
+ if (depth < 0) {
+ ret_error_message =
+ "wuffs_aux::DecodeJson: internal error: bad depth";
+ goto done;
+ }
goto parsed_a_value;
}
diff --git a/internal/cgen/data/data.go b/internal/cgen/data/data.go
index cf2d6af..aef0227 100644
--- a/internal/cgen/data/data.go
+++ b/internal/cgen/data/data.go
@@ -802,18 +802,18 @@
const AuxCborCc = "" +
"// ---------------- Auxiliary - CBOR\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__CBOR)\n\n#include <utility>\n\nnamespace wuffs_aux {\n\nDecodeCborResult::DecodeCborResult(std::string&& error_message0,\n uint64_t cursor_position0)\n : error_message(std::move(error_message0)),\n cursor_position(cursor_position0) {}\n\nDecodeCborCallbacks::~DecodeCborCallbacks() {}\n\nvoid //\nDecodeCborCallbacks::Done(DecodeCborResult& result,\n sync_io::Input& input,\n IOBuffer& buffer) {}\n\nDecodeCborResult //\nDecodeCbor(DecodeCborCallbacks& callbacks,\n sync_io::Input& input,\n wuffs_base__slice_u32 quirks) {\n // Prepare the wuffs_base__io_buffer and the resultant error_message.\n wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();\n wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();\n std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);\n if (!io_buf) {\n fallback_" +
- "io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);\n fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);\n io_buf = &fallback_io_buf;\n }\n // cursor_index is discussed at\n // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index\n size_t cursor_index = 0;\n std::string ret_error_message;\n std::string io_error_message;\n\n do {\n // Prepare the low-level CBOR decoder.\n wuffs_cbor__decoder::unique_ptr dec = wuffs_cbor__decoder::alloc();\n if (!dec) {\n ret_error_message = \"wuffs_aux::CborDecoder: out of memory\";\n goto done;\n }\n for (size_t i = 0; i < quirks.len; i++) {\n dec->set_quirk_enabled(quirks.ptr[i], true);\n }\n\n // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.\n wuffs_base__token tok_array[256];\n wuffs_base__token_buffer tok_buf =\n wuffs_base__slice_token__writer(wuffs_base__make_slice_token(\n &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));\n wuffs_base__status tok_status = " +
- "wuffs_base__make_status(nullptr);\n\n // Prepare other state.\n uint32_t depth = 0;\n std::string str;\n int64_t extension_category = 0;\n uint64_t extension_detail = 0;\n\n // Valid token's VBCs range in 0 ..= 15. Values over that are for tokens\n // from outside of the base package, such as the CBOR package.\n constexpr int64_t EXT_CAT__CBOR_TAG = 16;\n\n // Loop, doing these two things:\n // 1. Get the next token.\n // 2. Process that token.\n while (true) {\n // 1. Get the next token.\n\n while (tok_buf.meta.ri >= tok_buf.meta.wi) {\n if (tok_status.repr == nullptr) {\n // No-op.\n } else if (tok_status.repr == wuffs_base__suspension__short_write) {\n tok_buf.compact();\n } else if (tok_status.repr == wuffs_base__suspension__short_read) {\n // Read from input to io_buf.\n if (!io_error_message.empty()) {\n ret_error_message = std::move(io_error_message);\n goto done;\n } else if (cursor_index != io_" +
- "buf->meta.ri) {\n ret_error_message =\n \"wuffs_aux::CborDecoder: internal error: bad cursor_index\";\n goto done;\n } else if (io_buf->meta.closed) {\n ret_error_message =\n \"wuffs_aux::CborDecoder: internal error: io_buf is closed\";\n goto done;\n }\n io_buf->compact();\n if (io_buf->meta.wi >= io_buf->data.len) {\n ret_error_message =\n \"wuffs_aux::CborDecoder: internal error: io_buf is full\";\n goto done;\n }\n cursor_index = io_buf->meta.ri;\n io_error_message = input.CopyIn(io_buf);\n } else {\n ret_error_message = tok_status.message();\n goto done;\n }\n\n if (WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {\n ret_error_message =\n \"wuffs_aux::CborDecoder: internal error: bad WORKBUF_LEN\";\n goto done;\n }\n wuffs_base__slice_u8 work_buf = wuffs_base__empty_slice_u8(" +
- ");\n tok_status = dec->decode_tokens(&tok_buf, io_buf, work_buf);\n }\n\n wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];\n uint64_t token_len = token.length();\n if ((io_buf->meta.ri < cursor_index) ||\n ((io_buf->meta.ri - cursor_index) < token_len)) {\n ret_error_message =\n \"wuffs_aux::CborDecoder: internal error: bad token indexes\";\n goto done;\n }\n uint8_t* token_ptr = io_buf->data.ptr + cursor_index;\n cursor_index += static_cast<size_t>(token_len);\n\n // 2. Process that token.\n\n uint64_t vbd = token.value_base_detail();\n\n if (extension_category != 0) {\n int64_t ext = token.value_extension();\n if ((ext >= 0) && !token.continued()) {\n extension_detail = (extension_detail\n << WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS) |\n static_cast<uint64_t>(ext);\n switch (extension_category) {\n case WUFFS_BASE__TOKEN__VBC__IN" +
- "LINE_INTEGER_SIGNED:\n extension_category = 0;\n ret_error_message =\n callbacks.AppendI64(static_cast<int64_t>(extension_detail));\n goto parsed_a_value;\n case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED:\n extension_category = 0;\n ret_error_message = callbacks.AppendU64(extension_detail);\n goto parsed_a_value;\n case EXT_CAT__CBOR_TAG:\n extension_category = 0;\n ret_error_message = callbacks.AppendCborTag(extension_detail);\n if (!ret_error_message.empty()) {\n goto done;\n }\n continue;\n }\n }\n ret_error_message =\n \"wuffs_aux::CborDecoder: internal error: bad extended token\";\n goto done;\n }\n\n switch (token.value_base_category()) {\n case WUFFS_BASE__TOKEN__VBC__FILLER:\n continue;\n\n case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {\n if (vbd & WUFFS_" +
- "BASE__TOKEN__VBD__STRUCTURE__PUSH) {\n ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));\n if (!ret_error_message.empty()) {\n goto done;\n }\n depth++;\n continue;\n }\n ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));\n depth--;\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__STRING: {\n if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {\n // No-op.\n } else if (vbd &\n WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {\n const char* ptr = // Convert from (uint8_t*).\n static_cast<const char*>(static_cast<void*>(token_ptr));\n str.append(ptr, static_cast<size_t>(token_len));\n } else {\n goto fail;\n }\n if (token.continued()) {\n continue;\n }\n ret_error_message =\n (vbd & WUFFS_BASE__T" +
- "OKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8)\n ? callbacks.AppendTextString(std::move(str))\n : callbacks.AppendByteString(std::move(str));\n str.clear();\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {\n uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];\n size_t n = wuffs_base__utf_8__encode(\n wuffs_base__make_slice_u8(\n &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),\n static_cast<uint32_t>(vbd));\n const char* ptr = // Convert from (uint8_t*).\n static_cast<const char*>(static_cast<void*>(&u[0]));\n str.append(ptr, n);\n if (token.continued()) {\n continue;\n }\n goto fail;\n }\n\n case WUFFS_BASE__TOKEN__VBC__LITERAL: {\n if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL) {\n ret_error_message = callbacks.AppendNull();\n } else if (vbd & WUFFS_BASE__TOKEN__VBD_" +
- "_LITERAL__UNDEFINED) {\n ret_error_message = callbacks.AppendUndefined();\n } else {\n ret_error_message = callbacks.AppendBool(\n vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);\n }\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__NUMBER: {\n const uint64_t cfp_fbbe_fifb =\n WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT |\n WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN |\n WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE;\n if ((vbd & cfp_fbbe_fifb) == cfp_fbbe_fifb) {\n double f;\n switch (token_len) {\n case 3:\n f = wuffs_base__ieee_754_bit_representation__from_u16_to_f64(\n wuffs_base__peek_u16be__no_bounds_check(token_ptr + 1));\n break;\n case 5:\n f = wuffs_base__ieee_754_bit_representation__from_u32_to_f64(\n wuffs_base__peek" +
- "_u32be__no_bounds_check(token_ptr + 1));\n break;\n case 9:\n f = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));\n break;\n default:\n goto fail;\n }\n ret_error_message = callbacks.AppendF64(f);\n goto parsed_a_value;\n }\n goto fail;\n }\n\n case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED: {\n if (token.continued()) {\n extension_category = WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED;\n extension_detail =\n static_cast<uint64_t>(token.value_base_detail__sign_extended());\n continue;\n }\n ret_error_message =\n callbacks.AppendI64(token.value_base_detail__sign_extended());\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED: {\n if (token.continu" +
- "ed()) {\n extension_category =\n WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED;\n extension_detail = vbd;\n continue;\n }\n ret_error_message = callbacks.AppendU64(vbd);\n goto parsed_a_value;\n }\n }\n\n if (token.value_major() == WUFFS_CBOR__TOKEN_VALUE_MAJOR) {\n uint64_t value_minor = token.value_minor();\n if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X) {\n if (token_len == 9) {\n ret_error_message = callbacks.AppendMinus1MinusX(\n wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));\n goto parsed_a_value;\n }\n } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE) {\n ret_error_message =\n callbacks.AppendCborSimpleValue(static_cast<uint8_t>(\n value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK));\n goto parsed_a_value;\n } else if (value_minor & WUFFS_CBOR__TOKE" +
- "N_VALUE_MINOR__TAG) {\n if (token.continued()) {\n extension_category = EXT_CAT__CBOR_TAG;\n extension_detail =\n value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK;\n continue;\n }\n ret_error_message = callbacks.AppendCborTag(\n value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK);\n if (!ret_error_message.empty()) {\n goto done;\n }\n continue;\n }\n }\n\n fail:\n ret_error_message =\n \"wuffs_aux::CborDecoder: internal error: unexpected token\";\n goto done;\n\n parsed_a_value:\n if (!ret_error_message.empty() || (depth == 0)) {\n goto done;\n }\n }\n } while (false);\n\ndone:\n DecodeCborResult result(\n std::move(ret_error_message),\n wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));\n callbacks.Done(result, input, *io_buf);\n return result;\n}\n\n} // namespace wuffs_aux\n\n#endif // !defined(WUFFS_CONFIG__MODULES) ||\n " +
- "// defined(WUFFS_CONFIG__MODULE__AUX__CBOR)\n" +
+ "io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);\n fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);\n io_buf = &fallback_io_buf;\n }\n // cursor_index is discussed at\n // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index\n size_t cursor_index = 0;\n std::string ret_error_message;\n std::string io_error_message;\n\n do {\n // Prepare the low-level CBOR decoder.\n wuffs_cbor__decoder::unique_ptr dec = wuffs_cbor__decoder::alloc();\n if (!dec) {\n ret_error_message = \"wuffs_aux::DecodeCbor: out of memory\";\n goto done;\n }\n for (size_t i = 0; i < quirks.len; i++) {\n dec->set_quirk_enabled(quirks.ptr[i], true);\n }\n\n // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.\n wuffs_base__token tok_array[256];\n wuffs_base__token_buffer tok_buf =\n wuffs_base__slice_token__writer(wuffs_base__make_slice_token(\n &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));\n wuffs_base__status tok_status = w" +
+ "uffs_base__make_status(nullptr);\n\n // Prepare other state.\n int32_t depth = 0;\n std::string str;\n int64_t extension_category = 0;\n uint64_t extension_detail = 0;\n\n // Valid token's VBCs range in 0 ..= 15. Values over that are for tokens\n // from outside of the base package, such as the CBOR package.\n constexpr int64_t EXT_CAT__CBOR_TAG = 16;\n\n // Loop, doing these two things:\n // 1. Get the next token.\n // 2. Process that token.\n while (true) {\n // 1. Get the next token.\n\n while (tok_buf.meta.ri >= tok_buf.meta.wi) {\n if (tok_status.repr == nullptr) {\n // No-op.\n } else if (tok_status.repr == wuffs_base__suspension__short_write) {\n tok_buf.compact();\n } else if (tok_status.repr == wuffs_base__suspension__short_read) {\n // Read from input to io_buf.\n if (!io_error_message.empty()) {\n ret_error_message = std::move(io_error_message);\n goto done;\n } else if (cursor_index != io_bu" +
+ "f->meta.ri) {\n ret_error_message =\n \"wuffs_aux::DecodeCbor: internal error: bad cursor_index\";\n goto done;\n } else if (io_buf->meta.closed) {\n ret_error_message =\n \"wuffs_aux::DecodeCbor: internal error: io_buf is closed\";\n goto done;\n }\n io_buf->compact();\n if (io_buf->meta.wi >= io_buf->data.len) {\n ret_error_message =\n \"wuffs_aux::DecodeCbor: internal error: io_buf is full\";\n goto done;\n }\n cursor_index = io_buf->meta.ri;\n io_error_message = input.CopyIn(io_buf);\n } else {\n ret_error_message = tok_status.message();\n goto done;\n }\n\n if (WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {\n ret_error_message =\n \"wuffs_aux::DecodeCbor: internal error: bad WORKBUF_LEN\";\n goto done;\n }\n wuffs_base__slice_u8 work_buf = wuffs_base__empty_slice_u8();\n " +
+ " tok_status = dec->decode_tokens(&tok_buf, io_buf, work_buf);\n if ((tok_buf.meta.ri > tok_buf.meta.wi) ||\n (tok_buf.meta.wi > tok_buf.data.len) ||\n (io_buf->meta.ri > io_buf->meta.wi) ||\n (io_buf->meta.wi > io_buf->data.len)) {\n ret_error_message =\n \"wuffs_aux::DecodeCbor: internal error: bad buffer indexes\";\n goto done;\n }\n }\n\n wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];\n uint64_t token_len = token.length();\n if ((io_buf->meta.ri < cursor_index) ||\n ((io_buf->meta.ri - cursor_index) < token_len)) {\n ret_error_message =\n \"wuffs_aux::DecodeCbor: internal error: bad token indexes\";\n goto done;\n }\n uint8_t* token_ptr = io_buf->data.ptr + cursor_index;\n cursor_index += static_cast<size_t>(token_len);\n\n // 2. Process that token.\n\n uint64_t vbd = token.value_base_detail();\n\n if (extension_category != 0) {\n int64_t ext = token." +
+ "value_extension();\n if ((ext >= 0) && !token.continued()) {\n extension_detail = (extension_detail\n << WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS) |\n static_cast<uint64_t>(ext);\n switch (extension_category) {\n case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED:\n extension_category = 0;\n ret_error_message =\n callbacks.AppendI64(static_cast<int64_t>(extension_detail));\n goto parsed_a_value;\n case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED:\n extension_category = 0;\n ret_error_message = callbacks.AppendU64(extension_detail);\n goto parsed_a_value;\n case EXT_CAT__CBOR_TAG:\n extension_category = 0;\n ret_error_message = callbacks.AppendCborTag(extension_detail);\n if (!ret_error_message.empty()) {\n goto done;\n }\n continue;\n " +
+ " }\n }\n ret_error_message =\n \"wuffs_aux::DecodeCbor: internal error: bad extended token\";\n goto done;\n }\n\n switch (token.value_base_category()) {\n case WUFFS_BASE__TOKEN__VBC__FILLER:\n continue;\n\n case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {\n if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {\n ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));\n if (!ret_error_message.empty()) {\n goto done;\n }\n depth++;\n if (depth > WUFFS_CBOR__DECODER_DEPTH_MAX_INCL) {\n ret_error_message =\n \"wuffs_aux::DecodeCbor: internal error: bad depth\";\n goto done;\n }\n continue;\n }\n ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));\n depth--;\n if (depth < 0) {\n ret_error_message =\n \"wuffs_aux::DecodeCbor: internal error: bad depth\";\n g" +
+ "oto done;\n }\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__STRING: {\n if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {\n // No-op.\n } else if (vbd &\n WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {\n const char* ptr = // Convert from (uint8_t*).\n static_cast<const char*>(static_cast<void*>(token_ptr));\n str.append(ptr, static_cast<size_t>(token_len));\n } else {\n goto fail;\n }\n if (token.continued()) {\n continue;\n }\n ret_error_message =\n (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8)\n ? callbacks.AppendTextString(std::move(str))\n : callbacks.AppendByteString(std::move(str));\n str.clear();\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {\n uint8_t u[WUFFS_BASE__" +
+ "UTF_8__BYTE_LENGTH__MAX_INCL];\n size_t n = wuffs_base__utf_8__encode(\n wuffs_base__make_slice_u8(\n &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),\n static_cast<uint32_t>(vbd));\n const char* ptr = // Convert from (uint8_t*).\n static_cast<const char*>(static_cast<void*>(&u[0]));\n str.append(ptr, n);\n if (token.continued()) {\n continue;\n }\n goto fail;\n }\n\n case WUFFS_BASE__TOKEN__VBC__LITERAL: {\n if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL) {\n ret_error_message = callbacks.AppendNull();\n } else if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED) {\n ret_error_message = callbacks.AppendUndefined();\n } else {\n ret_error_message = callbacks.AppendBool(\n vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);\n }\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__NUMBER: {\n " +
+ " const uint64_t cfp_fbbe_fifb =\n WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT |\n WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN |\n WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE;\n if ((vbd & cfp_fbbe_fifb) == cfp_fbbe_fifb) {\n double f;\n switch (token_len) {\n case 3:\n f = wuffs_base__ieee_754_bit_representation__from_u16_to_f64(\n wuffs_base__peek_u16be__no_bounds_check(token_ptr + 1));\n break;\n case 5:\n f = wuffs_base__ieee_754_bit_representation__from_u32_to_f64(\n wuffs_base__peek_u32be__no_bounds_check(token_ptr + 1));\n break;\n case 9:\n f = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));\n break;\n default:\n goto fail;\n " +
+ " }\n ret_error_message = callbacks.AppendF64(f);\n goto parsed_a_value;\n }\n goto fail;\n }\n\n case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED: {\n if (token.continued()) {\n extension_category = WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED;\n extension_detail =\n static_cast<uint64_t>(token.value_base_detail__sign_extended());\n continue;\n }\n ret_error_message =\n callbacks.AppendI64(token.value_base_detail__sign_extended());\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED: {\n if (token.continued()) {\n extension_category =\n WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED;\n extension_detail = vbd;\n continue;\n }\n ret_error_message = callbacks.AppendU64(vbd);\n goto parsed_a_value;\n }\n }\n\n if (token.value_major() == WUFFS_CB" +
+ "OR__TOKEN_VALUE_MAJOR) {\n uint64_t value_minor = token.value_minor();\n if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X) {\n if (token_len == 9) {\n ret_error_message = callbacks.AppendMinus1MinusX(\n wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));\n goto parsed_a_value;\n }\n } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE) {\n ret_error_message =\n callbacks.AppendCborSimpleValue(static_cast<uint8_t>(\n value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK));\n goto parsed_a_value;\n } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG) {\n if (token.continued()) {\n extension_category = EXT_CAT__CBOR_TAG;\n extension_detail =\n value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK;\n continue;\n }\n ret_error_message = callbacks.AppendCborTag(\n value_" +
+ "minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK);\n if (!ret_error_message.empty()) {\n goto done;\n }\n continue;\n }\n }\n\n fail:\n ret_error_message =\n \"wuffs_aux::DecodeCbor: internal error: unexpected token\";\n goto done;\n\n parsed_a_value:\n if (!ret_error_message.empty() || (depth == 0)) {\n goto done;\n }\n }\n } while (false);\n\ndone:\n DecodeCborResult result(\n std::move(ret_error_message),\n wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));\n callbacks.Done(result, input, *io_buf);\n return result;\n}\n\n} // namespace wuffs_aux\n\n#endif // !defined(WUFFS_CONFIG__MODULES) ||\n // defined(WUFFS_CONFIG__MODULE__AUX__CBOR)\n" +
""
const AuxCborHh = "" +
@@ -856,32 +856,34 @@
""
const AuxJsonCc = "" +
- "// ---------------- Auxiliary - JSON\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__JSON)\n\n#include <utility>\n\nnamespace wuffs_aux {\n\nDecodeJsonResult::DecodeJsonResult(std::string&& error_message0,\n uint64_t cursor_position0)\n : error_message(std::move(error_message0)),\n cursor_position(cursor_position0) {}\n\nDecodeJsonCallbacks::~DecodeJsonCallbacks() {}\n\nvoid //\nDecodeJsonCallbacks::Done(DecodeJsonResult& result,\n sync_io::Input& input,\n IOBuffer& buffer) {}\n\nconst char DecodeJson_BadJsonPointer[] =\n \"wuffs_aux::DecodeJson: bad JSON Pointer\";\nconst char DecodeJson_NoMatch[] = \"wuffs_aux::DecodeJson: no match\";\n\n" +
+ "// ---------------- Auxiliary - JSON\n\n#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__JSON)\n\n#include <utility>\n\nnamespace wuffs_aux {\n\nDecodeJsonResult::DecodeJsonResult(std::string&& error_message0,\n uint64_t cursor_position0)\n : error_message(std::move(error_message0)),\n cursor_position(cursor_position0) {}\n\nDecodeJsonCallbacks::~DecodeJsonCallbacks() {}\n\nvoid //\nDecodeJsonCallbacks::Done(DecodeJsonResult& result,\n sync_io::Input& input,\n IOBuffer& buffer) {}\n\nconst char DecodeJson_BadJsonPointer[] = //\n \"wuffs_aux::DecodeJson: bad JSON Pointer\";\nconst char DecodeJson_NoMatch[] = //\n \"wuffs_aux::DecodeJson: no match\";\n\n" +
"" +
"// --------\n\n#define WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN \\\n while (tok_buf.meta.ri >= tok_buf.meta.wi) { \\\n if (tok_status.repr == nullptr) { \\\n goto done; \\\n } else if (tok_status.repr == wuffs_base__suspension__short_write) { \\\n tok_buf.compact(); \\\n } else if (tok_status.repr == wuffs_base__suspension__short_read) { \\\n if (!io_error_message.empty()) { \\\n ret_error_message = std::move(io_error_message); \\\n goto done; \\\n } else if (cursor_index != io_buf->meta.ri) { \\\n ret_error_message = \\\n \"wuffs_aux::DecodeJson: internal error: bad cursor_index\"; " +
" \\\n goto done; \\\n } else if (io_buf->meta.closed) { \\\n ret_error_message = \\\n \"wuffs_aux::DecodeJson: internal error: io_buf is closed\"; \\\n goto done; \\\n } \\\n io_buf->compact(); \\\n if (io_buf->meta.wi >= io_buf->data.len) { \\\n ret_error_message = \\\n \"wuffs_aux::DecodeJson: internal error: io_buf is full\"; \\\n goto done; \\\n } \\\n cursor_index = io_buf->meta.ri; \\\n i" +
- "o_error_message = input.CopyIn(io_buf); \\\n } else { \\\n ret_error_message = tok_status.message(); \\\n goto done; \\\n } \\\n tok_status = \\\n dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8()); \\\n } \\\n wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++]; \\\n uint64_t token_len = token.length(); \\\n if ((io_buf->meta.ri < cursor_index) || \\\n ((io_buf->meta.ri - cursor_index) < token_len)) { \\\n ret_error_message = \\\n \"wuffs_au" +
- "x::DecodeJson: internal error: bad token indexes\"; \\\n goto done; \\\n } \\\n uint8_t* token_ptr = io_buf->data.ptr + cursor_index; \\\n (void)(token_ptr); \\\n cursor_index += static_cast<size_t>(token_len)\n\n" +
+ "o_error_message = input.CopyIn(io_buf); \\\n } else { \\\n ret_error_message = tok_status.message(); \\\n goto done; \\\n } \\\n tok_status = \\\n dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8()); \\\n if ((tok_buf.meta.ri > tok_buf.meta.wi) || \\\n (tok_buf.meta.wi > tok_buf.data.len) || \\\n (io_buf->meta.ri > io_buf->meta.wi) || \\\n (io_buf->meta.wi > io_buf->data.len)) { \\\n ret_error_message = \\\n \"wuffs_aux::DecodeJson: internal error: bad buffer indexes\"; \\\n goto done; " +
+ " \\\n } \\\n } \\\n wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++]; \\\n uint64_t token_len = token.length(); \\\n if ((io_buf->meta.ri < cursor_index) || \\\n ((io_buf->meta.ri - cursor_index) < token_len)) { \\\n ret_error_message = \\\n \"wuffs_aux::DecodeJson: internal error: bad token indexes\"; \\\n goto done; \\\n } \\\n uint8_t* token_ptr = io_buf->data.ptr + cursor_index; \\\n (void)(token_ptr); \\\n cursor_index += static_ca" +
+ "st<size_t>(token_len)\n\n" +
"" +
- "// --------\n\nnamespace {\n\n// DecodeJson_SplitJsonPointer returns (\"bar\", 8) for (\"/foo/bar/b~1z/qux\", 5,\n// etc). It returns a 0 size_t when s has invalid JSON Pointer syntax.\n//\n// The string returned is unescaped. If calling it again, this time with i=8,\n// the \"b~1z\" substring would be returned as \"b/z\".\nstd::pair<std::string, size_t> //\nDecodeJson_SplitJsonPointer(std::string& s,\n size_t i,\n bool allow_tilde_n_tilde_r_tilde_t) {\n std::string fragment;\n while (i < s.size()) {\n char c = s[i];\n if (c == '/') {\n break;\n } else if (c != '~') {\n fragment.push_back(c);\n i++;\n continue;\n }\n i++;\n if (i >= s.size()) {\n return std::make_pair(std::string(), 0);\n }\n c = s[i];\n if (c == '0') {\n fragment.push_back('~');\n i++;\n continue;\n } else if (c == '1') {\n fragment.push_back('/');\n i++;\n continue;\n } else if (allow_tilde_n_tilde_r_tilde_t) {\n if (c == 'n') {\n " +
- "fragment.push_back('\\n');\n i++;\n continue;\n } else if (c == 'r') {\n fragment.push_back('\\r');\n i++;\n continue;\n } else if (c == 't') {\n fragment.push_back('\\t');\n i++;\n continue;\n }\n }\n return std::make_pair(std::string(), 0);\n }\n return std::make_pair(std::move(fragment), i);\n}\n\n" +
+ "// --------\n\nnamespace {\n\n// DecodeJson_SplitJsonPointer returns (\"bar\", 8) for (\"/foo/bar/b~1z/qux\", 5,\n// etc). It returns a 0 size_t when s has invalid JSON Pointer syntax or i is\n// out of bounds.\n//\n// The string returned is unescaped. If calling it again, this time with i=8,\n// the \"b~1z\" substring would be returned as \"b/z\".\nstd::pair<std::string, size_t> //\nDecodeJson_SplitJsonPointer(std::string& s,\n size_t i,\n bool allow_tilde_n_tilde_r_tilde_t) {\n std::string fragment;\n if (i > s.size()) {\n return std::make_pair(std::string(), 0);\n }\n while (i < s.size()) {\n char c = s[i];\n if (c == '/') {\n break;\n } else if (c != '~') {\n fragment.push_back(c);\n i++;\n continue;\n }\n i++;\n if (i >= s.size()) {\n return std::make_pair(std::string(), 0);\n }\n c = s[i];\n if (c == '0') {\n fragment.push_back('~');\n i++;\n continue;\n } else if (c == '1') {\n fragment.push_back('/');\n i++" +
+ ";\n continue;\n } else if (allow_tilde_n_tilde_r_tilde_t) {\n if (c == 'n') {\n fragment.push_back('\\n');\n i++;\n continue;\n } else if (c == 'r') {\n fragment.push_back('\\r');\n i++;\n continue;\n } else if (c == 't') {\n fragment.push_back('\\t');\n i++;\n continue;\n }\n }\n return std::make_pair(std::string(), 0);\n }\n return std::make_pair(std::move(fragment), i);\n}\n\n" +
"" +
"// --------\n\nstd::string //\nDecodeJson_WalkJsonPointerFragment(wuffs_base__token_buffer& tok_buf,\n wuffs_base__status& tok_status,\n wuffs_json__decoder::unique_ptr& dec,\n wuffs_base__io_buffer* io_buf,\n std::string& io_error_message,\n size_t& cursor_index,\n sync_io::Input& input,\n std::string& json_pointer_fragment) {\n std::string ret_error_message;\n while (true) {\n WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;\n\n int64_t vbc = token.value_base_category();\n uint64_t vbd = token.value_base_detail();\n if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {\n continue;\n } else if ((vbc != WUFFS_BASE__TOKEN__VBC__STRUCTURE) ||\n !(vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH)) {\n return DecodeJson_NoMatch;\n } else if (vbd & WUFFS_BASE__TOKEN__VBD__ST" +
"RUCTURE__TO_LIST) {\n goto do_list;\n }\n goto do_dict;\n }\n\ndo_dict:\n // Alternate between these two things:\n // 1. Decode the next dict key (a string). If it matches the fragment, we're\n // done (success). If we've reached the dict's end (VBD__STRUCTURE__POP)\n // so that there was no next dict key, we're done (failure).\n // 2. Otherwise, skip the next dict value.\n while (true) {\n for (std::string str; true;) {\n WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;\n\n int64_t vbc = token.value_base_category();\n uint64_t vbd = token.value_base_detail();\n switch (vbc) {\n case WUFFS_BASE__TOKEN__VBC__FILLER:\n continue;\n\n case WUFFS_BASE__TOKEN__VBC__STRUCTURE:\n if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {\n goto fail;\n }\n return DecodeJson_NoMatch;\n\n case WUFFS_BASE__TOKEN__VBC__STRING: {\n if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {\n // No-op.\n } els" +
"e if (vbd &\n WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {\n const char* ptr = // Convert from (uint8_t*).\n static_cast<const char*>(static_cast<void*>(token_ptr));\n str.append(ptr, static_cast<size_t>(token_len));\n } else {\n goto fail;\n }\n break;\n }\n\n case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {\n uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];\n size_t n = wuffs_base__utf_8__encode(\n wuffs_base__make_slice_u8(\n &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),\n static_cast<uint32_t>(vbd));\n const char* ptr = // Convert from (uint8_t*).\n static_cast<const char*>(static_cast<void*>(&u[0]));\n str.append(ptr, n);\n break;\n }\n\n default:\n goto fail;\n }\n\n if (token.continued()) {\n continue;\n }\n if (str == json_pointer_fragment) {\n " +
" return \"\";\n }\n goto skip_the_next_dict_value;\n }\n\n skip_the_next_dict_value:\n for (uint32_t skip_depth = 0; true;) {\n WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;\n\n int64_t vbc = token.value_base_category();\n uint64_t vbd = token.value_base_detail();\n if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {\n continue;\n } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {\n if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {\n skip_depth++;\n continue;\n }\n skip_depth--;\n }\n\n if (skip_depth == 0) {\n break;\n }\n } // skip_the_next_dict_value\n } // do_dict\n\ndo_list:\n do {\n wuffs_base__result_u64 result_u64 = wuffs_base__parse_number_u64(\n wuffs_base__make_slice_u8(\n static_cast<uint8_t*>(static_cast<void*>(\n const_cast<char*>(json_pointer_fragment.data()))),\n json_pointer_fragment.size()),\n WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTI" +
"ONS);\n if (!result_u64.status.is_ok()) {\n return DecodeJson_NoMatch;\n }\n uint64_t remaining = result_u64.value;\n if (remaining == 0) {\n goto check_that_a_value_follows;\n }\n for (uint32_t skip_depth = 0; true;) {\n WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;\n\n int64_t vbc = token.value_base_category();\n uint64_t vbd = token.value_base_detail();\n if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {\n continue;\n } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {\n if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {\n skip_depth++;\n continue;\n }\n if (skip_depth == 0) {\n return DecodeJson_NoMatch;\n }\n skip_depth--;\n }\n\n if (skip_depth > 0) {\n continue;\n }\n remaining--;\n if (remaining == 0) {\n goto check_that_a_value_follows;\n }\n }\n } while (false); // do_list\n\ncheck_that_a_value_follows:\n while (true) {\n WUFFS_AUX__DECODE_JSON" +
- "__GET_THE_NEXT_TOKEN;\n\n int64_t vbc = token.value_base_category();\n uint64_t vbd = token.value_base_detail();\n if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {\n continue;\n }\n\n // Undo the last part of WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN, so that\n // we're only peeking at the next token.\n tok_buf.meta.ri--;\n cursor_index -= static_cast<size_t>(token_len);\n\n if ((vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) &&\n (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP)) {\n return DecodeJson_NoMatch;\n }\n return \"\";\n } // check_that_a_value_follows\n\nfail:\n return \"wuffs_aux::DecodeJson: internal error: unexpected token\";\ndone:\n return ret_error_message;\n}\n\n} // namespace\n\n" +
+ "__GET_THE_NEXT_TOKEN;\n\n int64_t vbc = token.value_base_category();\n uint64_t vbd = token.value_base_detail();\n if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {\n continue;\n }\n\n // Undo the last part of WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN, so\n // that we're only peeking at the next token.\n tok_buf.meta.ri--;\n cursor_index -= static_cast<size_t>(token_len);\n\n if ((vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) &&\n (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP)) {\n return DecodeJson_NoMatch;\n }\n return \"\";\n } // check_that_a_value_follows\n\nfail:\n return \"wuffs_aux::DecodeJson: internal error: unexpected token\";\ndone:\n return ret_error_message;\n}\n\n} // namespace\n\n" +
"" +
"// --------\n\nDecodeJsonResult //\nDecodeJson(DecodeJsonCallbacks& callbacks,\n sync_io::Input& input,\n wuffs_base__slice_u32 quirks,\n std::string json_pointer) {\n // Prepare the wuffs_base__io_buffer and the resultant error_message.\n wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();\n wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();\n std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);\n if (!io_buf) {\n fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);\n fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);\n io_buf = &fallback_io_buf;\n }\n // cursor_index is discussed at\n // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index\n size_t cursor_index = 0;\n std::string ret_error_message;\n std::string io_error_message;\n\n do {\n // Prepare the low-level JSON decoder.\n wuffs_json__decoder::unique_ptr dec = wuffs_json__decoder::alloc();\n if (!dec) {\n ret_error_message = " +
- "\"wuffs_aux::DecodeJson: out of memory\";\n goto done;\n } else if (WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {\n ret_error_message =\n \"wuffs_aux::DecodeJson: internal error: bad WORKBUF_LEN\";\n goto done;\n }\n bool allow_tilde_n_tilde_r_tilde_t = false;\n for (size_t i = 0; i < quirks.len; i++) {\n dec->set_quirk_enabled(quirks.ptr[i], true);\n if (quirks.ptr[i] ==\n WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T) {\n allow_tilde_n_tilde_r_tilde_t = true;\n }\n }\n\n // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.\n wuffs_base__token tok_array[256];\n wuffs_base__token_buffer tok_buf =\n wuffs_base__slice_token__writer(wuffs_base__make_slice_token(\n &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));\n wuffs_base__status tok_status =\n dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());\n\n // Prepare other state.\n uint32_t depth = 0;\n std::string str;" +
- "\n\n // Walk the (optional) JSON Pointer.\n for (size_t i = 0; i < json_pointer.size();) {\n if (json_pointer[i] != '/') {\n ret_error_message = DecodeJson_BadJsonPointer;\n goto done;\n }\n std::pair<std::string, size_t> split = DecodeJson_SplitJsonPointer(\n json_pointer, i + 1, allow_tilde_n_tilde_r_tilde_t);\n i = split.second;\n if (i == 0) {\n ret_error_message = DecodeJson_BadJsonPointer;\n goto done;\n }\n ret_error_message = DecodeJson_WalkJsonPointerFragment(\n tok_buf, tok_status, dec, io_buf, io_error_message, cursor_index,\n input, split.first);\n if (!ret_error_message.empty()) {\n goto done;\n }\n }\n\n // Loop, doing these two things:\n // 1. Get the next token.\n // 2. Process that token.\n while (true) {\n WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;\n\n int64_t vbc = token.value_base_category();\n uint64_t vbd = token.value_base_detail();\n switch (vbc) {\n case WUFFS_" +
- "BASE__TOKEN__VBC__FILLER:\n continue;\n\n case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {\n if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {\n ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));\n if (!ret_error_message.empty()) {\n goto done;\n }\n depth++;\n continue;\n }\n ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));\n depth--;\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__STRING: {\n if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {\n // No-op.\n } else if (vbd &\n WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {\n const char* ptr = // Convert from (uint8_t*).\n static_cast<const char*>(static_cast<void*>(token_ptr));\n str.append(ptr, static_cast<size_t>(token_len));\n } else {\n goto fail;\n }\n " +
- "if (token.continued()) {\n continue;\n }\n ret_error_message = callbacks.AppendTextString(std::move(str));\n str.clear();\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {\n uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];\n size_t n = wuffs_base__utf_8__encode(\n wuffs_base__make_slice_u8(\n &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),\n static_cast<uint32_t>(vbd));\n const char* ptr = // Convert from (uint8_t*).\n static_cast<const char*>(static_cast<void*>(&u[0]));\n str.append(ptr, n);\n if (token.continued()) {\n continue;\n }\n goto fail;\n }\n\n case WUFFS_BASE__TOKEN__VBC__LITERAL: {\n ret_error_message =\n (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL)\n ? callbacks.AppendNull()\n : callbacks.AppendBool(vbd &\n " +
- " WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__NUMBER: {\n if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT) {\n if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED) {\n wuffs_base__result_i64 r = wuffs_base__parse_number_i64(\n wuffs_base__make_slice_u8(token_ptr,\n static_cast<size_t>(token_len)),\n WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);\n if (r.status.is_ok()) {\n ret_error_message = callbacks.AppendI64(r.value);\n goto parsed_a_value;\n }\n }\n if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT) {\n wuffs_base__result_f64 r = wuffs_base__parse_number_f64(\n wuffs_base__make_slice_u8(token_ptr,\n static_cast<size_t>(token_len)),\n " +
- " WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);\n if (r.status.is_ok()) {\n ret_error_message = callbacks.AppendF64(r.value);\n goto parsed_a_value;\n }\n }\n } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF) {\n ret_error_message = callbacks.AppendF64(\n wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n 0xFFF0000000000000ul));\n goto parsed_a_value;\n } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF) {\n ret_error_message = callbacks.AppendF64(\n wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n 0x7FF0000000000000ul));\n goto parsed_a_value;\n } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN) {\n ret_error_message = callbacks.AppendF64(\n wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n 0xF" +
- "FFFFFFFFFFFFFFFul));\n goto parsed_a_value;\n } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN) {\n ret_error_message = callbacks.AppendF64(\n wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n 0x7FFFFFFFFFFFFFFFul));\n goto parsed_a_value;\n }\n goto fail;\n }\n }\n\n fail:\n ret_error_message =\n \"wuffs_aux::DecodeJson: internal error: unexpected token\";\n goto done;\n\n parsed_a_value:\n // If an error was encountered, we are done. Otherwise, (depth == 0)\n // after parsing a value is equivalent to having decoded the entire JSON\n // value (for an empty json_pointer query) or having decoded the\n // pointed-to JSON value (for a non-empty json_pointer query). In the\n // latter case, we are also done.\n //\n // However, if quirks like WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER or\n // WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF are pass" +
- "ed, decoding\n // the entire JSON value should also consume any trailing filler, in case\n // the DecodeJson caller wants to subsequently check that the input is\n // completely exhausted (and otherwise raise \"valid JSON followed by\n // further (unexpected) data\"). We aren't done yet. Instead, keep the\n // loop running until WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN's\n // decode_tokens returns an ok status.\n if (!ret_error_message.empty() ||\n ((depth == 0) && !json_pointer.empty())) {\n goto done;\n }\n }\n } while (false);\n\ndone:\n DecodeJsonResult result(\n std::move(ret_error_message),\n wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));\n callbacks.Done(result, input, *io_buf);\n return result;\n}\n\n#undef WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN\n\n} // namespace wuffs_aux\n\n#endif // !defined(WUFFS_CONFIG__MODULES) ||\n // defined(WUFFS_CONFIG__MODULE__AUX__JSON)\n" +
+ "\"wuffs_aux::DecodeJson: out of memory\";\n goto done;\n } else if (WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {\n ret_error_message =\n \"wuffs_aux::DecodeJson: internal error: bad WORKBUF_LEN\";\n goto done;\n }\n bool allow_tilde_n_tilde_r_tilde_t = false;\n for (size_t i = 0; i < quirks.len; i++) {\n dec->set_quirk_enabled(quirks.ptr[i], true);\n if (quirks.ptr[i] ==\n WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T) {\n allow_tilde_n_tilde_r_tilde_t = true;\n }\n }\n\n // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.\n wuffs_base__token tok_array[256];\n wuffs_base__token_buffer tok_buf =\n wuffs_base__slice_token__writer(wuffs_base__make_slice_token(\n &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));\n wuffs_base__status tok_status =\n dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());\n\n // Prepare other state.\n int32_t depth = 0;\n std::string str;\n" +
+ "\n // Walk the (optional) JSON Pointer.\n for (size_t i = 0; i < json_pointer.size();) {\n if (json_pointer[i] != '/') {\n ret_error_message = DecodeJson_BadJsonPointer;\n goto done;\n }\n std::pair<std::string, size_t> split = DecodeJson_SplitJsonPointer(\n json_pointer, i + 1, allow_tilde_n_tilde_r_tilde_t);\n i = split.second;\n if (i == 0) {\n ret_error_message = DecodeJson_BadJsonPointer;\n goto done;\n }\n ret_error_message = DecodeJson_WalkJsonPointerFragment(\n tok_buf, tok_status, dec, io_buf, io_error_message, cursor_index,\n input, split.first);\n if (!ret_error_message.empty()) {\n goto done;\n }\n }\n\n // Loop, doing these two things:\n // 1. Get the next token.\n // 2. Process that token.\n while (true) {\n WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;\n\n int64_t vbc = token.value_base_category();\n uint64_t vbd = token.value_base_detail();\n switch (vbc) {\n case WUFFS_B" +
+ "ASE__TOKEN__VBC__FILLER:\n continue;\n\n case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {\n if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {\n ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));\n if (!ret_error_message.empty()) {\n goto done;\n }\n depth++;\n if (depth > WUFFS_JSON__DECODER_DEPTH_MAX_INCL) {\n ret_error_message =\n \"wuffs_aux::DecodeJson: internal error: bad depth\";\n goto done;\n }\n continue;\n }\n ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));\n depth--;\n if (depth < 0) {\n ret_error_message =\n \"wuffs_aux::DecodeJson: internal error: bad depth\";\n goto done;\n }\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__STRING: {\n if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {\n // No-op." +
+ "\n } else if (vbd &\n WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {\n const char* ptr = // Convert from (uint8_t*).\n static_cast<const char*>(static_cast<void*>(token_ptr));\n str.append(ptr, static_cast<size_t>(token_len));\n } else {\n goto fail;\n }\n if (token.continued()) {\n continue;\n }\n ret_error_message = callbacks.AppendTextString(std::move(str));\n str.clear();\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {\n uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];\n size_t n = wuffs_base__utf_8__encode(\n wuffs_base__make_slice_u8(\n &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),\n static_cast<uint32_t>(vbd));\n const char* ptr = // Convert from (uint8_t*).\n static_cast<const char*>(static_cast<void*>(&u[0]));\n str." +
+ "append(ptr, n);\n if (token.continued()) {\n continue;\n }\n goto fail;\n }\n\n case WUFFS_BASE__TOKEN__VBC__LITERAL: {\n ret_error_message =\n (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL)\n ? callbacks.AppendNull()\n : callbacks.AppendBool(vbd &\n WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);\n goto parsed_a_value;\n }\n\n case WUFFS_BASE__TOKEN__VBC__NUMBER: {\n if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT) {\n if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED) {\n wuffs_base__result_i64 r = wuffs_base__parse_number_i64(\n wuffs_base__make_slice_u8(token_ptr,\n static_cast<size_t>(token_len)),\n WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);\n if (r.status.is_ok()) {\n ret_error_message = callbacks.AppendI64" +
+ "(r.value);\n goto parsed_a_value;\n }\n }\n if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT) {\n wuffs_base__result_f64 r = wuffs_base__parse_number_f64(\n wuffs_base__make_slice_u8(token_ptr,\n static_cast<size_t>(token_len)),\n WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);\n if (r.status.is_ok()) {\n ret_error_message = callbacks.AppendF64(r.value);\n goto parsed_a_value;\n }\n }\n } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF) {\n ret_error_message = callbacks.AppendF64(\n wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n 0xFFF0000000000000ul));\n goto parsed_a_value;\n } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF) {\n ret_error_message = callbacks.AppendF64(\n " +
+ " wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n 0x7FF0000000000000ul));\n goto parsed_a_value;\n } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN) {\n ret_error_message = callbacks.AppendF64(\n wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n 0xFFFFFFFFFFFFFFFFul));\n goto parsed_a_value;\n } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN) {\n ret_error_message = callbacks.AppendF64(\n wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n 0x7FFFFFFFFFFFFFFFul));\n goto parsed_a_value;\n }\n goto fail;\n }\n }\n\n fail:\n ret_error_message =\n \"wuffs_aux::DecodeJson: internal error: unexpected token\";\n goto done;\n\n parsed_a_value:\n // If an error was encountered, we are done. Otherwise, (depth == 0)\n // after parsing a value is equivalent to havi" +
+ "ng decoded the entire JSON\n // value (for an empty json_pointer query) or having decoded the\n // pointed-to JSON value (for a non-empty json_pointer query). In the\n // latter case, we are also done.\n //\n // However, if quirks like WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER or\n // WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF are passed, decoding\n // the entire JSON value should also consume any trailing filler, in case\n // the DecodeJson caller wants to subsequently check that the input is\n // completely exhausted (and otherwise raise \"valid JSON followed by\n // further (unexpected) data\"). We aren't done yet. Instead, keep the\n // loop running until WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN's\n // decode_tokens returns an ok status.\n if (!ret_error_message.empty() ||\n ((depth == 0) && !json_pointer.empty())) {\n goto done;\n }\n }\n } while (false);\n\ndone:\n DecodeJsonResult result(\n std::move(ret_error_message),\n " +
+ " wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));\n callbacks.Done(result, input, *io_buf);\n return result;\n}\n\n#undef WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN\n\n} // namespace wuffs_aux\n\n#endif // !defined(WUFFS_CONFIG__MODULES) ||\n // defined(WUFFS_CONFIG__MODULE__AUX__JSON)\n" +
""
const AuxJsonHh = "" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index edf0dac..9370e9c 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -39348,7 +39348,7 @@
// Prepare the low-level CBOR decoder.
wuffs_cbor__decoder::unique_ptr dec = wuffs_cbor__decoder::alloc();
if (!dec) {
- ret_error_message = "wuffs_aux::CborDecoder: out of memory";
+ ret_error_message = "wuffs_aux::DecodeCbor: out of memory";
goto done;
}
for (size_t i = 0; i < quirks.len; i++) {
@@ -39363,7 +39363,7 @@
wuffs_base__status tok_status = wuffs_base__make_status(nullptr);
// Prepare other state.
- uint32_t depth = 0;
+ int32_t depth = 0;
std::string str;
int64_t extension_category = 0;
uint64_t extension_detail = 0;
@@ -39390,17 +39390,17 @@
goto done;
} else if (cursor_index != io_buf->meta.ri) {
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: bad cursor_index";
+ "wuffs_aux::DecodeCbor: internal error: bad cursor_index";
goto done;
} else if (io_buf->meta.closed) {
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: io_buf is closed";
+ "wuffs_aux::DecodeCbor: internal error: io_buf is closed";
goto done;
}
io_buf->compact();
if (io_buf->meta.wi >= io_buf->data.len) {
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: io_buf is full";
+ "wuffs_aux::DecodeCbor: internal error: io_buf is full";
goto done;
}
cursor_index = io_buf->meta.ri;
@@ -39412,11 +39412,19 @@
if (WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: bad WORKBUF_LEN";
+ "wuffs_aux::DecodeCbor: internal error: bad WORKBUF_LEN";
goto done;
}
wuffs_base__slice_u8 work_buf = wuffs_base__empty_slice_u8();
tok_status = dec->decode_tokens(&tok_buf, io_buf, work_buf);
+ if ((tok_buf.meta.ri > tok_buf.meta.wi) ||
+ (tok_buf.meta.wi > tok_buf.data.len) ||
+ (io_buf->meta.ri > io_buf->meta.wi) ||
+ (io_buf->meta.wi > io_buf->data.len)) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: bad buffer indexes";
+ goto done;
+ }
}
wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];
@@ -39424,7 +39432,7 @@
if ((io_buf->meta.ri < cursor_index) ||
((io_buf->meta.ri - cursor_index) < token_len)) {
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: bad token indexes";
+ "wuffs_aux::DecodeCbor: internal error: bad token indexes";
goto done;
}
uint8_t* token_ptr = io_buf->data.ptr + cursor_index;
@@ -39460,7 +39468,7 @@
}
}
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: bad extended token";
+ "wuffs_aux::DecodeCbor: internal error: bad extended token";
goto done;
}
@@ -39475,10 +39483,20 @@
goto done;
}
depth++;
+ if (depth > WUFFS_CBOR__DECODER_DEPTH_MAX_INCL) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: bad depth";
+ goto done;
+ }
continue;
}
ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
depth--;
+ if (depth < 0) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: bad depth";
+ goto done;
+ }
goto parsed_a_value;
}
@@ -39615,7 +39633,7 @@
fail:
ret_error_message =
- "wuffs_aux::CborDecoder: internal error: unexpected token";
+ "wuffs_aux::DecodeCbor: internal error: unexpected token";
goto done;
parsed_a_value:
@@ -40082,9 +40100,10 @@
sync_io::Input& input,
IOBuffer& buffer) {}
-const char DecodeJson_BadJsonPointer[] =
+const char DecodeJson_BadJsonPointer[] = //
"wuffs_aux::DecodeJson: bad JSON Pointer";
-const char DecodeJson_NoMatch[] = "wuffs_aux::DecodeJson: no match";
+const char DecodeJson_NoMatch[] = //
+ "wuffs_aux::DecodeJson: no match";
// --------
@@ -40121,6 +40140,14 @@
} \
tok_status = \
dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8()); \
+ if ((tok_buf.meta.ri > tok_buf.meta.wi) || \
+ (tok_buf.meta.wi > tok_buf.data.len) || \
+ (io_buf->meta.ri > io_buf->meta.wi) || \
+ (io_buf->meta.wi > io_buf->data.len)) { \
+ ret_error_message = \
+ "wuffs_aux::DecodeJson: internal error: bad buffer indexes"; \
+ goto done; \
+ } \
} \
wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++]; \
uint64_t token_len = token.length(); \
@@ -40139,7 +40166,8 @@
namespace {
// DecodeJson_SplitJsonPointer returns ("bar", 8) for ("/foo/bar/b~1z/qux", 5,
-// etc). It returns a 0 size_t when s has invalid JSON Pointer syntax.
+// etc). It returns a 0 size_t when s has invalid JSON Pointer syntax or i is
+// out of bounds.
//
// The string returned is unescaped. If calling it again, this time with i=8,
// the "b~1z" substring would be returned as "b/z".
@@ -40148,6 +40176,9 @@
size_t i,
bool allow_tilde_n_tilde_r_tilde_t) {
std::string fragment;
+ if (i > s.size()) {
+ return std::make_pair(std::string(), 0);
+ }
while (i < s.size()) {
char c = s[i];
if (c == '/') {
@@ -40354,8 +40385,8 @@
continue;
}
- // Undo the last part of WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN, so that
- // we're only peeking at the next token.
+ // Undo the last part of WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN, so
+ // that we're only peeking at the next token.
tok_buf.meta.ri--;
cursor_index -= static_cast<size_t>(token_len);
@@ -40425,7 +40456,7 @@
dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());
// Prepare other state.
- uint32_t depth = 0;
+ int32_t depth = 0;
std::string str;
// Walk the (optional) JSON Pointer.
@@ -40468,10 +40499,20 @@
goto done;
}
depth++;
+ if (depth > WUFFS_JSON__DECODER_DEPTH_MAX_INCL) {
+ ret_error_message =
+ "wuffs_aux::DecodeJson: internal error: bad depth";
+ goto done;
+ }
continue;
}
ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
depth--;
+ if (depth < 0) {
+ ret_error_message =
+ "wuffs_aux::DecodeJson: internal error: bad depth";
+ goto done;
+ }
goto parsed_a_value;
}