cpython: d40afd489b6a (original) (raw)
Mercurial > cpython
changeset 82227:d40afd489b6a 3.2
Issue #9669: Protect re against infinite loops on zero-width matching in non-greedy repeat. Patch by Matthew Barnett. [#9669]
Serhiy Storchaka storchaka@gmail.com | |
---|---|
date | Sat, 16 Feb 2013 21:23:53 +0200 |
parents | 472a7c652cbd |
children | 8f9b628593db a6231ed7bff4 |
files | Lib/test/test_re.py Misc/NEWS Modules/_sre.c |
diffstat | 3 files changed, 19 insertions(+), 2 deletions(-)[+] [-] Lib/test/test_re.py 9 Misc/NEWS 3 Modules/_sre.c 9 |
line wrap: on
line diff
--- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -616,6 +616,15 @@ class ReTests(unittest.TestCase): self.assertEqual(re.match('(x)y', 50000'x'+'y').group(1), 'x') self.assertEqual(re.match('(x)?y', 50000'x'+'y').group(1), 'x')
- def test_unlimited_zero_width_repeat(self):
# Issue #9669[](#l1.8)
self.assertIsNone(re.match(r'(?:a?)*y', 'z'))[](#l1.9)
self.assertIsNone(re.match(r'(?:a?)+y', 'z'))[](#l1.10)
self.assertIsNone(re.match(r'(?:a?){2,}y', 'z'))[](#l1.11)
self.assertIsNone(re.match(r'(?:a?)*?y', 'z'))[](#l1.12)
self.assertIsNone(re.match(r'(?:a?)+?y', 'z'))[](#l1.13)
self.assertIsNone(re.match(r'(?:a?){2,}?y', 'z'))[](#l1.14)
+ def test_scanner(self): def s_ident(scanner, token): return token def s_operator(scanner, token): return "op%s" % token
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -224,6 +224,9 @@ Core and Builtins Library ------- +- Issue #9669: Protect re against infinite loops on zero-width matching in
- Issue #13169: The maximal repetition number in a regular expression has been increased from 65534 to 2147483647 (on 32-bit platform) or 4294967294 (on 64-bit).
--- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -1295,13 +1295,18 @@ entrance: LASTMARK_RESTORE();
if (ctx->count >= ctx->u.rep->pattern[2][](#l3.7)
&& ctx->u.rep->pattern[2] != SRE_MAXREPEAT)[](#l3.8)
if ((ctx->count >= ctx->u.rep->pattern[2][](#l3.9)
&& ctx->u.rep->pattern[2] != SRE_MAXREPEAT) ||[](#l3.10)
state->ptr == ctx->u.rep->last_ptr)[](#l3.11) RETURN_FAILURE;[](#l3.12)
ctx->u.rep->count = ctx->count;
/* zero-width match protection */[](#l3.15)
DATA_PUSH(&ctx->u.rep->last_ptr);[](#l3.16)
ctx->u.rep->last_ptr = state->ptr;[](#l3.17) DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3,[](#l3.18) ctx->u.rep->pattern+3);[](#l3.19)
DATA_POP(&ctx->u.rep->last_ptr);[](#l3.20) if (ret) {[](#l3.21) RETURN_ON_ERROR(ret);[](#l3.22) RETURN_SUCCESS;[](#l3.23)