summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Williams <nico@cryptonector.com>2017-03-01 17:35:08 -0600
committerNicolas Williams <nico@cryptonector.com>2017-03-01 17:48:45 -0600
commit65cbaac34498a75973e26799dc03dd81bd27e5ad (patch)
tree94bd8d57af3957acded87c4d86783c9cd78d168f
parent2fcb25716827d92f3056e05a6e0db123e07b64f2 (diff)
Array slice overflows (fix #1108)
-rw-r--r--src/jv.c16
-rw-r--r--tests/jq.test9
2 files changed, 21 insertions, 4 deletions
diff --git a/src/jv.c b/src/jv.c
index 5e54d2f3..c2448a7c 100644
--- a/src/jv.c
+++ b/src/jv.c
@@ -296,10 +296,18 @@ static jv jvp_array_slice(jv a, int start, int end) {
jv_free(a);
return jv_array();
}
- // FIXME FIXME FIXME large offsets
- a.offset += start;
- a.size = end - start;
- return a;
+
+ if (a.offset + start > 1 << (sizeof(a.offset) * CHAR_BIT)) {
+ jv r = jv_array_sized(end - start);
+ for (int i = start; i < end; i++)
+ r = jv_array_append(r, jv_array_get(jv_copy(a), i));
+ jv_free(a);
+ return r;
+ } else {
+ a.offset += start;
+ a.size = end - start;
+ return a;
+ }
}
/*
diff --git a/tests/jq.test b/tests/jq.test
index 4dad2308..930bf794 100644
--- a/tests/jq.test
+++ b/tests/jq.test
@@ -383,6 +383,15 @@ del(.[2:4],.[0],.[-2:])
[0,1,"a","b",4,5,6,7]
[0,1,"a","b","c",4,5,6,7]
+# Slices at large offsets (issue #1108)
+#
+# This is written this way because [range(<large number>)] is
+# significantly slower under valgrind than .[<large number>] = value.
+#
+# We range down rather than up so that we have just one realloc.
+reduce range(70010;69999;-1) as $i ([]; .[$i] = $i)|.[69999:70003]
+null
+[null,70000,70001,70002]
#
# Variables