Fixed sre bug "[#581080] Provoking infinite scanner loops".

This bug happened because: 1) the scanner_search and scanner_match methods
were not checking the buffer limits before increasing the current pointer;
and 2) SRE_SEARCH was using "if (ptr == end)" as a loop break, instead of
"if (ptr >= end)".

* Modules/_sre.c
  (SRE_SEARCH): Check for "ptr >= end" to break loops, so that we don't
  hang forever if a pointer passing the buffer limit is used.
  (scanner_search,scanner_match): Don't increment the current pointer
  if we're going to pass the buffer limit.

* Misc/NEWS
  Mention the fix.
This commit is contained in:
Gustavo Niemeyer 2002-11-07 03:28:56 +00:00
parent 65fe8dda15
commit c523b04b0f
2 changed files with 11 additions and 4 deletions

View File

@ -359,6 +359,11 @@ Extension modules
when running the expression r'(a)(b)?b' over 'ab', lastindex must be
1, not 2.
- Fixed bug #581080: sre scanner was not checking the buffer limit
before increasing the current pointer. This was creating an infinite
loop in the search function, once the pointer exceeded the buffer
limit.
Library
-------

View File

@ -1237,7 +1237,7 @@ SRE_SEARCH(SRE_STATE* state, SRE_CODE* pattern)
for (;;) {
while (ptr < end && (SRE_CODE) ptr[0] != chr)
ptr++;
if (ptr == end)
if (ptr >= end)
return 0;
TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr));
state->start = ptr;
@ -1254,7 +1254,7 @@ SRE_SEARCH(SRE_STATE* state, SRE_CODE* pattern)
for (;;) {
while (ptr < end && !SRE_CHARSET(charset, ptr[0]))
ptr++;
if (ptr == end)
if (ptr >= end)
return 0;
TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
state->start = ptr;
@ -2896,7 +2896,8 @@ scanner_match(ScannerObject* self, PyObject* args)
match = pattern_new_match((PatternObject*) self->pattern,
state, status);
if (status == 0 || state->ptr == state->start)
if ((status == 0 || state->ptr == state->start) &&
state->ptr < state->end)
state->start = (void*) ((char*) state->ptr + state->charsize);
else
state->start = state->ptr;
@ -2927,7 +2928,8 @@ scanner_search(ScannerObject* self, PyObject* args)
match = pattern_new_match((PatternObject*) self->pattern,
state, status);
if (status == 0 || state->ptr == state->start)
if ((status == 0 || state->ptr == state->start) &&
state->ptr < state->end)
state->start = (void*) ((char*) state->ptr + state->charsize);
else
state->start = state->ptr;