summaryrefslogtreecommitdiffstats
path: root/Modules/_sre.c
diff options
context:
space:
mode:
authorGustavo Niemeyer <gustavo@niemeyer.net>2002-11-06 14:06:53 (GMT)
committerGustavo Niemeyer <gustavo@niemeyer.net>2002-11-06 14:06:53 (GMT)
commit4e7be06a652680611a81d6bb1fb03ce4227ac02e (patch)
tree0abf84675d23c70b00736be2692b59a6fd5c0222 /Modules/_sre.c
parent3c2c43341792b886740adec80ff875b1461a0ef2 (diff)
downloadcpython-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/_sre.c')
-rw-r--r--Modules/_sre.c37
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;
}