diff options
author | Jo-Philipp Wich <jo@mein.io> | 2021-03-19 17:33:46 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2021-03-19 17:39:45 +0100 |
commit | 4a5b9010ccc56fdf288fe758023af445feb93fad (patch) | |
tree | 030788347c69efc2aff5a7b4c06d9f7d889e4b82 | |
parent | 647c6a7927c5c6ef2941ba1dc3c1d40c2c7d7f34 (diff) |
value: fix accessing array indexes with non-numeric values
Since libjson-c's json_object_get_int64() returns 0 for any input value
that has no integer representation, any kind of invalid array index
incorrectly yielded the first array element.
Fix this issue by explicitly converting string values and by rejecting
any other kind of value.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r-- | tests/03_bugs/09_reject_invalid_array_indexes | 25 | ||||
-rw-r--r-- | value.c | 14 |
2 files changed, 36 insertions, 3 deletions
diff --git a/tests/03_bugs/09_reject_invalid_array_indexes b/tests/03_bugs/09_reject_invalid_array_indexes new file mode 100644 index 0000000..a7e5272 --- /dev/null +++ b/tests/03_bugs/09_reject_invalid_array_indexes @@ -0,0 +1,25 @@ +Since libjson-c's json_object_get_int64() returns 0 for any input value +that has no integer representation, any kind of invalid array index +incorrectly yielded the first array element. + +-- Testcase -- +{% + x = [1, 2, 3]; + + print([ + x[1], + x["1"], + x[1.0], + x[1.1], + x.foo, + x["foo"], + x["0abc"], + x[x], + x[{ foo: true }] + ], "\n"); +%} +-- End -- + +-- Expect stdout -- +[ 2, 2, 2, null, null, null, null, null, null ] +-- End -- @@ -205,6 +205,7 @@ uc_getval(json_object *scope, json_object *key) const char *k; int64_t idx; double d; + char *e; if (json_object_is_type(scope, json_type_array)) { /* only consider doubles with integer values as array keys */ @@ -216,13 +217,20 @@ uc_getval(json_object *scope, json_object *key) else idx = -1; } - else { - errno = 0; + else if (json_object_is_type(key, json_type_int)) { idx = json_object_get_int64(key); + } + else if (json_object_is_type(key, json_type_string)) { + errno = 0; + k = json_object_get_string(key); + idx = strtoll(k, &e, 0); - if (errno != 0) + if (errno != 0 || e == k || *e != 0) idx = -1; } + else { + idx = -1; + } if (idx >= 0 && idx < json_object_array_length(scope)) return json_object_get(json_object_array_get_idx(scope, idx)); |