From a686beb9a7976d790e2ee6caf14747138899529c Mon Sep 17 00:00:00 2001 From: oakfire Date: Tue, 30 Aug 2022 14:22:58 +0800 Subject: [PATCH] fix: #1696 mg_json_get() bugs. --- mongoose.c | 19 ++++++++++++++++--- test/unit_test.c | 13 +++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/mongoose.c b/mongoose.c index d94ce7ef..d811e7f3 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2517,10 +2517,15 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) { MG_DBGP('-'); switch (expecting) { case S_VALUE: + if ( depth == ed && ei == ci && c != '[' && path[pos] == '[' ) return MG_JSON_NOT_FOUND; if (depth == ed) j = i; if (c == '{') { if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP; - if (depth == ed && path[pos] == '.') ed++, pos++; + if (depth == ed && (ci == ei || ci < 0) && path[pos] == '.') { + ed++, pos++; + ci = -1; + ei = -1; + } nesting[depth++] = c; expecting = S_KEY; break; @@ -2537,6 +2542,7 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) { nesting[depth++] = c; break; } else if (c == ']' && depth > 0) { // Empty array + if (depth == ed) ci = -1; MG_EOO(']'); } else if (c == 't' && i + 3 < len && memcmp(&s[i], "true", 4) == 0) { i += 3; @@ -2556,7 +2562,11 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) { return MG_JSON_INVALID; } MG_CHECKRET('V'); - if (depth == ed && ei >= 0) ci++; + if (depth == ed && ei >= 0) { + ci++; + if (ci > ei) return MG_JSON_NOT_FOUND; + } + expecting = S_COMMA_OR_EOO; break; @@ -2602,7 +2612,10 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) { // MG_CHECKRET('C'); } else if (c == ']' || c == '}') { MG_EOO('O'); - if (depth == ed && ei >= 0) ci++; + if (depth == ed && ei >= 0) { + ci++; + if (ci > ei) return MG_JSON_NOT_FOUND; + } } else { return MG_JSON_INVALID; } diff --git a/test/unit_test.c b/test/unit_test.c index a34842e6..58948996 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -2495,6 +2495,19 @@ static void test_json(void) { ASSERT(mg_json_get_long(json, "$.a[0]", -42) == 1); ASSERT(mg_json_get_long(json, "$.ab", -42) == 2); ASSERT(mg_json_get_long(json, "$.ac", -42) == -42); + + json = mg_str("{\"a\":[],\"b\":[1,2]}"); + ASSERT(mg_json_get_long(json, "$.a[0]", -42) == -42); + ASSERT(mg_json_get_long(json, "$.b[0]", -42) == 1); + ASSERT(mg_json_get_long(json, "$.b[1]", -42) == 2); + ASSERT(mg_json_get_long(json, "$.b[2]", -42) == -42); + json = mg_str("[{\"a\":1,\"b\":2},{\"a\":3, \"b\":4}]"); + ASSERT(mg_json_get_long(json, "$[0].a", -42) == 1); + ASSERT(mg_json_get_long(json, "$[0].b", -42) == 2); + ASSERT(mg_json_get_long(json, "$[1].a", -42) == 3); + ASSERT(mg_json_get_long(json, "$[1].b", -42) == 4); + ASSERT(mg_json_get_long(json, "$[2].a", -42) == -42); + } }