]> granicus.if.org Git - curl/commitdiff
glob: error out on range overflow
authorDaniel Stenberg <daniel@haxx.se>
Fri, 16 Aug 2013 09:52:59 +0000 (11:52 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 16 Aug 2013 09:55:04 +0000 (11:55 +0200)
The new multiply() function detects range value overflows. 32bit
machines will overflow on a 32bit boundary while 64bit hosts support
ranges up to the full 64 bit range.

Added test 1236 to verify.

Bug: http://curl.haxx.se/bug/view.cgi?id=1267
Reported-by: Will Dietz
src/tool_urlglob.c
tests/data/Makefile.am
tests/data/test1236 [new file with mode: 0644]

index 0e454c19c78030a7c99f2d0f65650cb51cbc6fdd..ac13d683d7d1bf98a9a9941063a50ddf6b6ae308 100644 (file)
@@ -62,6 +62,19 @@ static GlobCode glob_fixed(URLGlob *glob, unsigned long *amount)
   return GLOB_OK;
 }
 
+/* multiply
+ *
+ * Multiplies and checks for overflow.
+ */
+static int multiply(unsigned long *amount, long with)
+{
+  unsigned long sum = *amount * with;
+  if(sum/with != *amount)
+    return 1; /* didn't fit, bail out */
+  *amount = sum;
+  return 0;
+}
+
 static GlobCode glob_set(URLGlob *glob, char **patternp,
                          size_t pos, unsigned long *amount,
                          int globindex)
@@ -102,8 +115,11 @@ static GlobCode glob_set(URLGlob *glob, char **patternp,
                  "no string within braces at pos %zu\n", pos);
         return GLOB_ERROR;
       }
-      /* add 1 since it'll be incremented below */
-      (*amount) *= (pat->content.Set.size+1);
+      /* add 1 to size since it'll be incremented below */
+      if(multiply(amount, pat->content.Set.size+1)) {
+        strcpy(glob->errormsg, "range overflow!\n");
+        return GLOB_ERROR;
+      }
       /* fall-through */
     case ',':
 
@@ -224,8 +240,11 @@ static GlobCode glob_range(URLGlob *glob, char **patternp,
     pat->content.CharRange.ptr_c = pat->content.CharRange.min_c = min_c;
     pat->content.CharRange.max_c = max_c;
 
-    *amount *= (pat->content.CharRange.max_c -
-                pat->content.CharRange.min_c + 1);
+    if(multiply(amount, (pat->content.CharRange.max_c -
+                         pat->content.CharRange.min_c + 1))) {
+      strcpy(glob->errormsg, "range overflow!\n");
+      return GLOB_ERROR;
+    }
   }
   else if(ISDIGIT(*pattern)) {
     /* numeric range detected */
@@ -288,8 +307,11 @@ static GlobCode glob_range(URLGlob *glob, char **patternp,
     pat->content.NumRange.max_n = max_n;
     pat->content.NumRange.step = step_n;
 
-    *amount *= (pat->content.NumRange.max_n -
-                pat->content.NumRange.min_n + 1);
+    if(multiply(amount, (pat->content.NumRange.max_n -
+                         pat->content.NumRange.min_n + 1))) {
+      strcpy(glob->errormsg, "range overflow!\n");
+      return GLOB_ERROR;
+    }
   }
   else {
     snprintf(glob->errormsg, sizeof(glob->errormsg),
index f661b710384853b4f886ab3e5d8e7a84d3f79071..dd7f6f95d8831cd7c992199cc4009f2d7ac05aee 100644 (file)
@@ -94,6 +94,7 @@ test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
 test1216 test1217 test1218 test1219 \
 test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 \
 test1228 test1229 test1230 test1231 test1232 test1233 test1234 test1235 \
+test1236 \
 \
 test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 \
 test1308 test1309 test1310 test1311 test1312 test1313 test1314 test1315 \
diff --git a/tests/data/test1236 b/tests/data/test1236
new file mode 100644 (file)
index 0000000..0829be3
--- /dev/null
@@ -0,0 +1,33 @@
+<testcase>
+<info>
+<keywords>
+globbing
+FAILURE
+</keywords>
+</info>
+# Server-side
+<reply>
+</reply>
+
+# Client-side
+<client>
+<server>
+none
+</server>
+ <name>
+[] globbing overflowing the range counter
+ </name>
+# 2^62 == 4611686018427387904
+ <command>
+"%HOSTIP:%HTTPPORT/1234[0-1]{" "%HOSTIP:%HTTPPORT/[1-4611686018427387904][1-4611686018427387904]"
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+# 3 == CURLE_URL_MALFORMAT
+<errorcode>
+3
+</errorcode>
+</verify>
+</testcase>