summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTravis Gockel <travis@gockelhut.com>2015-03-04 21:09:00 -0700
committerNicolas Williams <nico@cryptonector.com>2015-05-21 19:17:16 -0500
commit110e009996e1359d25b8e99e71f83b96e5870790 (patch)
treea52a4b412c3ba4bd2e237f37a5f11fd565e74bae
parent7b6a018dff623a4f13f6bcd52c7c56d9b4a4165f (diff)
Add wrapping and clamping to jv_array_slice
Fix #716. Fix #717.
-rw-r--r--jv.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/jv.c b/jv.c
index 22e2eb62..bf3d4f83 100644
--- a/jv.c
+++ b/jv.c
@@ -276,11 +276,28 @@ static int jvp_array_equal(jv a, jv b) {
return 1;
}
+static void jvp_clamp_slice_params(int len, int *pstart, int *pend)
+{
+ if (*pstart < 0) *pstart = len + *pstart;
+ if (*pend < 0) *pend = len + *pend;
+
+ if (*pstart < 0) *pstart = 0;
+ if (*pstart > len) *pstart = len;
+ if (*pend > len) *pend = len;
+ if (*pend < *pstart) *pend = *pstart;
+}
+
static jv jvp_array_slice(jv a, int start, int end) {
assert(jv_get_kind(a) == JV_KIND_ARRAY);
+ int len = jvp_array_length(a);
+ jvp_clamp_slice_params(len, &start, &end);
+ assert(0 <= start && start <= end && end <= len);
+
// FIXME: maybe slice should reallocate if the slice is small enough
- assert(0 <= start && start <= end);
- assert(end <= jvp_array_length(a));
+ if (start == end) {
+ jv_free(a);
+ return jv_array();
+ }
// FIXME FIXME FIXME large offsets
a.offset += start;
a.size = end - start;
@@ -728,15 +745,7 @@ jv jv_string_slice(jv j, int start, int end) {
int c;
jv res;
- if (start < 0) start = len + start;
- if (end < 0) end = len + end;
-
- if (start < 0) start = 0;
- if (start > len) start = len;
- if (end > len) end = len;
- if (end < start) end = start;
- if (start < 0 || start > end || end > len)
- return jv_invalid_with_msg(jv_string("Invalid string slice indices"));
+ jvp_clamp_slice_params(len, &start, &end);
assert(0 <= start && start <= end && end <= len);
/* Look for byte offset corresponding to start codepoints */