Commit c523b04b authored by Gustavo Niemeyer's avatar Gustavo Niemeyer

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.
parent 65fe8dda
......@@ -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
-------
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment