forked from weaselab/weaseljson
schemagen: reject scalar root values when root schema is object/array
The generated RootBuilder crashed (undefined behavior on std::vector::back()) when a JSON document's root value was a scalar or null while the schema declared a non-nullable object or array root. The stack starts empty for object/array roots, but cbStringData, cbNumberData, and cbBool called stack_.back() without checking for an empty stack. Add an empty-stack guard to the three scalar callbacks so they reject instead of crashing. cbNull already handles the empty-stack case. Regression tests added for: - non-nullable object root rejecting null, boolean, number, and string roots - nullable object root rejecting scalar roots - nullable array root rejecting scalar roots Closes #16
This commit is contained in:
@@ -184,6 +184,10 @@ int main() {
|
||||
expectReject(R"({"name":"x","age":1,"address":{"zip":5}})",
|
||||
"missing required nested 'city'");
|
||||
expectReject(R"([1,2,3])", "array where object expected (root)");
|
||||
expectReject("null", "null where object expected (root)");
|
||||
expectReject("true", "boolean where object expected (root)");
|
||||
expectReject("123", "number where object expected (root)");
|
||||
expectReject(R"("hi")", "string where object expected (root)");
|
||||
expectReject(R"({"name":"x","age":1,)", "truncated / invalid json");
|
||||
|
||||
if (failures == 0) {
|
||||
|
||||
@@ -61,6 +61,18 @@ static void expectReject(nullable_object::RootBuilder &b, std::string in,
|
||||
}
|
||||
}
|
||||
|
||||
static void expectReject(nullable_array::RootBuilder &b, std::string in,
|
||||
const char *what) {
|
||||
WeaselJsonStatus s = parseStrided(b, in);
|
||||
if (s == WeaselJson_REJECT) {
|
||||
printf("ok reject: %s\n", what);
|
||||
} else {
|
||||
printf("FAIL expected reject (%s) got status %d for: %s\n", what, s,
|
||||
in.c_str());
|
||||
++failures;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// ---- nullable root object: valid document ----
|
||||
{
|
||||
@@ -149,6 +161,34 @@ int main() {
|
||||
}
|
||||
}
|
||||
|
||||
// ---- nullable root object: scalar values rejected ----
|
||||
{
|
||||
nullable_object::RootBuilder b;
|
||||
expectReject(b, "true", "boolean where nullable object expected (root)");
|
||||
}
|
||||
{
|
||||
nullable_object::RootBuilder b;
|
||||
expectReject(b, "123", "number where nullable object expected (root)");
|
||||
}
|
||||
{
|
||||
nullable_object::RootBuilder b;
|
||||
expectReject(b, R"("hi")", "string where nullable object expected (root)");
|
||||
}
|
||||
|
||||
// ---- nullable root array: scalar values rejected ----
|
||||
{
|
||||
nullable_array::RootBuilder b;
|
||||
expectReject(b, "true", "boolean where nullable array expected (root)");
|
||||
}
|
||||
{
|
||||
nullable_array::RootBuilder b;
|
||||
expectReject(b, "123", "number where nullable array expected (root)");
|
||||
}
|
||||
{
|
||||
nullable_array::RootBuilder b;
|
||||
expectReject(b, R"("hi")", "string where nullable array expected (root)");
|
||||
}
|
||||
|
||||
if (failures == 0) {
|
||||
printf("\nALL TESTS PASSED\n");
|
||||
return 0;
|
||||
|
||||
@@ -1098,6 +1098,7 @@ private:
|
||||
|
||||
void cbStringData(const char *buf, int len, int done) {{
|
||||
if (error_) return;
|
||||
if (stack_.empty()) {{ reject(); return; }}
|
||||
Frame &f = stack_.back();
|
||||
SlotInfo si = slotInfoG(f);
|
||||
if (si.cat == Cat::Str) {{
|
||||
@@ -1124,6 +1125,7 @@ private:
|
||||
|
||||
void cbNumberData(const char *buf, int len, int done) {{
|
||||
if (error_) return;
|
||||
if (stack_.empty()) {{ reject(); return; }}
|
||||
Frame &f = stack_.back();
|
||||
SlotInfo si = slotInfoG(f);
|
||||
if (si.cat != Cat::Int && si.cat != Cat::Dbl) {{ reject(); return; }}
|
||||
@@ -1157,6 +1159,7 @@ private:
|
||||
|
||||
void cbBool(bool value) {{
|
||||
if (error_) return;
|
||||
if (stack_.empty()) {{ reject(); return; }}
|
||||
Frame &f = stack_.back();
|
||||
SlotInfo si = slotInfoG(f);
|
||||
if (si.cat != Cat::Bool) {{ reject(); return; }}
|
||||
|
||||
Reference in New Issue
Block a user