From c523b04b0f5cf76b503cfbed17fec95f61c1bd2e Mon Sep 17 00:00:00 2001 From: Gustavo Niemeyer Date: Thu, 7 Nov 2002 03:28:56 +0000 Subject: [PATCH] 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. --- Misc/NEWS | 5 +++++ Modules/_sre.c | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 5d97dd75616..8b1d085a3d5 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -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 ------- diff --git a/Modules/_sre.c b/Modules/_sre.c index 4440a6e187f..0357764c056 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -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;