~ubuntu-branches/ubuntu/lucid/curl/lucid-security

« back to all changes in this revision

Viewing changes to src/urlglob.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2005-12-12 15:04:52 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20051212150452-2ymlra67b2p7kjyy
Tags: 7.15.1-1ubuntu1
Resynchronise with Debian to get URL parser overflow fix from 7.15.1
(CVE-2005-4077).

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
19
 * KIND, either express or implied.
20
20
 *
21
 
 * $Id: urlglob.c,v 1.40 2005/03/31 07:02:03 bagder Exp $
 
21
 * $Id: urlglob.c,v 1.41 2005/11/10 22:11:02 bagder Exp $
22
22
 ***************************************************************************/
23
23
 
24
24
/* client-local setup.h */
166
166
  URLPattern *pat;
167
167
  char *c;
168
168
  int wordamount=1;
 
169
  char sep;
 
170
  char sep2;
 
171
  int step;
 
172
  int rc;
169
173
 
170
174
  pat = (URLPattern*)&glob->pattern[glob->size / 2];
171
175
  /* patterns 0,1,2,... correspond to size=1,3,5,... */
172
176
  ++glob->size;
173
177
 
174
178
  if (isalpha((int)*pattern)) {         /* character range detected */
 
179
    char min_c;
 
180
    char max_c;
 
181
 
175
182
    pat->type = UPTCharRange;
176
 
    if (sscanf(pattern, "%c-%c]", &pat->content.CharRange.min_c,
177
 
               &pat->content.CharRange.max_c) != 2 ||
178
 
        pat->content.CharRange.min_c >= pat->content.CharRange.max_c ||
179
 
        pat->content.CharRange.max_c - pat->content.CharRange.min_c > 'z' - 'a') {
 
183
    rc = sscanf(pattern, "%c-%c%c%d%c", &min_c, &max_c, &sep, &step, &sep2);
 
184
    if ((rc < 3) || (min_c >= max_c) || ((max_c - min_c) > ('z' - 'a'))) {
180
185
      /* the pattern is not well-formed */
181
186
      snprintf(glob->errormsg, sizeof(glob->errormsg),
182
 
               "illegal pattern or range specification after pos %d\n", pos);
183
 
      return GLOB_ERROR;
184
 
    }
185
 
    pat->content.CharRange.ptr_c = pat->content.CharRange.min_c;
186
 
    /* always check for a literal (may be "") between patterns */
187
 
 
188
 
    if(GLOB_ERROR == glob_word(glob, pattern + 4, pos + 4, &wordamount))
189
 
      wordamount=1;
190
 
 
191
 
    *amount = (pat->content.CharRange.max_c -
192
 
               pat->content.CharRange.min_c + 1) *
193
 
      wordamount;
194
 
 
195
 
    return GLOB_OK;
 
187
               "errpr: bad range specification after pos %d\n", pos);
 
188
      return GLOB_ERROR;
 
189
    }
 
190
 
 
191
    /* check the (first) separating character */
 
192
    if((sep != ']') && (sep != ':')) {
 
193
      snprintf(glob->errormsg, sizeof(glob->errormsg),
 
194
               "error: unsupported character (%c) after range at pos %d\n",
 
195
               sep, pos);
 
196
      return GLOB_ERROR;
 
197
    }
 
198
 
 
199
    /* if there was a ":[num]" thing, use that as step or else use 1 */
 
200
    pat->content.CharRange.step =
 
201
      ((sep == ':') && (rc == 5) && (sep2 == ']'))?step:1;
 
202
 
 
203
    pat->content.CharRange.ptr_c = pat->content.CharRange.min_c = min_c;
 
204
    pat->content.CharRange.max_c = max_c;
196
205
  }
197
 
 
198
 
  if (isdigit((int)*pattern)) { /* numeric range detected */
 
206
  else if (isdigit((int)*pattern)) { /* numeric range detected */
 
207
    int min_n;
 
208
    int max_n;
199
209
 
200
210
    pat->type = UPTNumRange;
201
211
    pat->content.NumRange.padlength = 0;
202
 
    if (sscanf(pattern, "%d-%d]",
203
 
               &pat->content.NumRange.min_n,
204
 
               &pat->content.NumRange.max_n) != 2 ||
205
 
        pat->content.NumRange.min_n >= pat->content.NumRange.max_n) {
 
212
 
 
213
    rc = sscanf(pattern, "%d-%d%c%d%c", &min_n, &max_n, &sep, &step, &sep2);
 
214
 
 
215
    if ((rc < 2) || (min_n >= max_n)) {
206
216
      /* the pattern is not well-formed */
207
217
      snprintf(glob->errormsg, sizeof(glob->errormsg),
208
 
               "error: illegal pattern or range specification after pos %d\n",
209
 
               pos);
 
218
               "error: bad range specification after pos %d\n", pos);
210
219
      return GLOB_ERROR;
211
220
    }
 
221
    pat->content.NumRange.ptr_n =  pat->content.NumRange.min_n = min_n;
 
222
    pat->content.NumRange.max_n = max_n;
 
223
 
 
224
    /* if there was a ":[num]" thing, use that as step or else use 1 */
 
225
    pat->content.NumRange.step =
 
226
      ((sep == ':') && (rc == 5) && (sep2 == ']'))?step:1;
 
227
 
212
228
    if (*pattern == '0') {              /* leading zero specified */
213
229
      c = pattern;
214
230
      while (isdigit((int)*c++))
215
231
        ++pat->content.NumRange.padlength; /* padding length is set for all
216
232
                                              instances of this pattern */
217
233
    }
218
 
    pat->content.NumRange.ptr_n = pat->content.NumRange.min_n;
219
 
    c = (char*)strchr(pattern, ']'); /* continue after next ']' */
220
 
    if(c)
221
 
      c++;
222
 
    else {
223
 
      snprintf(glob->errormsg, sizeof(glob->errormsg), "missing ']'");
224
 
      return GLOB_ERROR; /* missing ']' */
225
 
    }
226
 
 
227
 
    /* always check for a literal (may be "") between patterns */
228
 
 
229
 
    if(GLOB_ERROR == glob_word(glob, c, pos + (c - pattern), &wordamount))
230
 
      wordamount = 1;
231
 
 
 
234
 
 
235
  }
 
236
  else {
 
237
    snprintf(glob->errormsg, sizeof(glob->errormsg),
 
238
             "illegal character in range specification at pos %d\n", pos);
 
239
    return GLOB_ERROR;
 
240
  }
 
241
 
 
242
  c = (char*)strchr(pattern, ']'); /* continue after next ']' */
 
243
  if(c)
 
244
    c++;
 
245
  else {
 
246
    snprintf(glob->errormsg, sizeof(glob->errormsg), "missing ']'");
 
247
    return GLOB_ERROR; /* missing ']' */
 
248
  }
 
249
 
 
250
  /* always check for a literal (may be "") between patterns */
 
251
 
 
252
  if(GLOB_ERROR == glob_word(glob, c, pos + (c - pattern), &wordamount))
 
253
    wordamount = 1;
 
254
 
 
255
  if(pat->type == UPTCharRange)
 
256
    *amount = (pat->content.CharRange.max_c -
 
257
               pat->content.CharRange.min_c + 1) *
 
258
      wordamount;
 
259
  else
232
260
    *amount = (pat->content.NumRange.max_n -
233
 
               pat->content.NumRange.min_n + 1) *
234
 
      wordamount;
 
261
               pat->content.NumRange.min_n + 1) * wordamount;
235
262
 
236
 
    return GLOB_OK;
237
 
  }
238
 
  snprintf(glob->errormsg, sizeof(glob->errormsg),
239
 
           "illegal character in range specification at pos %d\n", pos);
240
 
  return GLOB_ERROR;
 
263
  return GLOB_OK;
241
264
}
242
265
 
243
266
static GlobCode glob_word(URLGlob *glob, char *pattern,
374
397
  char *lit;
375
398
  size_t i;
376
399
  size_t j;
377
 
  int carry;
378
400
 
379
401
  if (!glob->beenhere)
380
402
    glob->beenhere = 1;
381
403
  else {
382
 
    carry = 1;
 
404
    bool carry = TRUE;
383
405
 
384
406
    /* implement a counter over the index ranges of all patterns,
385
407
       starting with the rightmost pattern */
386
408
    for (i = glob->size / 2 - 1; carry && i < glob->size; --i) {
387
 
      carry = 0;
 
409
      carry = FALSE;
388
410
      pat = &glob->pattern[i];
389
411
      switch (pat->type) {
390
412
      case UPTSet:
391
413
        if (++pat->content.Set.ptr_s == pat->content.Set.size) {
392
414
          pat->content.Set.ptr_s = 0;
393
 
          carry = 1;
 
415
          carry = TRUE;
394
416
        }
395
417
        break;
396
418
      case UPTCharRange:
397
 
        if (++pat->content.CharRange.ptr_c > pat->content.CharRange.max_c) {
 
419
        pat->content.CharRange.ptr_c += pat->content.CharRange.step;
 
420
        if (pat->content.CharRange.ptr_c > pat->content.CharRange.max_c) {
398
421
          pat->content.CharRange.ptr_c = pat->content.CharRange.min_c;
399
 
          carry = 1;
 
422
          carry = TRUE;
400
423
        }
401
424
        break;
402
425
      case UPTNumRange:
403
 
        if (++pat->content.NumRange.ptr_n > pat->content.NumRange.max_n) {
 
426
        pat->content.NumRange.ptr_n += pat->content.NumRange.step;
 
427
        if (pat->content.NumRange.ptr_n > pat->content.NumRange.max_n) {
404
428
          pat->content.NumRange.ptr_n = pat->content.NumRange.min_n;
405
 
          carry = 1;
 
429
          carry = TRUE;
406
430
        }
407
431
        break;
408
432
      default: