Add json QUIRK_JSON_POINTER_ALLOW_TILDE_R_TILDE_N
diff --git a/example/jsonfindptrs/jsonfindptrs.cc b/example/jsonfindptrs/jsonfindptrs.cc
index 4794279..b4ca64b 100644
--- a/example/jsonfindptrs/jsonfindptrs.cc
+++ b/example/jsonfindptrs/jsonfindptrs.cc
@@ -501,6 +501,9 @@
 std::string  //
 main1(int argc, char** argv) {
   TRY(parse_flags(argc, argv));
+  if (!g_flags.strict_json_pointer_syntax) {
+    g_quirks.push_back(WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_R_TILDE_N);
+  }
 
   FILE* in = stdin;
   if (g_flags.remaining_argc > 1) {
diff --git a/internal/cgen/auxiliary/json.cc b/internal/cgen/auxiliary/json.cc
index bcd3908..1946112 100644
--- a/internal/cgen/auxiliary/json.cc
+++ b/internal/cgen/auxiliary/json.cc
@@ -92,10 +92,15 @@
 
 namespace {
 
-// DecodeJson_SplitJsonPointer returns ("bar", 8) for ("/foo/bar/baz/qux", 5).
-// It returns a 0 size_t when s has invalid JSON Pointer syntax.
+// 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.
+//
+// The string returned is unescaped. If calling it again, this time with i=8,
+// the "b~1z" substring would be returned as "b/z".
 std::pair<std::string, size_t>  //
-DecodeJson_SplitJsonPointer(std::string& s, size_t i) {
+DecodeJson_SplitJsonPointer(std::string& s,
+                            size_t i,
+                            bool allow_tilde_r_tilde_n) {
   std::string fragment;
   while (i < s.size()) {
     char c = s[i];
@@ -119,6 +124,16 @@
       fragment.push_back('/');
       i++;
       continue;
+    } else if (allow_tilde_r_tilde_n) {
+      if (c == 'r') {
+        fragment.push_back('\r');
+        i++;
+        continue;
+      } else if (c == 'n') {
+        fragment.push_back('\n');
+        i++;
+        continue;
+      }
     }
     return std::make_pair(std::string(), 0);
   }
@@ -366,8 +381,13 @@
       ret_error_message = "wuffs_aux::DecodeJson: out of memory";
       goto done;
     }
+    bool allow_tilde_r_tilde_n = false;
     for (size_t i = 0; i < quirks.len; i++) {
       dec->set_quirk_enabled(quirks.ptr[i], true);
+      if (quirks.ptr[i] ==
+          WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_R_TILDE_N) {
+        allow_tilde_r_tilde_n = true;
+      }
     }
 
     // Prepare the wuffs_base__tok_buffer.
@@ -387,8 +407,8 @@
         ret_error_message = DecodeJson_BadJsonPointer;
         goto done;
       }
-      std::pair<std::string, size_t> split =
-          DecodeJson_SplitJsonPointer(json_pointer, i + 1);
+      std::pair<std::string, size_t> split = DecodeJson_SplitJsonPointer(
+          json_pointer, i + 1, allow_tilde_r_tilde_n);
       i = std::move(split.second);
       if (i == 0) {
         ret_error_message = DecodeJson_BadJsonPointer;
diff --git a/internal/cgen/data/data.go b/internal/cgen/data/data.go
index 97a3686..a2772a9 100644
--- a/internal/cgen/data/data.go
+++ b/internal/cgen/data/data.go
@@ -652,22 +652,23 @@
 	"{                                    \\\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        go" +
 	"to 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: i" +
-	"nternal error: bad token indexes\";      \\\n    goto done;                                                           \\\n  }                                                                      \\\n  uint8_t* token_ptr = io_buf->data.ptr + cursor_index;                  \\\n  cursor_index += token_len\n\nnamespace {\n\n// DecodeJson_SplitJsonPointer returns (\"bar\", 8) for (\"/foo/bar/baz/qux\", 5).\n// It returns a 0 size_t when s has invalid JSON Pointer syntax.\nstd::pair<std::string, size_t>  //\nDecodeJson_SplitJsonPointer(std::string& s, size_t i) {\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    }\n    return std::make" +
-	"_pair(std::string(), 0);\n  }\n  return std::make_pair(std::move(fragment), i);\n}\n\nstd::string  //\nDecodeJson_DecodeBackslashX(std::string& str,\n                            uint8_t* token_ptr,\n                            size_t token_len) {\n  wuffs_base__slice_u8 encoded =\n      wuffs_base__make_slice_u8(token_ptr, token_len);\n  while (encoded.len > 0) {\n    uint8_t decoded[64];\n    constexpr bool src_closed = true;\n    wuffs_base__transform__output o = wuffs_base__base_16__decode4(\n        wuffs_base__make_slice_u8(&decoded[0], sizeof decoded), encoded,\n        src_closed, WUFFS_BASE__BASE_16__DEFAULT_OPTIONS);\n    if (o.status.is_error()) {\n      return o.status.message();\n    } else if ((o.num_dst > (sizeof decoded)) || (o.num_src > encoded.len)) {\n      return \"wuffs_aux::DecodeJson: internal error: inconsistent base16 \"\n             \"decoding\";\n    }\n    str.append(  // Convert from (uint8_t*).\n        static_cast<const char*>(static_cast<void*>(&decoded[0])), o.num_dst);\n    encoded.ptr += o.num_src;\n    " +
-	"encoded.len -= o.num_src;\n  }\n  return \"\";\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__STRUCTURE__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          } 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, token_len);\n          } else if (\n              vbd &\n              WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_4_SRC_BACKSLASH_X) {\n            ret_error_message =\n                DecodeJson_DecodeBackslashX(str, token_ptr, token_len);\n            if (!ret_error_message.empty()) {\n              goto done;\n            }\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_OPTIONS);\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          ret" +
-	"urn 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 -= 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\nD" +
-	"ecodeJsonResult  //\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  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    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.\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 =\n          DecodeJson_SplitJsonPointer(json_pointer, i + 1);\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_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__T" +
-	"OKEN__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, token_len);\n          } else if (\n              vbd &\n              WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_4_SRC_BACKSLASH_X) {\n            ret_error_message =\n                DecodeJson_DecodeBackslashX(str, token_ptr, token_len);\n            if (!ret_error_message.empty()) {\n              goto done;\n            }\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          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__NUM" +
-	"BER: {\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, 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, 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__T" +
-	"OKEN__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" +
+	"nternal error: bad token indexes\";      \\\n    goto done;                                                           \\\n  }                                                                      \\\n  uint8_t* token_ptr = io_buf->data.ptr + cursor_index;                  \\\n  cursor_index += token_len\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_r_tilde_n) {\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_r_tilde_n) {\n      if (c == 'r') {\n        fragment.push_back('\\r');\n        i++;\n        continue;\n      } else if (c == 'n') {\n        fragment.push_back('\\n');\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\nstd::string  //\nDecodeJson_DecodeBackslashX(std::string& str,\n                            uint8_t* token_ptr,\n                            size_t token_len) {\n  wuffs_base__slice_u8 encoded =\n      wuffs_base__make_slice_u8(token_ptr, token_len);\n  while (encoded.len > 0) {\n    uint8_t decoded[64];\n    constexpr bool src_closed = true;\n    wuffs_base__transform__output o = wuffs_base__base_16__decode4(\n        wuffs_base__make_slice_u8(&decoded[0], sizeof decoded), encoded,\n        src_c" +
+	"losed, WUFFS_BASE__BASE_16__DEFAULT_OPTIONS);\n    if (o.status.is_error()) {\n      return o.status.message();\n    } else if ((o.num_dst > (sizeof decoded)) || (o.num_src > encoded.len)) {\n      return \"wuffs_aux::DecodeJson: internal error: inconsistent base16 \"\n             \"decoding\";\n    }\n    str.append(  // Convert from (uint8_t*).\n        static_cast<const char*>(static_cast<void*>(&decoded[0])), o.num_dst);\n    encoded.ptr += o.num_src;\n    encoded.len -= o.num_src;\n  }\n  return \"\";\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__STRUCTURE__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          } 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, token_len);\n          } else if (\n              vbd &\n              WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_4_SRC_BACKSLASH_X) {\n            ret_error_message =\n                DecodeJson_DecodeBackslashX(str, token_ptr, token_len);\n            if (!ret_error_message.empty()) {\n " +
+	"             goto done;\n            }\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_OPTIONS);\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      WU" +
+	"FFS_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 -= 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\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_u" +
+	"8__writer(fallback_io_array.get(), 4096);\n    io_buf = &fallback_io_buf;\n  }\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_r_tilde_n = 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_R_TILDE_N) {\n        allow_tilde_r_tilde_n = true;\n      }\n    }\n\n    // Prepare the wuffs_base__tok_buffer.\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    // Pre" +
+	"pare 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_r_tilde_n);\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 = to" +
+	"ken.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, token_len);\n          } else if " +
+	"(\n              vbd &\n              WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_4_SRC_BACKSLASH_X) {\n            ret_error_message =\n                DecodeJson_DecodeBackslashX(str, token_ptr, token_len);\n            if (!ret_error_message.empty()) {\n              goto done;\n            }\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          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, 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, 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.AppendF" +
+	"64(\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\nd" +
+	"one:\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 4b75f86..32567aa 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -7625,7 +7625,9 @@
 
 #define WUFFS_JSON__QUIRK_ALLOW_TRAILING_NEW_LINE 1225364497
 
-#define WUFFS_JSON__QUIRK_REPLACE_INVALID_UNICODE 1225364498
+#define WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_R_TILDE_N 1225364498
+
+#define WUFFS_JSON__QUIRK_REPLACE_INVALID_UNICODE 1225364499
 
 // ---------------- Struct Declarations
 
@@ -7715,7 +7717,7 @@
     wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
     wuffs_base__vtable null_vtable;
 
-    bool f_quirks[19];
+    bool f_quirks[20];
     bool f_allow_leading_ars;
     bool f_allow_leading_ubom;
     bool f_end_of_data;
@@ -25710,7 +25712,7 @@
 
 #define WUFFS_JSON__QUIRKS_BASE 1225364480
 
-#define WUFFS_JSON__QUIRKS_COUNT 19
+#define WUFFS_JSON__QUIRKS_COUNT 20
 
 // ---------------- Private Initializer Prototypes
 
@@ -25852,7 +25854,7 @@
 
   if (a_quirk >= 1225364480) {
     a_quirk -= 1225364480;
-    if (a_quirk < 19) {
+    if (a_quirk < 20) {
       self->private_impl.f_quirks[a_quirk] = a_enabled;
     }
   }
@@ -26214,7 +26216,7 @@
                   } else {
                     if (((uint64_t)(io2_a_src - iop_a_src)) < 12) {
                       if (a_src && a_src->meta.closed) {
-                        if (self->private_impl.f_quirks[18]) {
+                        if (self->private_impl.f_quirks[19]) {
                           (iop_a_src += 6, wuffs_base__make_empty_struct());
                           *iop_a_dst++ = wuffs_base__make_token(
                               (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
@@ -26265,7 +26267,7 @@
                       goto label__string_loop_outer__continue;
                     }
                   }
-                  if (self->private_impl.f_quirks[18]) {
+                  if (self->private_impl.f_quirks[19]) {
                     if (((uint64_t)(io2_a_src - iop_a_src)) < 6) {
                       status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
                       goto exit;
@@ -26324,7 +26326,7 @@
                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
                         (((uint64_t)(10)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
                     goto label__string_loop_outer__continue;
-                  } else if (self->private_impl.f_quirks[18]) {
+                  } else if (self->private_impl.f_quirks[19]) {
                     (iop_a_src += 10, wuffs_base__make_empty_struct());
                     *iop_a_dst++ = wuffs_base__make_token(
                         (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
@@ -26416,7 +26418,7 @@
                     }
                   }
                   if (a_src && a_src->meta.closed) {
-                    if (self->private_impl.f_quirks[18]) {
+                    if (self->private_impl.f_quirks[19]) {
                       *iop_a_dst++ = wuffs_base__make_token(
                           (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
@@ -26461,7 +26463,7 @@
                     }
                   }
                   if (a_src && a_src->meta.closed) {
-                    if (self->private_impl.f_quirks[18]) {
+                    if (self->private_impl.f_quirks[19]) {
                       *iop_a_dst++ = wuffs_base__make_token(
                           (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
@@ -26508,7 +26510,7 @@
                     }
                   }
                   if (a_src && a_src->meta.closed) {
-                    if (self->private_impl.f_quirks[18]) {
+                    if (self->private_impl.f_quirks[19]) {
                       *iop_a_dst++ = wuffs_base__make_token(
                           (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
@@ -26568,7 +26570,7 @@
                 status = wuffs_base__make_status(wuffs_json__error__bad_c0_control_code);
                 goto exit;
               }
-              if (self->private_impl.f_quirks[18]) {
+              if (self->private_impl.f_quirks[19]) {
                 *iop_a_dst++ = wuffs_base__make_token(
                     (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
                     (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
@@ -29435,10 +29437,15 @@
 
 namespace {
 
-// DecodeJson_SplitJsonPointer returns ("bar", 8) for ("/foo/bar/baz/qux", 5).
-// It returns a 0 size_t when s has invalid JSON Pointer syntax.
+// 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.
+//
+// The string returned is unescaped. If calling it again, this time with i=8,
+// the "b~1z" substring would be returned as "b/z".
 std::pair<std::string, size_t>  //
-DecodeJson_SplitJsonPointer(std::string& s, size_t i) {
+DecodeJson_SplitJsonPointer(std::string& s,
+                            size_t i,
+                            bool allow_tilde_r_tilde_n) {
   std::string fragment;
   while (i < s.size()) {
     char c = s[i];
@@ -29462,6 +29469,16 @@
       fragment.push_back('/');
       i++;
       continue;
+    } else if (allow_tilde_r_tilde_n) {
+      if (c == 'r') {
+        fragment.push_back('\r');
+        i++;
+        continue;
+      } else if (c == 'n') {
+        fragment.push_back('\n');
+        i++;
+        continue;
+      }
     }
     return std::make_pair(std::string(), 0);
   }
@@ -29709,8 +29726,13 @@
       ret_error_message = "wuffs_aux::DecodeJson: out of memory";
       goto done;
     }
+    bool allow_tilde_r_tilde_n = false;
     for (size_t i = 0; i < quirks.len; i++) {
       dec->set_quirk_enabled(quirks.ptr[i], true);
+      if (quirks.ptr[i] ==
+          WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_R_TILDE_N) {
+        allow_tilde_r_tilde_n = true;
+      }
     }
 
     // Prepare the wuffs_base__tok_buffer.
@@ -29730,8 +29752,8 @@
         ret_error_message = DecodeJson_BadJsonPointer;
         goto done;
       }
-      std::pair<std::string, size_t> split =
-          DecodeJson_SplitJsonPointer(json_pointer, i + 1);
+      std::pair<std::string, size_t> split = DecodeJson_SplitJsonPointer(
+          json_pointer, i + 1, allow_tilde_r_tilde_n);
       i = std::move(split.second);
       if (i == 0) {
         ret_error_message = DecodeJson_BadJsonPointer;
diff --git a/std/json/decode_quirks.wuffs b/std/json/decode_quirks.wuffs
index 2d9a97c..6fbe85f 100644
--- a/std/json/decode_quirks.wuffs
+++ b/std/json/decode_quirks.wuffs
@@ -197,6 +197,13 @@
 // line comment.
 pub const QUIRK_ALLOW_TRAILING_NEW_LINE : base.u32 = 0x4909_9400 | 0x11
 
+// When this quirk is enabled, JSON Pointer strings containing "~r" or "~n",
+// which would otherwise be invalid, are unescaped as "\r" or "\n".
+//
+// This quirk isn't used by Wuffs' std/json package per se, but it is used by
+// the wuffs_aux::DecodeJson function.
+pub const QUIRK_JSON_POINTER_ALLOW_TILDE_R_TILDE_N : base.u32 = 0x4909_9400 | 0x12
+
 // When this quirk is enabled, invalid UTF-8 inside a JSON string is accepted.
 // Each byte of invalid UTF-8 is equivalent to "\uFFFD", the Unicode
 // Replacement Character. The UTF-8 encoding of U+FFFD is "\xEF\xBF\xBD".
@@ -211,6 +218,6 @@
 // When combined with QUIRK_ALLOW_BACKSLASH_CAPITAL_U, a "\U12345678" 10-byte
 // unit that is an invalid Unicode code point (i.e. in the range U+D800 ..=
 // U+DFFF or above U+10FFFF) is similarly replaced with U+FFFD.
-pub const QUIRK_REPLACE_INVALID_UNICODE : base.u32 = 0x4909_9400 | 0x12
+pub const QUIRK_REPLACE_INVALID_UNICODE : base.u32 = 0x4909_9400 | 0x13
 
-pri const QUIRKS_COUNT : base.u32 = 0x13
+pri const QUIRKS_COUNT : base.u32 = 0x14