The generated RootBuilder crashes (undefined behavior / assertion failure) when the JSON document root is a scalar value or null while the schema declares a non-nullable object or array root.
Relevant generated-code paths in contrib/schemagen/weaseljson_schemagen.py:
Lines 788-793 (_ctor_body): only pushes an initial Kind::RootScalar frame when the root is a scalar. For object/array roots the stack starts empty.
Lines 795-824 (_begin_container): handles empty-stack container starts by pushing a root frame, but only for { and [ events.
Lines 964-1000 (cbStringData), 1002-1042 (cbNumberData), 1044-1057 (cbBool), and 1061-1072 (cbNull): all call Frame &f = stack_.back(); without first checking stack_.empty().
Reproduction using the existing example.schema.json (root object):
RootBuilderb;std::stringjson="null";// also "true", "123", or "\"hi\""
WeaselJsonStatuss=b.feed(json.data(),(int)json.size());if(s==WeaselJson_AGAIN)s=b.finish();
Actual result: assertion failure at std::vector::back() because stack_ is empty:
Expected result: WeaselJson_REJECT (the JSON value does not match the object/array root type).
The same crash occurs for a root array schema when the input is any scalar or null.
Impact: any schema with an object or array root will crash instead of rejecting malformed/untrusted input that happens to be a scalar or null. This contradicts the parser's documented claim of being "robust to crashes with untrusted input" and makes the generated builder unsuitable for directly handling untrusted documents.
The generated `RootBuilder` crashes (undefined behavior / assertion failure) when the JSON document root is a scalar value or `null` while the schema declares a non-nullable object or array root.
**Relevant generated-code paths in `contrib/schemagen/weaseljson_schemagen.py`:**
- Lines 788-793 (`_ctor_body`): only pushes an initial `Kind::RootScalar` frame when the root is a scalar. For object/array roots the stack starts empty.
- Lines 795-824 (`_begin_container`): handles empty-stack container starts by pushing a root frame, but only for `{` and `[` events.
- Lines 964-1000 (`cbStringData`), 1002-1042 (`cbNumberData`), 1044-1057 (`cbBool`), and 1061-1072 (`cbNull`): all call `Frame &f = stack_.back();` without first checking `stack_.empty()`.
**Reproduction** using the existing `example.schema.json` (root object):
```cpp
RootBuilder b;
std::string json = "null"; // also "true", "123", or "\"hi\""
WeaselJsonStatus s = b.feed(json.data(), (int)json.size());
if (s == WeaselJson_AGAIN) s = b.finish();
```
Actual result: assertion failure at `std::vector::back()` because `stack_` is empty:
```
/usr/include/c++/.../stl_vector.h:...: __builtin_expect(!this->_M_impl._M_start, true): Assertion '!this->empty()' failed.
```
Expected result: `WeaselJson_REJECT` (the JSON value does not match the object/array root type).
The same crash occurs for a root array schema when the input is any scalar or `null`.
**Impact:** any schema with an object or array root will crash instead of rejecting malformed/untrusted input that happens to be a scalar or `null`. This contradicts the parser's documented claim of being "robust to crashes with untrusted input" and makes the generated builder unsuitable for directly handling untrusted documents.
weaselbot
was assigned by andrew2026-06-24 17:24:38 +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 generated
RootBuildercrashes (undefined behavior / assertion failure) when the JSON document root is a scalar value ornullwhile the schema declares a non-nullable object or array root.Relevant generated-code paths in
contrib/schemagen/weaseljson_schemagen.py:_ctor_body): only pushes an initialKind::RootScalarframe when the root is a scalar. For object/array roots the stack starts empty._begin_container): handles empty-stack container starts by pushing a root frame, but only for{and[events.cbStringData), 1002-1042 (cbNumberData), 1044-1057 (cbBool), and 1061-1072 (cbNull): all callFrame &f = stack_.back();without first checkingstack_.empty().Reproduction using the existing
example.schema.json(root object):Actual result: assertion failure at
std::vector::back()becausestack_is empty:Expected result:
WeaselJson_REJECT(the JSON value does not match the object/array root type).The same crash occurs for a root array schema when the input is any scalar or
null.Impact: any schema with an object or array root will crash instead of rejecting malformed/untrusted input that happens to be a scalar or
null. This contradicts the parser's documented claim of being "robust to crashes with untrusted input" and makes the generated builder unsuitable for directly handling untrusted documents.