diff -r 698fd628b001 Modules/_sre.c --- a/Modules/_sre.c Wed Aug 07 05:52:20 2013 -0700 +++ b/Modules/_sre.c Thu Aug 08 10:01:59 2013 +0300 @@ -321,7 +321,7 @@ SRE_IS_LINEBREAK((int) SRE_CHARGET(state, ptr, -1))); case SRE_AT_END: - return (((void*) (ptr+state->charsize) == state->end && + return (((char*)state->end - ptr == state->charsize && SRE_IS_LINEBREAK((int) SRE_CHARGET(state, ptr, 0))) || ((void*) ptr == state->end)); @@ -1372,9 +1372,10 @@ /* */ TRACE(("|%p|%p|ASSERT %d\n", ctx->pattern, ctx->ptr, ctx->pattern[1])); + if ((ctx->ptr - (char *)state->beginning) / state->charsize < + ctx->pattern[1]) + RETURN_FAILURE; state->ptr = ctx->ptr - state->charsize * ctx->pattern[1]; - if (state->ptr < state->beginning) - RETURN_FAILURE; DO_JUMP(JUMP_ASSERT, jump_assert, ctx->pattern+2); RETURN_ON_FAILURE(ret); ctx->pattern += ctx->pattern[0]; @@ -1385,8 +1386,9 @@ /* */ TRACE(("|%p|%p|ASSERT_NOT %d\n", ctx->pattern, ctx->ptr, ctx->pattern[1])); - state->ptr = ctx->ptr - state->charsize * ctx->pattern[1]; - if (state->ptr >= state->beginning) { + if ((ctx->ptr - (char *)state->beginning) / state->charsize >= + ctx->pattern[1]) { + state->ptr = ctx->ptr - state->charsize * ctx->pattern[1]; DO_JUMP(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2); if (ret) { RETURN_ON_ERROR(ret); @@ -1477,12 +1479,20 @@ SRE_CODE* overlap = NULL; int flags = 0; + if (ptr > end) + return 0; + if (pattern[0] == SRE_OP_INFO) { /* optimization info block */ /* <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> */ flags = pattern[2]; + if (pattern[3] && (end - ptr)/state->charsize < pattern[3]) { + TRACE(("reject (got %u chars, need %u)\n", + (unsigned int)((end - ptr)/state->charsize), pattern[3])); + return 0; + } if (pattern[3] > 1) { /* adjust end point (but make sure we leave at least one character in there, so literal search will work) */ @@ -1581,16 +1591,18 @@ break; ptr += state->charsize; } - } else + } else { /* general case */ - while (ptr <= end) { + assert(ptr <= end); + while (1) { TRACE(("|%p|%p|SEARCH\n", pattern, ptr)); state->start = state->ptr = ptr; + status = SRE_MATCH(state, pattern); + if (status != 0 || ptr >= end) + break; ptr += state->charsize; - status = SRE_MATCH(state, pattern); - if (status != 0) - break; } + } return status; } @@ -2214,7 +2226,7 @@ } if (state.start == state.ptr) { - if (last == state.end) + if (last == state.end || state.ptr == state.end) break; /* skip one character */ state.start = (void*) ((char*) state.ptr + state.charsize); @@ -2412,6 +2424,8 @@ next: /* move on */ + if (state.ptr == state.end) + break; if (state.ptr == state.start) state.start = (void*) ((char*) state.ptr + state.charsize); else @@ -3769,6 +3783,9 @@ PyObject* match; int status; + if (state->start == NULL) + Py_RETURN_NONE; + state_reset(state); state->ptr = state->start; @@ -3784,10 +3801,14 @@ match = pattern_new_match((PatternObject*) self->pattern, state, status); - if (status == 0 || state->ptr == state->start) + if (status == 0) + state->start = NULL; + else if (state->ptr != state->start) + state->start = state->ptr; + else if (state->ptr != state->end) state->start = (void*) ((char*) state->ptr + state->charsize); else - state->start = state->ptr; + state->start = NULL; return match; } @@ -3800,6 +3821,9 @@ PyObject* match; int status; + if (state->start == NULL) + Py_RETURN_NONE; + state_reset(state); state->ptr = state->start; @@ -3815,10 +3839,14 @@ match = pattern_new_match((PatternObject*) self->pattern, state, status); - if (status == 0 || state->ptr == state->start) + if (status == 0) + state->start = NULL; + else if (state->ptr != state->start) + state->start = state->ptr; + else if (state->ptr != state->end) state->start = (void*) ((char*) state->ptr + state->charsize); else - state->start = state->ptr; + state->start = NULL; return match; }