]> granicus.if.org Git - jq/commitdiff
convert range bounds to integers in a way that avoids undefined behaviour 239/head
authorDavid R. MacIver <david@drmaciver.com>
Tue, 10 Dec 2013 09:18:16 +0000 (09:18 +0000)
committerDavid R. MacIver <david@drmaciver.com>
Tue, 10 Dec 2013 09:20:13 +0000 (09:20 +0000)
jv_aux.c
tests/all.test

index e994053d86d99b874141913d0e42d8db3eb34513..ec2aaa18ca00242a619aa0ed6326ab8387fd1113 100644 (file)
--- a/jv_aux.c
+++ b/jv_aux.c
@@ -26,13 +26,18 @@ static int parse_slice(jv j, jv slice, int* pstart, int* pend) {
     jv_free(end_jv);
     return 0;
   } else {
-    int start = (int)jv_number_value(start_jv);
-    int end = (int)jv_number_value(end_jv);
-    if (start < 0) start = len + start;
-    if (end < 0) end = len + end;
+    double dstart = jv_number_value(start_jv);
+    double dend = jv_number_value(end_jv);
+    if (dstart < 0) dstart += len;
+    if (dend < 0) dend += len;
+    if (dstart < 0) dstart = 0;
+    if (dstart > len) dstart = len;
+
+    int start = (int)dstart;
+    int end = (dend > len) ? len : (int)dend;
+    // Ends are exclusive but e.g. 1 < 1.5 so :1.5 should be :2 not :1
+    if(end < dend) end += 1;
 
-    if (start < 0) start = 0;
-    if (start > len) start = len;
     if (end > len) end = len;
     if (end < start) end = start;
     assert(0 <= start && start <= end && end <= len);
index 15e075d4becd1bb0044a9d7d53df3bc0a0f9811f..3615bee9fd0b42d0aa49ffb71264cc4df79ae443 100644 (file)
@@ -722,3 +722,7 @@ keys
 [][.]
 1000000000000000000
 null
+
+map([1,2][0:.])
+[-1, 1, 2, 3, 1000000000000000000]
+[[1], [1], [1,2], [1,2], [1,2]]