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).
This commit is contained in:
Serhiy Storchaka 2013-02-16 16:47:15 +02:00
parent 94bf697b01
commit e18e05cce9
7 changed files with 68 additions and 15 deletions

View file

@ -524,7 +524,7 @@ SRE_COUNT(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount)
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]) {
@ -1139,7 +1139,7 @@ entrance:
} 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,
@ -1225,7 +1225,7 @@ entrance:
}
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 */
@ -1303,7 +1303,7 @@ entrance:
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;
@ -3042,7 +3042,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups)
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;
@ -3061,7 +3061,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups)
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;
@ -3938,6 +3938,12 @@ PyMODINIT_FUNC init_sre(void)
Py_DECREF(x);
}
x = PyLong_FromUnsignedLong(SRE_MAXREPEAT);
if (x) {
PyDict_SetItemString(d, "MAXREPEAT", x);
Py_DECREF(x);
}
x = PyString_FromString(copyright);
if (x) {
PyDict_SetItemString(d, "copyright", x);

View file

@ -16,9 +16,19 @@
/* size of a code word (must be unsigned short or larger, and
large enough to hold a UCS4 character) */
#ifdef Py_USING_UNICODE
#define SRE_CODE Py_UCS4
# define SRE_CODE Py_UCS4
# if SIZEOF_SIZE_T > 4
# define SRE_MAXREPEAT (~(SRE_CODE)0)
# else
# define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX + 1u)
# endif
#else
#define SRE_CODE unsigned long
# define SRE_CODE unsigned long
# if SIZEOF_SIZE_T > SIZEOF_LONG
# define SRE_MAXREPEAT (~(SRE_CODE)0)
# else
# define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX + 1u)
# endif
#endif
typedef struct {