Super final review: fix cj_unescape_string data-loss, escape-scan infinite loop, operator[] destructor Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
diff --git a/tinygltf_json.h b/tinygltf_json.h index 0e7e9e1..f6a0203 100644 --- a/tinygltf_json.h +++ b/tinygltf_json.h
@@ -440,7 +440,16 @@ char *dst = out; while (p < str_end) { + /* Track start of literal run so we can copy it before processing + * the special character that ends it. */ + const char *run = p; p = cj_scan_str(p, str_end); + /* Copy non-special (literal) bytes from run to p */ + if (p > run) { + size_t n = (size_t)(p - run); + memcpy(dst, run, n); + dst += n; + } if (p >= str_end) break; unsigned char c = (unsigned char)*p; @@ -1090,9 +1099,10 @@ size_t klen = strlen(key); nm->key = (char *)malloc(klen + 1); if (!nm->key) { - /* Roll back insertion on key allocation failure: do not bump - * obj_size_, and return the shared null fallback, keeping the + /* Roll back insertion on key allocation failure: destroy the + * placement-new'd member and do not bump obj_size_, keeping the * object in a consistent state. */ + nm->~tinygltf_json_member(); return null_fallback; } memcpy(nm->key, key, klen + 1); @@ -1298,6 +1308,10 @@ } else { ++scan; } + } else { + /* cj_scan_str stopped at a control char (<0x20): invalid JSON */ + cj_ctx_error(ctx, "invalid control character in string"); + *out_str = NULL; *out_len = 0; return; } } /* After the loop, scan must point to the closing '"' */