-from test.support import verbose, run_unittest, gc_collect, bigmemtest, _2G
+from test.support import verbose, run_unittest, gc_collect, bigmemtest, _2G, \
+ cpython_only
import io
import re
from re import Scanner
self.assertEqual(n, size + 1)
+ def test_repeat_minmax_overflow(self):
+ # Issue #13169
+ string = "x" * 100000
+ self.assertEqual(re.match(r".{65535}", string).span(), (0, 65535))
+ self.assertEqual(re.match(r".{,65535}", string).span(), (0, 65535))
+ self.assertEqual(re.match(r".{65535,}?", string).span(), (0, 65535))
+ self.assertEqual(re.match(r".{65536}", string).span(), (0, 65536))
+ self.assertEqual(re.match(r".{,65536}", string).span(), (0, 65536))
+ self.assertEqual(re.match(r".{65536,}?", string).span(), (0, 65536))
+ # 2**128 should be big enough to overflow both SRE_CODE and Py_ssize_t.
+ self.assertRaises(OverflowError, re.compile, r".{%d}" % 2**128)
+ self.assertRaises(OverflowError, re.compile, r".{,%d}" % 2**128)
+ self.assertRaises(OverflowError, re.compile, r".{%d,}?" % 2**128)
+ self.assertRaises(OverflowError, re.compile, r".{%d,%d}" % (2**129, 2**128))
+
+ @cpython_only
+ def test_repeat_minmax_overflow_maxrepeat(self):
+ try:
+ from _sre import MAXREPEAT
+ except ImportError:
+ self.skipTest('requires _sre.MAXREPEAT constant')
+ string = "x" * 100000
+ self.assertIsNone(re.match(r".{%d}" % (MAXREPEAT - 1), string))
+ self.assertEqual(re.match(r".{,%d}" % (MAXREPEAT - 1), string).span(),
+ (0, 100000))
+ self.assertIsNone(re.match(r".{%d,}?" % (MAXREPEAT - 1), string))
+ self.assertRaises(OverflowError, re.compile, r".{%d}" % MAXREPEAT)
+ self.assertRaises(OverflowError, re.compile, r".{,%d}" % MAXREPEAT)
+ self.assertRaises(OverflowError, re.compile, r".{%d,}?" % MAXREPEAT)
+
+
def run_re_tests():
from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR
if verbose:
Py_ssize_t i;
/* adjust end */
- if (maxcount < end - ptr && maxcount != 65535)
+ if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
end = ptr + maxcount;
switch (pattern[0]) {
} else {
/* general case */
LASTMARK_SAVE();
- while ((Py_ssize_t)ctx->pattern[2] == 65535
+ while ((Py_ssize_t)ctx->pattern[2] == SRE_MAXREPEAT
|| ctx->count <= (Py_ssize_t)ctx->pattern[2]) {
state->ptr = ctx->ptr;
DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,
}
if ((ctx->count < ctx->u.rep->pattern[2] ||
- ctx->u.rep->pattern[2] == 65535) &&
+ ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
state->ptr != ctx->u.rep->last_ptr) {
/* we may have enough matches, but if we can
match another item, do so */
LASTMARK_RESTORE();
if (ctx->count >= ctx->u.rep->pattern[2]
- && ctx->u.rep->pattern[2] != 65535)
+ && ctx->u.rep->pattern[2] != SRE_MAXREPEAT)
RETURN_FAILURE;
ctx->u.rep->count = ctx->count;
GET_ARG; max = arg;
if (min > max)
FAIL;
- if (max > 65535)
+ if (max > SRE_MAXREPEAT)
FAIL;
if (!_validate_inner(code, code+skip-4, groups))
FAIL;
GET_ARG; max = arg;
if (min > max)
FAIL;
- if (max > 65535)
+ if (max > SRE_MAXREPEAT)
FAIL;
if (!_validate_inner(code, code+skip-3, groups))
FAIL;
Py_DECREF(x);
}
+ x = PyLong_FromUnsignedLong(SRE_MAXREPEAT);
+ if (x) {
+ PyDict_SetItemString(d, "MAXREPEAT", x);
+ Py_DECREF(x);
+ }
+
x = PyUnicode_FromString(copyright);
if (x) {
PyDict_SetItemString(d, "copyright", x);