More JSON tests

This commit is contained in:
cpq committed 2022-09-02 16:23:39 +01:00
1 parent 51076e68c8
commit 0d385c29a3
3 files changed
+39 -46

No files matched your search

+16 -24
View File
@@ -2494,12 +2494,12 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
// In the ascii table, the distance between `[` and `]` is 2.
// Ditto for `{` and `}`. Hence +2 in the code below.
#define MG_EOO(x) \
do { \
if (depth == ed && (ci != ei || ci < 0)) return MG_JSON_NOT_FOUND; \
if (c != nesting[depth - 1] + 2) return MG_JSON_INVALID; \
depth--; \
MG_CHECKRET(x); \
#define MG_EOO(x) \
do { \
if (depth == ed && ci != ei) return MG_JSON_NOT_FOUND; \
if (c != nesting[depth - 1] + 2) return MG_JSON_INVALID; \
depth--; \
MG_CHECKRET(x); \
} while (0)
for (i = 0; i < len; i++) {
@@ -2507,14 +2507,11 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') continue;
switch (expecting) {
case S_VALUE:
if (depth == ed && ei == ci && c != '[' && path[pos] == '[') {
// Expecting array start, but got something else
return MG_JSON_NOT_FOUND;
}
// p("V %s [%.*s] %d %d %d %d\n", path, pos, path, depth, ed, ci, ei);
if (depth == ed) j = i;
if (c == '{') {
if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
if (depth == ed && path[pos] == '.' && (ci == ei || ci < 0)) {
if (depth == ed && path[pos] == '.' && ci == ei) {
// If we start the object, reset array indices
ed++, pos++, ci = ei = -1;
}
@@ -2534,7 +2531,6 @@ 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; // Array ends. Reset current index
MG_EOO(']');
} else if (c == 't' && i + 3 < len && memcmp(&s[i], "true", 4) == 0) {
i += 3;
@@ -2554,24 +2550,21 @@ 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 (ci > ei) return MG_JSON_NOT_FOUND;
}
if (depth == ed && ei >= 0) ci++;
expecting = S_COMMA_OR_EOO;
break;
case S_KEY:
if (c == '"') {
int n = mg_pass_string(&s[i + 1], len - i - 1);
// printf("K1 %s %d %d %d [%.*s]\n", path, pos, n, i, n + 2, s + i);
if (n < 0) return n;
if (i + 1 + n >= len) return MG_JSON_NOT_FOUND;
// printf("K2 %s [%.*s] %d %d %d\n", path, n, &s[i + 1], n, depth,
// ed);
// NOTE(cpq): in the check sequence below is important.
// strncmp() must go first: it fails fast if the remaining length of
// the path is smaller than `n`.
if (depth < ed) return MG_JSON_NOT_FOUND;
// printf("K %s [%.*s] [%.*s] %d %d %d\n", path, pos, path, n,
// &s[i + 1], n, depth, ed);
// NOTE(cpq): in the check sequence below is important.
// strncmp() must go first: it fails fast if the remaining length of
// the path is smaller than `n`.
if (depth == ed && path[pos - 1] == '.' &&
strncmp(&s[i + 1], &path[pos], (size_t) n) == 0 &&
(path[pos + n] == '\0' || path[pos + n] == '.' ||
@@ -2602,7 +2595,6 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
} else if (c == ',') {
expecting = (nesting[depth - 1] == '{') ? S_KEY : S_VALUE;
} else if (c == ']' || c == '}') {
if (depth == ed && ei >= 0) ci--; // Array ends, as ci is pre-added by 1, needs to be decremented before MG_EOO
MG_EOO('O');
if (depth == ed && ei >= 0) ci++;
} else {
@@ -6934,7 +6926,7 @@ static void on_rx(void *buf, size_t len, void *userdata) {
void mip_init(struct mg_mgr *mgr, struct mip_cfg *ipcfg,
struct mip_driver *driver, void *driver_data) {
if (driver->init && !driver->init(ipcfg->mac, driver_data)) {
MG_ERROR(("ERROR intialising driver"));
MG_ERROR(("driver init failed"));
} else {
size_t maxpktsize = 1500, qlen = driver->setrx ? 1024 * 16 : 0;
struct mip_if *ifp =
+15 -22
View File
@@ -98,12 +98,12 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
// In the ascii table, the distance between `[` and `]` is 2.
// Ditto for `{` and `}`. Hence +2 in the code below.
#define MG_EOO(x) \
do { \
if (depth == ed && (ci != ei || ci < 0)) return MG_JSON_NOT_FOUND; \
if (c != nesting[depth - 1] + 2) return MG_JSON_INVALID; \
depth--; \
MG_CHECKRET(x); \
#define MG_EOO(x) \
do { \
if (depth == ed && ci != ei) return MG_JSON_NOT_FOUND; \
if (c != nesting[depth - 1] + 2) return MG_JSON_INVALID; \
depth--; \
MG_CHECKRET(x); \
} while (0)
for (i = 0; i < len; i++) {
@@ -111,14 +111,11 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') continue;
switch (expecting) {
case S_VALUE:
if (depth == ed && ei == ci && c != '[' && path[pos] == '[') {
// Expecting array start, but got something else
return MG_JSON_NOT_FOUND;
}
// p("V %s [%.*s] %d %d %d %d\n", path, pos, path, depth, ed, ci, ei);
if (depth == ed) j = i;
if (c == '{') {
if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
if (depth == ed && path[pos] == '.' && (ci == ei || ci < 0)) {
if (depth == ed && path[pos] == '.' && ci == ei) {
// If we start the object, reset array indices
ed++, pos++, ci = ei = -1;
}
@@ -138,7 +135,6 @@ 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; // Array ends. Reset current index
MG_EOO(']');
} else if (c == 't' && i + 3 < len && memcmp(&s[i], "true", 4) == 0) {
i += 3;
@@ -158,24 +154,21 @@ 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 (ci > ei) return MG_JSON_NOT_FOUND;
}
if (depth == ed && ei >= 0) ci++;
expecting = S_COMMA_OR_EOO;
break;
case S_KEY:
if (c == '"') {
int n = mg_pass_string(&s[i + 1], len - i - 1);
// printf("K1 %s %d %d %d [%.*s]\n", path, pos, n, i, n + 2, s + i);
if (n < 0) return n;
if (i + 1 + n >= len) return MG_JSON_NOT_FOUND;
// printf("K2 %s [%.*s] %d %d %d\n", path, n, &s[i + 1], n, depth,
// ed);
// NOTE(cpq): in the check sequence below is important.
// strncmp() must go first: it fails fast if the remaining length of
// the path is smaller than `n`.
if (depth < ed) return MG_JSON_NOT_FOUND;
// printf("K %s [%.*s] [%.*s] %d %d %d\n", path, pos, path, n,
// &s[i + 1], n, depth, ed);
// NOTE(cpq): in the check sequence below is important.
// strncmp() must go first: it fails fast if the remaining length of
// the path is smaller than `n`.
if (depth == ed && path[pos - 1] == '.' &&
strncmp(&s[i + 1], &path[pos], (size_t) n) == 0 &&
(path[pos + n] == '\0' || path[pos + n] == '.' ||
+8
View File
@@ -2482,6 +2482,7 @@ static void test_json(void) {
ASSERT(mg_json_get_bool(json, "$.b[0]", &b) == false);
ASSERT(mg_json_get_bool(json, "$.b[1]", &b) == true);
ASSERT(b == true);
ASSERT(mg_json_get(json, "$.b[2]", &len) < 0);
json = mg_str("[\"YWJj\", \"0100026869\"]");
ASSERT((str = mg_json_get_b64(json, "$[0]", &len)) != NULL);
@@ -2512,6 +2513,13 @@ static void test_json(void) {
ASSERT(mg_json_get_long(json, "$.a[0]", -42) == 1);
ASSERT(mg_json_get_long(json, "$.a[1]", -42) == -42);
json = mg_str("{\"a\":[1,[2,3], 4]}");
ASSERT(mg_json_get_long(json, "$.a[0]", -42) == 1);
ASSERT(mg_json_get_long(json, "$.a[1][0]", -42) == 2);
ASSERT(mg_json_get_long(json, "$.a[1][1]", -42) == 3);
ASSERT(mg_json_get_long(json, "$.a[1][2]", -42) == -42);
ASSERT(mg_json_get_long(json, "$.a[2]", -42) == 4);
ASSERT(mg_json_get_long(json, "$.a[3]", -42) == -42);
}
}