diff options
author | Gustavo Niemeyer <gustavo@niemeyer.net> | 2002-11-06 14:06:53 (GMT) |
---|---|---|
committer | Gustavo Niemeyer <gustavo@niemeyer.net> | 2002-11-06 14:06:53 (GMT) |
commit | 4e7be06a652680611a81d6bb1fb03ce4227ac02e (patch) | |
tree | 0abf84675d23c70b00736be2692b59a6fd5c0222 /Modules | |
parent | 3c2c43341792b886740adec80ff875b1461a0ef2 (diff) | |
download | cpython-4e7be06a652680611a81d6bb1fb03ce4227ac02e.zip cpython-4e7be06a652680611a81d6bb1fb03ce4227ac02e.tar.gz cpython-4e7be06a652680611a81d6bb1fb03ce4227ac02e.tar.bz2 |
Fixed bug #470582, using a modified version of patch #527371,
from Greg Chapman.
* Modules/_sre.c
(lastmark_restore): New function, implementing algorithm to restore
a state to a given lastmark. In addition to the similar algorithm used
in a few places of SRE_MATCH, restore lastindex when restoring lastmark.
(SRE_MATCH): Replace lastmark inline restoring by lastmark_restore(),
function. Also include it where missing. In SRE_OP_MARK, set lastindex
only if i > lastmark.
* Lib/test/re_tests.py
* Lib/test/test_sre.py
Included regression tests for the fixed bugs.
* Misc/NEWS
Mention fixes.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_sre.c | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/Modules/_sre.c b/Modules/_sre.c index f4dbef0..4440a6e 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -353,6 +353,18 @@ mark_restore(SRE_STATE* state, int lo, int hi) return 0; } +void lastmark_restore(SRE_STATE *state, int lastmark) +{ + if (state->lastmark > lastmark) { + memset( + state->mark + lastmark + 1, 0, + (state->lastmark - lastmark) * sizeof(void*) + ); + state->lastmark = lastmark; + state->lastindex = (lastmark == 0) ? -1 : (lastmark-1)/2+1; + } +} + /* generate 8-bit version */ #define SRE_CHAR unsigned char @@ -860,10 +872,11 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level) /* <MARK> <gid> */ TRACE(("|%p|%p|MARK %d\n", pattern, ptr, pattern[0])); i = pattern[0]; - if (i & 1) - state->lastindex = i/2 + 1; - if (i > state->lastmark) + if (i > state->lastmark) { state->lastmark = i; + if (i & 1) + state->lastindex = i/2 + 1; + } state->mark[i] = ptr; pattern++; break; @@ -920,13 +933,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level) i = SRE_MATCH(state, pattern + 1, level + 1); if (i) return i; - if (state->lastmark > lastmark) { - memset( - state->mark + lastmark + 1, 0, - (state->lastmark - lastmark) * sizeof(void*) - ); - state->lastmark = lastmark; - } + lastmark_restore(state, lastmark); } return 0; @@ -997,13 +1004,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level) return i; ptr--; count--; - if (state->lastmark > lastmark) { - memset( - state->mark + lastmark + 1, 0, - (state->lastmark - lastmark) * sizeof(void*) - ); - state->lastmark = lastmark; - } + lastmark_restore(state, lastmark); } } return 0; @@ -1071,9 +1072,9 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level) if (i) return i; i = mark_restore(state, 0, lastmark); - state->lastmark = lastmark; if (i < 0) return i; + lastmark_restore(state, lastmark); rp->count = count - 1; state->ptr = ptr; } |