glob: error out on range overflow

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
This commit is contained in:
Daniel Stenberg 2013-08-16 11:52:59 +02:00
parent 5ca96cb844
commit f15a88f2b2
3 changed files with 62 additions and 6 deletions

View 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),

View 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 \

33
tests/data/test1236 Normal file
View File

@ -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>