version 1.1.1.2, 2012/02/21 23:50:25
|
version 1.1.1.3, 2012/10/09 09:19:17
|
Line 37 POSSIBILITY OF SUCH DAMAGE.
|
Line 37 POSSIBILITY OF SUCH DAMAGE.
|
----------------------------------------------------------------------------- |
----------------------------------------------------------------------------- |
*/ |
*/ |
|
|
|
|
/* This module contains pcre_exec(), the externally visible function that does |
/* This module contains pcre_exec(), the externally visible function that does |
pattern matching using an NFA algorithm, trying to mimic Perl as closely as |
pattern matching using an NFA algorithm, trying to mimic Perl as closely as |
possible. There are also some static supporting functions. */ |
possible. There are also some static supporting functions. */ |
Line 140 Arguments:
|
Line 139 Arguments:
|
md points to match data block |
md points to match data block |
caseless TRUE if caseless |
caseless TRUE if caseless |
|
|
Returns: < 0 if not matched, otherwise the number of subject bytes matched | Returns: >= 0 the number of subject bytes matched |
| -1 no match |
| -2 partial match; always given if at end subject |
*/ |
*/ |
|
|
static int |
static int |
Line 163 pchars(p, length, FALSE, md);
|
Line 164 pchars(p, length, FALSE, md);
|
printf("\n"); |
printf("\n"); |
#endif |
#endif |
|
|
/* Always fail if reference not set (and not JavaScript compatible). */ | /* Always fail if reference not set (and not JavaScript compatible - in that |
| case the length is passed as zero). */ |
|
|
if (length < 0) return -1; |
if (length < 0) return -1; |
|
|
Line 189 if (caseless)
|
Line 191 if (caseless)
|
while (p < endptr) |
while (p < endptr) |
{ |
{ |
int c, d; |
int c, d; |
if (eptr >= md->end_subject) return -1; | if (eptr >= md->end_subject) return -2; /* Partial match */ |
GETCHARINC(c, eptr); |
GETCHARINC(c, eptr); |
GETCHARINC(d, p); |
GETCHARINC(d, p); |
if (c != d && c != UCD_OTHERCASE(d)) return -1; |
if (c != d && c != UCD_OTHERCASE(d)) return -1; |
Line 202 if (caseless)
|
Line 204 if (caseless)
|
/* The same code works when not in UTF-8 mode and in UTF-8 mode when there |
/* The same code works when not in UTF-8 mode and in UTF-8 mode when there |
is no UCP support. */ |
is no UCP support. */ |
{ |
{ |
if (eptr + length > md->end_subject) return -1; |
|
while (length-- > 0) |
while (length-- > 0) |
{ |
{ |
|
if (eptr >= md->end_subject) return -2; /* Partial match */ |
if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1; |
if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1; |
p++; |
p++; |
eptr++; |
eptr++; |
Line 217 are in UTF-8 mode. */
|
Line 219 are in UTF-8 mode. */
|
|
|
else |
else |
{ |
{ |
if (eptr + length > md->end_subject) return -1; | while (length-- > 0) |
while (length-- > 0) if (*p++ != *eptr++) return -1; | { |
| if (eptr >= md->end_subject) return -2; /* Partial match */ |
| if (*p++ != *eptr++) return -1; |
| } |
} |
} |
|
|
return (int)(eptr - eptr_start); |
return (int)(eptr - eptr_start); |
Line 311 argument of match(), which never changes. */
|
Line 316 argument of match(), which never changes. */
|
|
|
#define RMATCH(ra,rb,rc,rd,re,rw)\ |
#define RMATCH(ra,rb,rc,rd,re,rw)\ |
{\ |
{\ |
heapframe *newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\ | heapframe *newframe = frame->Xnextframe;\ |
if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\ | if (newframe == NULL)\ |
frame->Xwhere = rw; \ | {\ |
| newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\ |
| if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\ |
| newframe->Xnextframe = NULL;\ |
| frame->Xnextframe = newframe;\ |
| }\ |
| frame->Xwhere = rw;\ |
newframe->Xeptr = ra;\ |
newframe->Xeptr = ra;\ |
newframe->Xecode = rb;\ |
newframe->Xecode = rb;\ |
newframe->Xmstart = mstart;\ |
newframe->Xmstart = mstart;\ |
Line 332 argument of match(), which never changes. */
|
Line 343 argument of match(), which never changes. */
|
{\ |
{\ |
heapframe *oldframe = frame;\ |
heapframe *oldframe = frame;\ |
frame = oldframe->Xprevframe;\ |
frame = oldframe->Xprevframe;\ |
if (oldframe != &frame_zero) (PUBL(stack_free))(oldframe);\ |
|
if (frame != NULL)\ |
if (frame != NULL)\ |
{\ |
{\ |
rrc = ra;\ |
rrc = ra;\ |
Line 346 argument of match(), which never changes. */
|
Line 356 argument of match(), which never changes. */
|
|
|
typedef struct heapframe { |
typedef struct heapframe { |
struct heapframe *Xprevframe; |
struct heapframe *Xprevframe; |
|
struct heapframe *Xnextframe; |
|
|
/* Function arguments that may change */ |
/* Function arguments that may change */ |
|
|
Line 492 the top-level on the stack rather than malloc-ing them
|
Line 503 the top-level on the stack rather than malloc-ing them
|
boost in many cases where there is not much "recursion". */ |
boost in many cases where there is not much "recursion". */ |
|
|
#ifdef NO_RECURSE |
#ifdef NO_RECURSE |
heapframe frame_zero; | heapframe *frame = (heapframe *)md->match_frames_base; |
heapframe *frame = &frame_zero; | |
frame->Xprevframe = NULL; /* Marks the top level */ | |
|
|
/* Copy in the original argument variables */ |
/* Copy in the original argument variables */ |
|
|
Line 897 for (;;)
|
Line 906 for (;;)
|
} |
} |
else /* OP_KETRMAX */ |
else /* OP_KETRMAX */ |
{ |
{ |
md->match_function_type = MATCH_CBEGROUP; |
|
RMATCH(eptr, prev, offset_top, md, eptrb, RM66); |
RMATCH(eptr, prev, offset_top, md, eptrb, RM66); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
ecode += 1 + LINK_SIZE; |
ecode += 1 + LINK_SIZE; |
Line 1026 for (;;)
|
Line 1034 for (;;)
|
|
|
for (;;) |
for (;;) |
{ |
{ |
if (op >= OP_SBRA || op == OP_ONCE) md->match_function_type = MATCH_CBEGROUP; | if (op >= OP_SBRA || op == OP_ONCE) |
| md->match_function_type = MATCH_CBEGROUP; |
|
|
/* If this is not a possibly empty group, and there are no (*THEN)s in |
/* If this is not a possibly empty group, and there are no (*THEN)s in |
the pattern, and this is the final alternative, optimize as described |
the pattern, and this is the final alternative, optimize as described |
Line 1565 for (;;)
|
Line 1574 for (;;)
|
mstart = md->start_match_ptr; /* In case \K reset it */ |
mstart = md->start_match_ptr; /* In case \K reset it */ |
break; |
break; |
} |
} |
|
md->mark = save_mark; |
|
|
/* PCRE does not allow THEN to escape beyond an assertion; it is treated | /* A COMMIT failure must fail the entire assertion, without trying any |
as NOMATCH. */ | subsequent branches. */ |
|
|
|
if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH); |
|
|
|
/* PCRE does not allow THEN to escape beyond an assertion; it |
|
is treated as NOMATCH. */ |
|
|
if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); |
ecode += GET(ecode, 1); |
ecode += GET(ecode, 1); |
md->mark = save_mark; |
|
} |
} |
while (*ecode == OP_ALT); |
while (*ecode == OP_ALT); |
|
|
Line 1779 for (;;)
|
Line 1793 for (;;)
|
goto RECURSION_MATCHED; /* Exit loop; end processing */ |
goto RECURSION_MATCHED; /* Exit loop; end processing */ |
} |
} |
|
|
/* PCRE does not allow THEN to escape beyond a recursion; it is treated | /* PCRE does not allow THEN or COMMIT to escape beyond a recursion; it |
as NOMATCH. */ | is treated as NOMATCH. */ |
|
|
else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) | else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN && |
| rrc != MATCH_COMMIT) |
{ |
{ |
DPRINTF(("Recursion gave error %d\n", rrc)); |
DPRINTF(("Recursion gave error %d\n", rrc)); |
if (new_recursive.offset_save != stacksave) |
if (new_recursive.offset_save != stacksave) |
Line 1993 for (;;)
|
Line 2008 for (;;)
|
} |
} |
if (*prev >= OP_SBRA) /* Could match an empty string */ |
if (*prev >= OP_SBRA) /* Could match an empty string */ |
{ |
{ |
md->match_function_type = MATCH_CBEGROUP; |
|
RMATCH(eptr, prev, offset_top, md, eptrb, RM50); |
RMATCH(eptr, prev, offset_top, md, eptrb, RM50); |
RRETURN(rrc); |
RRETURN(rrc); |
} |
} |
Line 2002 for (;;)
|
Line 2016 for (;;)
|
} |
} |
else /* OP_KETRMAX */ |
else /* OP_KETRMAX */ |
{ |
{ |
if (*prev >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; |
|
RMATCH(eptr, prev, offset_top, md, eptrb, RM13); |
RMATCH(eptr, prev, offset_top, md, eptrb, RM13); |
if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH; |
if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH; |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
Line 2059 for (;;)
|
Line 2072 for (;;)
|
|
|
case OP_DOLLM: |
case OP_DOLLM: |
if (eptr < md->end_subject) |
if (eptr < md->end_subject) |
{ if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); } | { |
| if (!IS_NEWLINE(eptr)) |
| { |
| if (md->partial != 0 && |
| eptr + 1 >= md->end_subject && |
| NLBLOCK->nltype == NLTYPE_FIXED && |
| NLBLOCK->nllen == 2 && |
| *eptr == NLBLOCK->nl[0]) |
| { |
| md->hitend = TRUE; |
| if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); |
| } |
| RRETURN(MATCH_NOMATCH); |
| } |
| } |
else |
else |
{ |
{ |
if (md->noteol) RRETURN(MATCH_NOMATCH); |
if (md->noteol) RRETURN(MATCH_NOMATCH); |
Line 2091 for (;;)
|
Line 2118 for (;;)
|
ASSERT_NL_OR_EOS: |
ASSERT_NL_OR_EOS: |
if (eptr < md->end_subject && |
if (eptr < md->end_subject && |
(!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen)) |
(!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen)) |
|
{ |
|
if (md->partial != 0 && |
|
eptr + 1 >= md->end_subject && |
|
NLBLOCK->nltype == NLTYPE_FIXED && |
|
NLBLOCK->nllen == 2 && |
|
*eptr == NLBLOCK->nl[0]) |
|
{ |
|
md->hitend = TRUE; |
|
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); |
|
} |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
|
} |
|
|
/* Either at end of string or \n before end. */ |
/* Either at end of string or \n before end. */ |
|
|
Line 2219 for (;;)
|
Line 2257 for (;;)
|
} |
} |
break; |
break; |
|
|
/* Match a single character type; inline for speed */ | /* Match any single character type except newline; have to take care with |
| CRLF newlines and partial matching. */ |
|
|
case OP_ANY: |
case OP_ANY: |
if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); |
if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); |
|
if (md->partial != 0 && |
|
eptr + 1 >= md->end_subject && |
|
NLBLOCK->nltype == NLTYPE_FIXED && |
|
NLBLOCK->nllen == 2 && |
|
*eptr == NLBLOCK->nl[0]) |
|
{ |
|
md->hitend = TRUE; |
|
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); |
|
} |
|
|
/* Fall through */ |
/* Fall through */ |
|
|
|
/* Match any single character whatsoever. */ |
|
|
case OP_ALLANY: |
case OP_ALLANY: |
if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */ |
if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */ |
{ /* not be updated before SCHECK_PARTIAL. */ |
{ /* not be updated before SCHECK_PARTIAL. */ |
Line 2365 for (;;)
|
Line 2416 for (;;)
|
default: RRETURN(MATCH_NOMATCH); |
default: RRETURN(MATCH_NOMATCH); |
|
|
case 0x000d: |
case 0x000d: |
if (eptr < md->end_subject && *eptr == 0x0a) eptr++; | if (eptr >= md->end_subject) |
| { |
| SCHECK_PARTIAL(); |
| } |
| else if (*eptr == 0x0a) eptr++; |
break; |
break; |
|
|
case 0x000a: |
case 0x000a: |
Line 2595 for (;;)
|
Line 2650 for (;;)
|
if (UCD_CATEGORY(c) != ucp_M) break; |
if (UCD_CATEGORY(c) != ucp_M) break; |
eptr += len; |
eptr += len; |
} |
} |
|
CHECK_PARTIAL(); |
ecode++; |
ecode++; |
break; |
break; |
#endif |
#endif |
Line 2660 for (;;)
|
Line 2716 for (;;)
|
default: /* No repeat follows */ |
default: /* No repeat follows */ |
if ((length = match_ref(offset, eptr, length, md, caseless)) < 0) |
if ((length = match_ref(offset, eptr, length, md, caseless)) < 0) |
{ |
{ |
|
if (length == -2) eptr = md->end_subject; /* Partial match */ |
CHECK_PARTIAL(); |
CHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
Line 2685 for (;;)
|
Line 2742 for (;;)
|
int slength; |
int slength; |
if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) |
if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) |
{ |
{ |
|
if (slength == -2) eptr = md->end_subject; /* Partial match */ |
CHECK_PARTIAL(); |
CHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
Line 2708 for (;;)
|
Line 2766 for (;;)
|
if (fi >= max) RRETURN(MATCH_NOMATCH); |
if (fi >= max) RRETURN(MATCH_NOMATCH); |
if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) |
if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) |
{ |
{ |
|
if (slength == -2) eptr = md->end_subject; /* Partial match */ |
CHECK_PARTIAL(); |
CHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
Line 2726 for (;;)
|
Line 2785 for (;;)
|
int slength; |
int slength; |
if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) |
if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0) |
{ |
{ |
CHECK_PARTIAL(); | /* Can't use CHECK_PARTIAL because we don't want to update eptr in |
| the soft partial matching case. */ |
| |
| if (slength == -2 && md->partial != 0 && |
| md->end_subject > md->start_used_ptr) |
| { |
| md->hitend = TRUE; |
| if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); |
| } |
break; |
break; |
} |
} |
eptr += slength; |
eptr += slength; |
} |
} |
|
|
while (eptr >= pp) |
while (eptr >= pp) |
{ |
{ |
RMATCH(eptr, ecode, offset_top, md, eptrb, RM15); |
RMATCH(eptr, ecode, offset_top, md, eptrb, RM15); |
Line 3360 for (;;)
|
Line 3428 for (;;)
|
maximizing, find the maximum number of characters and work backwards. */ |
maximizing, find the maximum number of characters and work backwards. */ |
|
|
DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max, |
DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max, |
max, eptr)); | max, (char *)eptr)); |
|
|
if (op >= OP_STARI) /* Caseless */ |
if (op >= OP_STARI) /* Caseless */ |
{ |
{ |
Line 3504 for (;;)
|
Line 3572 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
ecode++; | #ifdef SUPPORT_UTF |
GETCHARINCTEST(c, eptr); | if (utf) |
if (op == OP_NOTI) /* The caseless case */ | |
{ |
{ |
register unsigned int ch, och; |
register unsigned int ch, och; |
ch = *ecode++; | |
#ifdef COMPILE_PCRE8 | ecode++; |
/* ch must be < 128 if UTF is enabled. */ | GETCHARINC(ch, ecode); |
och = md->fcc[ch]; | GETCHARINC(c, eptr); |
#else | |
#ifdef SUPPORT_UTF | if (op == OP_NOT) |
| { |
| if (ch == c) RRETURN(MATCH_NOMATCH); |
| } |
| else |
| { |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
if (utf && ch > 127) | if (ch > 127) |
och = UCD_OTHERCASE(ch); | och = UCD_OTHERCASE(ch); |
#else |
#else |
if (utf && ch > 127) | if (ch > 127) |
och = ch; | och = ch; |
#endif /* SUPPORT_UCP */ |
#endif /* SUPPORT_UCP */ |
else | else |
#endif /* SUPPORT_UTF */ | och = TABLE_GET(ch, md->fcc, ch); |
och = TABLE_GET(ch, md->fcc, ch); | if (ch == c || och == c) RRETURN(MATCH_NOMATCH); |
#endif /* COMPILE_PCRE8 */ | } |
if (ch == c || och == c) RRETURN(MATCH_NOMATCH); | |
} |
} |
else /* Caseful */ | else |
| #endif |
{ |
{ |
if (*ecode++ == c) RRETURN(MATCH_NOMATCH); | register unsigned int ch = ecode[1]; |
| c = *eptr++; |
| if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c)) |
| RRETURN(MATCH_NOMATCH); |
| ecode += 2; |
} |
} |
break; |
break; |
|
|
Line 3610 for (;;)
|
Line 3686 for (;;)
|
/* Common code for all repeated single-byte matches. */ |
/* Common code for all repeated single-byte matches. */ |
|
|
REPEATNOTCHAR: |
REPEATNOTCHAR: |
fc = *ecode++; | GETCHARINCTEST(fc, ecode); |
|
|
/* The code is duplicated for the caseless and caseful cases, for speed, |
/* The code is duplicated for the caseless and caseful cases, for speed, |
since matching characters is likely to be quite common. First, ensure the |
since matching characters is likely to be quite common. First, ensure the |
Line 3621 for (;;)
|
Line 3697 for (;;)
|
characters and work backwards. */ |
characters and work backwards. */ |
|
|
DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max, |
DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max, |
max, eptr)); | max, (char *)eptr)); |
|
|
if (op >= OP_NOTSTARI) /* Caseless */ |
if (op >= OP_NOTSTARI) /* Caseless */ |
{ |
{ |
#ifdef COMPILE_PCRE8 |
|
/* fc must be < 128 if UTF is enabled. */ |
|
foc = md->fcc[fc]; |
|
#else |
|
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
if (utf && fc > 127) |
if (utf && fc > 127) |
Line 3640 for (;;)
|
Line 3712 for (;;)
|
else |
else |
#endif /* SUPPORT_UTF */ |
#endif /* SUPPORT_UTF */ |
foc = TABLE_GET(fc, md->fcc, fc); |
foc = TABLE_GET(fc, md->fcc, fc); |
#endif /* COMPILE_PCRE8 */ |
|
|
|
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
if (utf) |
if (utf) |
Line 3654 for (;;)
|
Line 3725 for (;;)
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
GETCHARINC(d, eptr); |
GETCHARINC(d, eptr); |
if (fc == d || (unsigned int) foc == d) RRETURN(MATCH_NOMATCH); | if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH); |
} |
} |
} |
} |
else |
else |
Line 4164 for (;;)
|
Line 4235 for (;;)
|
if (UCD_CATEGORY(c) != ucp_M) break; |
if (UCD_CATEGORY(c) != ucp_M) break; |
eptr += len; |
eptr += len; |
} |
} |
|
CHECK_PARTIAL(); |
} |
} |
} |
} |
|
|
Line 4184 for (;;)
|
Line 4256 for (;;)
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); |
if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); |
|
if (md->partial != 0 && |
|
eptr + 1 >= md->end_subject && |
|
NLBLOCK->nltype == NLTYPE_FIXED && |
|
NLBLOCK->nllen == 2 && |
|
*eptr == NLBLOCK->nl[0]) |
|
{ |
|
md->hitend = TRUE; |
|
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); |
|
} |
eptr++; |
eptr++; |
ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
} |
} |
Line 4468 for (;;)
|
Line 4549 for (;;)
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); |
if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); |
|
if (md->partial != 0 && |
|
eptr + 1 >= md->end_subject && |
|
NLBLOCK->nltype == NLTYPE_FIXED && |
|
NLBLOCK->nllen == 2 && |
|
*eptr == NLBLOCK->nl[0]) |
|
{ |
|
md->hitend = TRUE; |
|
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); |
|
} |
eptr++; |
eptr++; |
} |
} |
break; |
break; |
Line 4948 for (;;)
|
Line 5038 for (;;)
|
if (UCD_CATEGORY(c) != ucp_M) break; |
if (UCD_CATEGORY(c) != ucp_M) break; |
eptr += len; |
eptr += len; |
} |
} |
|
CHECK_PARTIAL(); |
} |
} |
} |
} |
else |
else |
Line 4971 for (;;)
|
Line 5062 for (;;)
|
GETCHARINC(c, eptr); |
GETCHARINC(c, eptr); |
switch(ctype) |
switch(ctype) |
{ |
{ |
case OP_ANY: /* This is the non-NL case */ | case OP_ANY: /* This is the non-NL case */ |
| if (md->partial != 0 && /* Take care with CRLF partial */ |
| eptr >= md->end_subject && |
| NLBLOCK->nltype == NLTYPE_FIXED && |
| NLBLOCK->nllen == 2 && |
| c == NLBLOCK->nl[0]) |
| { |
| md->hitend = TRUE; |
| if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); |
| } |
| break; |
| |
case OP_ALLANY: |
case OP_ALLANY: |
case OP_ANYBYTE: |
case OP_ANYBYTE: |
break; |
break; |
Line 5134 for (;;)
|
Line 5236 for (;;)
|
c = *eptr++; |
c = *eptr++; |
switch(ctype) |
switch(ctype) |
{ |
{ |
case OP_ANY: /* This is the non-NL case */ | case OP_ANY: /* This is the non-NL case */ |
| if (md->partial != 0 && /* Take care with CRLF partial */ |
| eptr >= md->end_subject && |
| NLBLOCK->nltype == NLTYPE_FIXED && |
| NLBLOCK->nllen == 2 && |
| c == NLBLOCK->nl[0]) |
| { |
| md->hitend = TRUE; |
| if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); |
| } |
| break; |
| |
case OP_ALLANY: |
case OP_ALLANY: |
case OP_ANYBYTE: |
case OP_ANYBYTE: |
break; |
break; |
Line 5491 for (;;)
|
Line 5604 for (;;)
|
if (UCD_CATEGORY(c) != ucp_M) break; |
if (UCD_CATEGORY(c) != ucp_M) break; |
eptr += len; |
eptr += len; |
} |
} |
|
CHECK_PARTIAL(); |
} |
} |
|
|
/* eptr is now past the end of the maximum run */ |
/* eptr is now past the end of the maximum run */ |
Line 5534 for (;;)
|
Line 5648 for (;;)
|
break; |
break; |
} |
} |
if (IS_NEWLINE(eptr)) break; |
if (IS_NEWLINE(eptr)) break; |
|
if (md->partial != 0 && /* Take care with CRLF partial */ |
|
eptr + 1 >= md->end_subject && |
|
NLBLOCK->nltype == NLTYPE_FIXED && |
|
NLBLOCK->nllen == 2 && |
|
*eptr == NLBLOCK->nl[0]) |
|
{ |
|
md->hitend = TRUE; |
|
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); |
|
} |
eptr++; |
eptr++; |
ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
} |
} |
Line 5551 for (;;)
|
Line 5674 for (;;)
|
break; |
break; |
} |
} |
if (IS_NEWLINE(eptr)) break; |
if (IS_NEWLINE(eptr)) break; |
|
if (md->partial != 0 && /* Take care with CRLF partial */ |
|
eptr + 1 >= md->end_subject && |
|
NLBLOCK->nltype == NLTYPE_FIXED && |
|
NLBLOCK->nllen == 2 && |
|
*eptr == NLBLOCK->nl[0]) |
|
{ |
|
md->hitend = TRUE; |
|
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); |
|
} |
eptr++; |
eptr++; |
ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
} |
} |
Line 5815 for (;;)
|
Line 5947 for (;;)
|
break; |
break; |
} |
} |
if (IS_NEWLINE(eptr)) break; |
if (IS_NEWLINE(eptr)) break; |
|
if (md->partial != 0 && /* Take care with CRLF partial */ |
|
eptr + 1 >= md->end_subject && |
|
NLBLOCK->nltype == NLTYPE_FIXED && |
|
NLBLOCK->nllen == 2 && |
|
*eptr == NLBLOCK->nl[0]) |
|
{ |
|
md->hitend = TRUE; |
|
if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); |
|
} |
eptr++; |
eptr++; |
} |
} |
break; |
break; |
Line 6145 Undefine all the macros that were defined above to han
|
Line 6286 Undefine all the macros that were defined above to han
|
***************************************************************************/ |
***************************************************************************/ |
|
|
|
|
|
#ifdef NO_RECURSE |
|
/************************************************* |
|
* Release allocated heap frames * |
|
*************************************************/ |
|
|
|
/* This function releases all the allocated frames. The base frame is on the |
|
machine stack, and so must not be freed. |
|
|
|
Argument: the address of the base frame |
|
Returns: nothing |
|
*/ |
|
|
|
static void |
|
release_match_heapframes (heapframe *frame_base) |
|
{ |
|
heapframe *nextframe = frame_base->Xnextframe; |
|
while (nextframe != NULL) |
|
{ |
|
heapframe *oldframe = nextframe; |
|
nextframe = nextframe->Xnextframe; |
|
(PUBL(stack_free))(oldframe); |
|
} |
|
} |
|
#endif |
|
|
|
|
/************************************************* |
/************************************************* |
* Execute a Regular Expression * |
* Execute a Regular Expression * |
*************************************************/ |
*************************************************/ |
Line 6207 PCRE_PUCHAR req_char_ptr = start_match - 1;
|
Line 6373 PCRE_PUCHAR req_char_ptr = start_match - 1;
|
const pcre_study_data *study; |
const pcre_study_data *study; |
const REAL_PCRE *re = (const REAL_PCRE *)argument_re; |
const REAL_PCRE *re = (const REAL_PCRE *)argument_re; |
|
|
|
#ifdef NO_RECURSE |
|
heapframe frame_zero; |
|
frame_zero.Xprevframe = NULL; /* Marks the top level */ |
|
frame_zero.Xnextframe = NULL; /* None are allocated yet */ |
|
md->match_frames_base = &frame_zero; |
|
#endif |
|
|
/* Check for the special magic call that measures the size of the stack used |
/* Check for the special magic call that measures the size of the stack used |
per recursive call of match(). */ | per recursive call of match(). Without the funny casting for sizeof, a Windows |
| compiler gave this error: "unary minus operator applied to unsigned type, |
| result still unsigned". Hopefully the cast fixes that. */ |
|
|
if (re == NULL && extra_data == NULL && subject == NULL && length == -999 && |
if (re == NULL && extra_data == NULL && subject == NULL && length == -999 && |
start_offset == -999) |
start_offset == -999) |
#ifdef NO_RECURSE |
#ifdef NO_RECURSE |
return -sizeof(heapframe); | return -((int)sizeof(heapframe)); |
#else |
#else |
return match(NULL, NULL, NULL, 0, NULL, NULL, 0); |
return match(NULL, NULL, NULL, 0, NULL, NULL, 0); |
#endif |
#endif |
Line 6280 if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
|
Line 6455 if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
|
/* If the pattern was successfully studied with JIT support, run the JIT |
/* If the pattern was successfully studied with JIT support, run the JIT |
executable instead of the rest of this function. Most options must be set at |
executable instead of the rest of this function. Most options must be set at |
compile time for the JIT code to be usable. Fallback to the normal code path if |
compile time for the JIT code to be usable. Fallback to the normal code path if |
an unsupported flag is set. In particular, JIT does not support partial | an unsupported flag is set. */ |
matching. */ | |
|
|
#ifdef SUPPORT_JIT |
#ifdef SUPPORT_JIT |
if (extra_data != NULL |
if (extra_data != NULL |
&& (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 | && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT | |
| PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT |
&& extra_data->executable_jit != NULL |
&& extra_data->executable_jit != NULL |
&& (extra_data->flags & PCRE_EXTRA_TABLES) == 0 |
|
&& (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL | |
&& (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL | |
PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0) | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | |
return PRIV(jit_exec)(re, extra_data->executable_jit, | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0) |
(const pcre_uchar *)subject, length, start_offset, options, | { |
((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) | rc = PRIV(jit_exec)(re, extra_data, (const pcre_uchar *)subject, length, |
? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount); | start_offset, options, offsets, offsetcount); |
| |
| /* PCRE_ERROR_NULL means that the selected normal or partial matching |
| mode is not compiled. In this case we simply fallback to interpreter. */ |
| |
| if (rc != PCRE_ERROR_NULL) return rc; |
| } |
#endif |
#endif |
|
|
/* Carry on with non-JIT matching. This information is for finding all the |
/* Carry on with non-JIT matching. This information is for finding all the |
Line 6887 if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
|
Line 7067 if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
|
{ |
{ |
register int *iptr, *iend; |
register int *iptr, *iend; |
int resetcount = 2 + re->top_bracket * 2; |
int resetcount = 2 + re->top_bracket * 2; |
if (resetcount > offsetcount) resetcount = ocount; | if (resetcount > offsetcount) resetcount = offsetcount; |
iptr = offsets + md->end_offset_top; |
iptr = offsets + md->end_offset_top; |
iend = offsets + resetcount; |
iend = offsets + resetcount; |
while (iptr < iend) *iptr++ = -1; |
while (iptr < iend) *iptr++ = -1; |
Line 6908 if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
|
Line 7088 if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
|
if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0) |
if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0) |
*(extra_data->mark) = (pcre_uchar *)md->mark; |
*(extra_data->mark) = (pcre_uchar *)md->mark; |
DPRINTF((">>>> returning %d\n", rc)); |
DPRINTF((">>>> returning %d\n", rc)); |
|
#ifdef NO_RECURSE |
|
release_match_heapframes(&frame_zero); |
|
#endif |
return rc; |
return rc; |
} |
} |
|
|
Line 6925 if (using_temporary_offsets)
|
Line 7108 if (using_temporary_offsets)
|
if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL) |
if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL) |
{ |
{ |
DPRINTF((">>>> error: returning %d\n", rc)); |
DPRINTF((">>>> error: returning %d\n", rc)); |
|
#ifdef NO_RECURSE |
|
release_match_heapframes(&frame_zero); |
|
#endif |
return rc; |
return rc; |
} |
} |
|
|
Line 6954 else
|
Line 7140 else
|
|
|
if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0) |
if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0) |
*(extra_data->mark) = (pcre_uchar *)md->nomatch_mark; |
*(extra_data->mark) = (pcre_uchar *)md->nomatch_mark; |
|
#ifdef NO_RECURSE |
|
release_match_heapframes(&frame_zero); |
|
#endif |
return rc; |
return rc; |
} |
} |
|
|