From 4b3090a9abba3fa5b94a46c5f44944deec17d5d4 Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Sun, 16 Jul 2023 11:56:36 +0200 Subject: [PATCH] Make stream parser error when a non-empty object or array is used as key Fixes #2463 --- src/jv_parse.c | 22 ++++++++++++++++++++++ tests/shtest | 10 ++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/jv_parse.c b/src/jv_parse.c index 2caf330b29..3a8718ae82 100644 --- a/src/jv_parse.c +++ b/src/jv_parse.c @@ -246,6 +246,17 @@ static pfunc stream_token(struct jv_parser* p, char ch) { case '[': if (jv_is_valid(p->next)) return "Expected a separator between values"; + if (p->last_seen == JV_LAST_OPEN_OBJECT) + // Looks like {["foo"]} + return "Expected string key after '{', not '['"; + if (p->last_seen == JV_LAST_COMMA) { + last = jv_array_get(jv_copy(p->path), p->stacklen - 1); + k = jv_get_kind(last); + jv_free(last); + if (k != JV_KIND_NUMBER) + // Looks like {"x":"y",["foo"]} + return "Expected string key after ',' in object, not '['"; + } p->path = jv_array_append(p->path, jv_number(0)); // push p->last_seen = JV_LAST_OPEN_ARRAY; p->stacklen++; @@ -254,6 +265,17 @@ static pfunc stream_token(struct jv_parser* p, char ch) { case '{': if (p->last_seen == JV_LAST_VALUE) return "Expected a separator between values"; + if (p->last_seen == JV_LAST_OPEN_OBJECT) + // Looks like {{"foo":"bar"}} + return "Expected string key after '{', not '{'"; + if (p->last_seen == JV_LAST_COMMA) { + last = jv_array_get(jv_copy(p->path), p->stacklen - 1); + k = jv_get_kind(last); + jv_free(last); + if (k != JV_KIND_NUMBER) + // Looks like {"x":"y",{"foo":"bar"}} + return "Expected string key after ',' in object, not '{'"; + } // Push object key: null, since we don't know it yet p->path = jv_array_append(p->path, jv_null()); // push p->last_seen = JV_LAST_OPEN_OBJECT; diff --git a/tests/shtest b/tests/shtest index 8af791ae2e..a7fba4451d 100755 --- a/tests/shtest +++ b/tests/shtest @@ -222,6 +222,16 @@ fi echo '{"a":1,"b",' | $JQ --stream > /dev/null 2> $d/err || true grep 'Objects must consist of key:value pairs' $d/err > /dev/null +## Regression tests for issue #2463 assert when stream parse non-scalar object key +echo '{{"a":"b"}}' | $JQ --stream > /dev/null 2> $d/err || true +grep "Expected string key after '{', not '{'" $d/err > /dev/null +echo '{"x":"y",{"a":"b"}}' | $JQ --stream > /dev/null 2> $d/err || true +grep "Expected string key after ',' in object, not '{'" $d/err > /dev/null +echo '{["a","b"]}' | $JQ --stream > /dev/null 2> $d/err || true +grep "Expected string key after '{', not '\\['" $d/err > /dev/null +echo '{"x":"y",["a","b"]}' | $JQ --stream > /dev/null 2> $d/err || true +grep "Expected string key after ',' in object, not '\\['" $d/err > /dev/null + ## Regression test for issue #2572 assert when using --jsonargs and invalid JSON $JQ -n --jsonargs null invalid && EC=$? || EC=$? if [ "$EC" -ne 2 ]; then