diff options
| author | Daniel Stenberg <daniel@haxx.se> | 2013-08-16 11:52:59 +0200 | 
|---|---|---|
| committer | Daniel Stenberg <daniel@haxx.se> | 2013-08-16 11:55:04 +0200 | 
| commit | f15a88f2b25ee44d8c8d3bdcf2508fdf50f8b868 (patch) | |
| tree | b42a5187543301a88712f464eec1f440b36d4a42 /src | |
| parent | 5ca96cb84410270e233c92bf1b2583cba40c3fad (diff) | |
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
Diffstat (limited to 'src')
| -rw-r--r-- | src/tool_urlglob.c | 34 | 
1 files changed, 28 insertions, 6 deletions
| diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c index 0e454c19c..ac13d683d 100644 --- a/src/tool_urlglob.c +++ b/src/tool_urlglob.c @@ -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), | 
