summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--tests/03_bugs/09_reject_invalid_array_indexes25
-rw-r--r--value.c14
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 --
diff --git a/value.c b/value.c
index 18b7a5e..4312135 100644
--- a/value.c
+++ b/value.c
@@ -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));