WeaselJsonParser_reset does not clear inKey, misrouting string callbacks #2

Closed
opened 2026-06-17 23:38:03 +00:00 by weaselbot · 0 comments
Member

WeaselJsonParser_reset is documented in include/weaseljson.h line 60 as restoring the parser to its newly-created state, but Parser3::reset() in src/parser3.h (line 138) only resets the symbol stack. It does not reset the inKey member (declared at line 157), so transient key/string state from the previous parse leaks into the next parse.

Impact: if a chunk ends while the parser is inside an object key, the parser leaves inKey == true. After WeaselJsonParser_reset, a subsequent top-level string value is delivered through on_key_data instead of on_string_data.

Reproducer:

auto *p = WeaselJsonParser_create(1024, &callbacks, nullptr, 0);
WeaselJsonParser_parse(p, "{\"ab", 4);  // returns AGAIN, parser is mid-key
WeaselJsonParser_reset(p);
WeaselJsonStatus r = WeaselJsonParser_parse(p, "\"hello\"", 7);
if (r == WeaselJson_AGAIN) r = WeaselJsonParser_parse(p, nullptr, 0);
// r == WeaselJson_OK, but callbacks receive "abhello" via on_key_data,
// not "hello" via on_string_data.

Expected behavior: reset() should set inKey = false and clear any other per-parse transient state (e.g. utf8Codepoint, utf16Surrogate, numDfa, strDfa) so that the next document starts from the same state as a newly created parser.

Files/lines:

  • src/parser3.h:138reset() implementation
  • src/parser3.h:157bool inKey = false;
  • src/lib.cpp:31-32 — C wrapper calling reset()
  • include/weaseljson.h:59-60 — contract comment
`WeaselJsonParser_reset` is documented in `include/weaseljson.h` line 60 as restoring the parser to its newly-created state, but `Parser3::reset()` in `src/parser3.h` (line 138) only resets the symbol stack. It does not reset the `inKey` member (declared at line 157), so transient key/string state from the previous parse leaks into the next parse. Impact: if a chunk ends while the parser is inside an object key, the parser leaves `inKey == true`. After `WeaselJsonParser_reset`, a subsequent top-level string value is delivered through `on_key_data` instead of `on_string_data`. Reproducer: ```cpp auto *p = WeaselJsonParser_create(1024, &callbacks, nullptr, 0); WeaselJsonParser_parse(p, "{\"ab", 4); // returns AGAIN, parser is mid-key WeaselJsonParser_reset(p); WeaselJsonStatus r = WeaselJsonParser_parse(p, "\"hello\"", 7); if (r == WeaselJson_AGAIN) r = WeaselJsonParser_parse(p, nullptr, 0); // r == WeaselJson_OK, but callbacks receive "abhello" via on_key_data, // not "hello" via on_string_data. ``` Expected behavior: `reset()` should set `inKey = false` and clear any other per-parse transient state (e.g. `utf8Codepoint`, `utf16Surrogate`, `numDfa`, `strDfa`) so that the next document starts from the same state as a newly created parser. Files/lines: - `src/parser3.h:138` — `reset()` implementation - `src/parser3.h:157` — `bool inKey = false;` - `src/lib.cpp:31-32` — C wrapper calling `reset()` - `include/weaseljson.h:59-60` — contract comment
weaselbot was assigned by andrew 2026-06-18 14:05:32 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: weaselab/weaseljson#2