Have wuffs_aux::DecodeJson consume trailing filler

Prior to this commit, wuffs_aux::DecodeJson would almost always consume
(optional) trailing filler, but in rare coincidences, it might not if a
wuffs_base__suspension__short_write coroutine suspension was needed
between the last token of the actual JSON value and the first token of
the filler after that JSON value.

This commit should change behavior only if the wuffs_aux::DecodeJson
caller had opted into WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER or
WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF.

Also remove an unnecessary std::move on a size_t typed value.
diff --git a/internal/cgen/auxiliary/json.cc b/internal/cgen/auxiliary/json.cc
index c56a91a..643b677 100644
--- a/internal/cgen/auxiliary/json.cc
+++ b/internal/cgen/auxiliary/json.cc
@@ -43,6 +43,7 @@
 #define WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN                       \
   while (tok_buf.meta.ri >= tok_buf.meta.wi) {                           \
     if (tok_status.repr == nullptr) {                                    \
+      goto done;                                                         \
     } else if (tok_status.repr == wuffs_base__suspension__short_write) { \
       tok_buf.compact();                                                 \
     } else if (tok_status.repr == wuffs_base__suspension__short_read) {  \
@@ -70,11 +71,6 @@
       ret_error_message = tok_status.message();                          \
       goto done;                                                         \
     }                                                                    \
-    if (WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {      \
-      ret_error_message =                                                \
-          "wuffs_aux::DecodeJson: 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);         \
   }                                                                      \
@@ -358,6 +354,10 @@
     if (!dec) {
       ret_error_message = "wuffs_aux::DecodeJson: out of memory";
       goto done;
+    } else if (WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
+      ret_error_message =
+          "wuffs_aux::DecodeJson: internal error: bad WORKBUF_LEN";
+      goto done;
     }
     bool allow_tilde_n_tilde_r_tilde_t = false;
     for (size_t i = 0; i < quirks.len; i++) {
@@ -373,7 +373,8 @@
     wuffs_base__token_buffer tok_buf =
         wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
             &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
-    wuffs_base__status tok_status = wuffs_base__make_status(nullptr);
+    wuffs_base__status tok_status =
+        dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());
 
     // Prepare other state.
     uint32_t depth = 0;
@@ -387,7 +388,7 @@
       }
       std::pair<std::string, size_t> split = DecodeJson_SplitJsonPointer(
           json_pointer, i + 1, allow_tilde_n_tilde_r_tilde_t);
-      i = std::move(split.second);
+      i = split.second;
       if (i == 0) {
         ret_error_message = DecodeJson_BadJsonPointer;
         goto done;
@@ -522,7 +523,22 @@
       goto done;
 
     parsed_a_value:
-      if (!ret_error_message.empty() || (depth == 0)) {
+      // If an error was encountered, we are done. Otherwise, (depth == 0)
+      // after parsing a value is equivalent to having decoded the entire JSON
+      // value (for an empty json_pointer query) or having decoded the
+      // pointed-to JSON value (for a non-empty json_pointer query). In the
+      // latter case, we are also done.
+      //
+      // However, if quirks like WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER or
+      // WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF are passed, decoding
+      // the entire JSON value should also consume any trailing filler, in case
+      // the DecodeJson caller wants to subsequently check that the input is
+      // completely exhausted (and otherwise raise "valid JSON followed by
+      // further (unexpected) data"). We aren't done yet. Instead, keep the
+      // loop running until WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN's
+      // decode_tokens returns an ok status.
+      if (!ret_error_message.empty() ||
+          ((depth == 0) && !json_pointer.empty())) {
         goto done;
       }
     }
diff --git a/internal/cgen/data/data.go b/internal/cgen/data/data.go
index f434cfa..9ca61f2 100644
--- a/internal/cgen/data/data.go
+++ b/internal/cgen/data/data.go
@@ -857,10 +857,10 @@
 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" +
 	"" +
-	"// --------\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    } 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      io_error_message = input.CopyIn(io_buf);                           \\\n    } else {                                                             \\\n      ret_" +
-	"error_message = tok_status.message();                          \\\n      goto done;                                                         \\\n    }                                                                    \\\n    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    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  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_cast<size_t>(token_len)\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      io_error_message = input.CopyIn(io_buf);                           \\\n    } else" +
+	" {                                                             \\\n      ret_error_message = tok_status.message();                          \\\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  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_cast<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" +
@@ -873,13 +873,14 @@
 	"__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" +
 	"" +
 	"// --------\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    }\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 = wuffs_base__make_status(nullptr);\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 = std::move(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_cas" +
-	"t<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                    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 (!ret_error_message.empty() || (depth == 0)) {\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    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" +
 	""
 
 const AuxJsonHh = "" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 2450891..c4f09c5 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -40056,6 +40056,7 @@
 #define WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN                       \
   while (tok_buf.meta.ri >= tok_buf.meta.wi) {                           \
     if (tok_status.repr == nullptr) {                                    \
+      goto done;                                                         \
     } else if (tok_status.repr == wuffs_base__suspension__short_write) { \
       tok_buf.compact();                                                 \
     } else if (tok_status.repr == wuffs_base__suspension__short_read) {  \
@@ -40083,11 +40084,6 @@
       ret_error_message = tok_status.message();                          \
       goto done;                                                         \
     }                                                                    \
-    if (WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {      \
-      ret_error_message =                                                \
-          "wuffs_aux::DecodeJson: 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);         \
   }                                                                      \
@@ -40371,6 +40367,10 @@
     if (!dec) {
       ret_error_message = "wuffs_aux::DecodeJson: out of memory";
       goto done;
+    } else if (WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
+      ret_error_message =
+          "wuffs_aux::DecodeJson: internal error: bad WORKBUF_LEN";
+      goto done;
     }
     bool allow_tilde_n_tilde_r_tilde_t = false;
     for (size_t i = 0; i < quirks.len; i++) {
@@ -40386,7 +40386,8 @@
     wuffs_base__token_buffer tok_buf =
         wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
             &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
-    wuffs_base__status tok_status = wuffs_base__make_status(nullptr);
+    wuffs_base__status tok_status =
+        dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());
 
     // Prepare other state.
     uint32_t depth = 0;
@@ -40400,7 +40401,7 @@
       }
       std::pair<std::string, size_t> split = DecodeJson_SplitJsonPointer(
           json_pointer, i + 1, allow_tilde_n_tilde_r_tilde_t);
-      i = std::move(split.second);
+      i = split.second;
       if (i == 0) {
         ret_error_message = DecodeJson_BadJsonPointer;
         goto done;
@@ -40535,7 +40536,22 @@
       goto done;
 
     parsed_a_value:
-      if (!ret_error_message.empty() || (depth == 0)) {
+      // If an error was encountered, we are done. Otherwise, (depth == 0)
+      // after parsing a value is equivalent to having decoded the entire JSON
+      // value (for an empty json_pointer query) or having decoded the
+      // pointed-to JSON value (for a non-empty json_pointer query). In the
+      // latter case, we are also done.
+      //
+      // However, if quirks like WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER or
+      // WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF are passed, decoding
+      // the entire JSON value should also consume any trailing filler, in case
+      // the DecodeJson caller wants to subsequently check that the input is
+      // completely exhausted (and otherwise raise "valid JSON followed by
+      // further (unexpected) data"). We aren't done yet. Instead, keep the
+      // loop running until WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN's
+      // decode_tokens returns an ok status.
+      if (!ret_error_message.empty() ||
+          ((depth == 0) && !json_pointer.empty())) {
         goto done;
       }
     }