The parser is not sticky after it returns WeaselJson_REJECT. If an invalid byte arrives in one chunk and the caller later calls WeaselJsonParser_parse(parser, nullptr, 0) to finish, the parser can return WeaselJson_OK and make the malformed input look valid.
Minimal reproduction (C API):
WeaselJsonCallbacksc={/* all no-op callbacks set */};WeaselJsonParser*p=WeaselJsonParser_create(1024,&c,NULL,0);chara[]="1";charb[]="x";printf("chunk1 %d\n",WeaselJsonParser_parse(p,a,1));// 1 = AGAIN
printf("chunk2 %d\n",WeaselJsonParser_parse(p,b,1));// 2 = REJECT
printf("final %d\n",WeaselJsonParser_parse(p,NULL,0));// 0 = OK (bug)
The input 1x is not valid JSON, yet the final EOF call reports OK.
Relevant code:
src/parser3.h lines 1062-1078: Parser3::parse re-dispatches from whatever symbol is on top of the stack without checking whether a previous step already rejected the document.
src/lib.cpp line 43: WeaselJsonParser_parse just forwards into Parser3::parse.
src/parser3.h lines 1015-1021: once the stack collapses to T_EOF, t_eof returns OK as soon as buf == bufEnd, regardless of prior rejections.
Expected behavior: after WeaselJsonParser_parse has returned WeaselJson_REJECT once, every subsequent call (including the final len == 0 call) must return WeaselJson_REJECT.
Actual behavior: subsequent calls may return WeaselJson_OK if the top-of-stack symbol happens to be T_EOF when the buffer is empty.
Impact: streaming consumers that detect a reject mid-stream but still call finish() can be tricked into accepting malformed input. This breaks the API contract that WeaselJson_REJECT means the document is invalid.
The parser is not sticky after it returns `WeaselJson_REJECT`. If an invalid byte arrives in one chunk and the caller later calls `WeaselJsonParser_parse(parser, nullptr, 0)` to finish, the parser can return `WeaselJson_OK` and make the malformed input look valid.
Minimal reproduction (C API):
```c
WeaselJsonCallbacks c = { /* all no-op callbacks set */ };
WeaselJsonParser *p = WeaselJsonParser_create(1024, &c, NULL, 0);
char a[] = "1";
char b[] = "x";
printf("chunk1 %d\n", WeaselJsonParser_parse(p, a, 1)); // 1 = AGAIN
printf("chunk2 %d\n", WeaselJsonParser_parse(p, b, 1)); // 2 = REJECT
printf("final %d\n", WeaselJsonParser_parse(p, NULL, 0)); // 0 = OK (bug)
```
The input `1x` is not valid JSON, yet the final EOF call reports `OK`.
Relevant code:
- `src/parser3.h` lines 1062-1078: `Parser3::parse` re-dispatches from whatever symbol is on top of the stack without checking whether a previous step already rejected the document.
- `src/lib.cpp` line 43: `WeaselJsonParser_parse` just forwards into `Parser3::parse`.
- `src/parser3.h` lines 1015-1021: once the stack collapses to `T_EOF`, `t_eof` returns `OK` as soon as `buf == bufEnd`, regardless of prior rejections.
Expected behavior: after `WeaselJsonParser_parse` has returned `WeaselJson_REJECT` once, every subsequent call (including the final `len == 0` call) must return `WeaselJson_REJECT`.
Actual behavior: subsequent calls may return `WeaselJson_OK` if the top-of-stack symbol happens to be `T_EOF` when the buffer is empty.
Impact: streaming consumers that detect a reject mid-stream but still call `finish()` can be tricked into accepting malformed input. This breaks the API contract that `WeaselJson_REJECT` means the document is invalid.
weaselbot
was assigned by andrew2026-06-19 16:50:19 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The parser is not sticky after it returns
WeaselJson_REJECT. If an invalid byte arrives in one chunk and the caller later callsWeaselJsonParser_parse(parser, nullptr, 0)to finish, the parser can returnWeaselJson_OKand make the malformed input look valid.Minimal reproduction (C API):
The input
1xis not valid JSON, yet the final EOF call reportsOK.Relevant code:
src/parser3.hlines 1062-1078:Parser3::parsere-dispatches from whatever symbol is on top of the stack without checking whether a previous step already rejected the document.src/lib.cppline 43:WeaselJsonParser_parsejust forwards intoParser3::parse.src/parser3.hlines 1015-1021: once the stack collapses toT_EOF,t_eofreturnsOKas soon asbuf == bufEnd, regardless of prior rejections.Expected behavior: after
WeaselJsonParser_parsehas returnedWeaselJson_REJECTonce, every subsequent call (including the finallen == 0call) must returnWeaselJson_REJECT.Actual behavior: subsequent calls may return
WeaselJson_OKif the top-of-stack symbol happens to beT_EOFwhen the buffer is empty.Impact: streaming consumers that detect a reject mid-stream but still call
finish()can be tricked into accepting malformed input. This breaks the API contract thatWeaselJson_REJECTmeans the document is invalid.