version 1.1.1.1, 2012/02/21 23:05:51
|
version 1.1.1.3, 2012/10/09 09:19:17
|
Line 6
|
Line 6
|
and semantics are as close as possible to those of the Perl 5 language. |
and semantics are as close as possible to those of the Perl 5 language. |
|
|
Written by Philip Hazel |
Written by Philip Hazel |
Copyright (c) 1997-2011 University of Cambridge | Copyright (c) 1997-2012 University of Cambridge |
|
|
----------------------------------------------------------------------------- |
----------------------------------------------------------------------------- |
Redistribution and use in source and binary forms, with or without |
Redistribution and use in source and binary forms, with or without |
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 113 Returns: nothing
|
Line 112 Returns: nothing
|
*/ |
*/ |
|
|
static void |
static void |
pchars(const uschar *p, int length, BOOL is_subject, match_data *md) | pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md) |
{ |
{ |
unsigned int c; |
unsigned int c; |
if (is_subject && length > md->end_subject - p) length = md->end_subject - p; |
if (is_subject && length > md->end_subject - p) length = md->end_subject - p; |
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 |
match_ref(int offset, register USPTR eptr, int length, match_data *md, | match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md, |
BOOL caseless) |
BOOL caseless) |
{ |
{ |
USPTR eptr_start = eptr; | PCRE_PUCHAR eptr_start = eptr; |
register USPTR p = md->start_subject + md->offset_vector[offset]; | register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset]; |
|
|
#ifdef PCRE_DEBUG |
#ifdef PCRE_DEBUG |
if (eptr >= md->end_subject) |
if (eptr >= md->end_subject) |
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 173 ASCII characters. */
|
Line 175 ASCII characters. */
|
|
|
if (caseless) |
if (caseless) |
{ |
{ |
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
if (md->utf8) | if (md->utf) |
{ |
{ |
/* Match characters up to the end of the reference. NOTE: the number of |
/* Match characters up to the end of the reference. NOTE: the number of |
bytes matched may differ, because there are some characters whose upper and |
bytes matched may differ, because there are some characters whose upper and |
Line 185 if (caseless)
|
Line 187 if (caseless)
|
the latter. It is important, therefore, to check the length along the |
the latter. It is important, therefore, to check the length along the |
reference, not along the subject (earlier code did this wrong). */ |
reference, not along the subject (earlier code did this wrong). */ |
|
|
USPTR endptr = p + length; | PCRE_PUCHAR endptr = p + length; |
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 (md->lcc[*p++] != md->lcc[*eptr++]) return -1; } | { |
| if (eptr >= md->end_subject) return -2; /* Partial match */ |
| if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1; |
| p++; |
| eptr++; |
| } |
} |
} |
} |
} |
|
|
Line 213 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 307 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 *)(pcre_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 328 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;\ |
(pcre_stack_free)(oldframe);\ |
|
if (frame != NULL)\ |
if (frame != NULL)\ |
{\ |
{\ |
rrc = ra;\ |
rrc = ra;\ |
Line 342 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 */ |
|
|
USPTR Xeptr; | PCRE_PUCHAR Xeptr; |
const uschar *Xecode; | const pcre_uchar *Xecode; |
USPTR Xmstart; | PCRE_PUCHAR Xmstart; |
int Xoffset_top; |
int Xoffset_top; |
eptrblock *Xeptrb; |
eptrblock *Xeptrb; |
unsigned int Xrdepth; |
unsigned int Xrdepth; |
|
|
/* Function local variables */ |
/* Function local variables */ |
|
|
USPTR Xcallpat; | PCRE_PUCHAR Xcallpat; |
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
USPTR Xcharptr; | PCRE_PUCHAR Xcharptr; |
#endif |
#endif |
USPTR Xdata; | PCRE_PUCHAR Xdata; |
USPTR Xnext; | PCRE_PUCHAR Xnext; |
USPTR Xpp; | PCRE_PUCHAR Xpp; |
USPTR Xprev; | PCRE_PUCHAR Xprev; |
USPTR Xsaved_eptr; | PCRE_PUCHAR Xsaved_eptr; |
|
|
recursion_info Xnew_recursive; |
recursion_info Xnew_recursive; |
|
|
Line 375 typedef struct heapframe {
|
Line 390 typedef struct heapframe {
|
int Xprop_value; |
int Xprop_value; |
int Xprop_fail_result; |
int Xprop_fail_result; |
int Xoclength; |
int Xoclength; |
uschar Xocchars[8]; | pcre_uchar Xocchars[6]; |
#endif |
#endif |
|
|
int Xcodelink; |
int Xcodelink; |
Line 440 the subject. */
|
Line 455 the subject. */
|
|
|
|
|
/* Performance note: It might be tempting to extract commonly used fields from |
/* Performance note: It might be tempting to extract commonly used fields from |
the md structure (e.g. utf8, end_subject) into individual variables to improve | the md structure (e.g. utf, end_subject) into individual variables to improve |
performance. Tests using gcc on a SPARC disproved this; in the first case, it |
performance. Tests using gcc on a SPARC disproved this; in the first case, it |
made performance worse. |
made performance worse. |
|
|
Line 463 Returns: MATCH_MATCH if matched ) th
|
Line 478 Returns: MATCH_MATCH if matched ) th
|
*/ |
*/ |
|
|
static int |
static int |
match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart, | match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode, |
int offset_top, match_data *md, eptrblock *eptrb, unsigned int rdepth) | PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb, |
| unsigned int rdepth) |
{ |
{ |
/* These variables do not need to be preserved over recursion in this function, |
/* These variables do not need to be preserved over recursion in this function, |
so they can be ordinary variables in all cases. Mark some of them with |
so they can be ordinary variables in all cases. Mark some of them with |
Line 473 so they can be ordinary variables in all cases. Mark s
|
Line 489 so they can be ordinary variables in all cases. Mark s
|
register int rrc; /* Returns from recursive calls */ |
register int rrc; /* Returns from recursive calls */ |
register int i; /* Used for loops not involving calls to RMATCH() */ |
register int i; /* Used for loops not involving calls to RMATCH() */ |
register unsigned int c; /* Character values not kept over RMATCH() calls */ |
register unsigned int c; /* Character values not kept over RMATCH() calls */ |
register BOOL utf8; /* Local copy of UTF-8 flag for speed */ | register BOOL utf; /* Local copy of UTF flag for speed */ |
|
|
BOOL minimize, possessive; /* Quantifier options */ |
BOOL minimize, possessive; /* Quantifier options */ |
BOOL caseless; |
BOOL caseless; |
int condcode; |
int condcode; |
|
|
/* When recursion is not being used, all "local" variables that have to be |
/* When recursion is not being used, all "local" variables that have to be |
preserved over calls to RMATCH() are part of a "frame" which is obtained from | preserved over calls to RMATCH() are part of a "frame". We set up the top-level |
heap storage. Set up the top-level frame here; others are obtained from the | frame on the stack here; subsequent instantiations are obtained from the heap |
heap whenever RMATCH() does a "recursion". See the macro definitions above. */ | whenever RMATCH() does a "recursion". See the macro definitions above. Putting |
| the top-level on the stack rather than malloc-ing them all gives a performance |
| boost in many cases where there is not much "recursion". */ |
|
|
#ifdef NO_RECURSE |
#ifdef NO_RECURSE |
heapframe *frame = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe)); | heapframe *frame = (heapframe *)md->match_frames_base; |
if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY); | |
frame->Xprevframe = NULL; /* Marks the top level */ | |
|
|
/* Copy in the original argument variables */ |
/* Copy in the original argument variables */ |
|
|
Line 513 HEAP_RECURSE:
|
Line 529 HEAP_RECURSE:
|
|
|
/* Ditto for the local variables */ |
/* Ditto for the local variables */ |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
#define charptr frame->Xcharptr |
#define charptr frame->Xcharptr |
#endif |
#endif |
#define callpat frame->Xcallpat |
#define callpat frame->Xcallpat |
Line 571 declarations can be cut out in a block. The only decla
|
Line 587 declarations can be cut out in a block. The only decla
|
below are for variables that do not have to be preserved over a recursive call |
below are for variables that do not have to be preserved over a recursive call |
to RMATCH(). */ |
to RMATCH(). */ |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
const uschar *charptr; | const pcre_uchar *charptr; |
#endif |
#endif |
const uschar *callpat; | const pcre_uchar *callpat; |
const uschar *data; | const pcre_uchar *data; |
const uschar *next; | const pcre_uchar *next; |
USPTR pp; | PCRE_PUCHAR pp; |
const uschar *prev; | const pcre_uchar *prev; |
USPTR saved_eptr; | PCRE_PUCHAR saved_eptr; |
|
|
recursion_info new_recursive; |
recursion_info new_recursive; |
|
|
Line 592 int prop_type;
|
Line 608 int prop_type;
|
int prop_value; |
int prop_value; |
int prop_fail_result; |
int prop_fail_result; |
int oclength; |
int oclength; |
uschar occhars[8]; | pcre_uchar occhars[6]; |
#endif |
#endif |
|
|
int codelink; |
int codelink; |
Line 608 int save_offset1, save_offset2, save_offset3;
|
Line 624 int save_offset1, save_offset2, save_offset3;
|
int stacksave[REC_STACK_SAVE_MAX]; |
int stacksave[REC_STACK_SAVE_MAX]; |
|
|
eptrblock newptrb; |
eptrblock newptrb; |
|
|
|
/* There is a special fudge for calling match() in a way that causes it to |
|
measure the size of its basic stack frame when the stack is being used for |
|
recursion. The second argument (ecode) being NULL triggers this behaviour. It |
|
cannot normally ever be NULL. The return is the negated value of the frame |
|
size. */ |
|
|
|
if (ecode == NULL) |
|
{ |
|
if (rdepth == 0) |
|
return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1); |
|
else |
|
{ |
|
int len = (char *)&rdepth - (char *)eptr; |
|
return (len > 0)? -len : len; |
|
} |
|
} |
#endif /* NO_RECURSE */ |
#endif /* NO_RECURSE */ |
|
|
/* To save space on the stack and in the heap frame, I have doubled up on some |
/* To save space on the stack and in the heap frame, I have doubled up on some |
Line 620 the alternative names that are used. */
|
Line 653 the alternative names that are used. */
|
#define code_offset codelink |
#define code_offset codelink |
#define condassert condition |
#define condassert condition |
#define matched_once prev_is_word |
#define matched_once prev_is_word |
|
#define foc number |
|
#define save_mark data |
|
|
/* These statements are here to stop the compiler complaining about unitialized |
/* These statements are here to stop the compiler complaining about unitialized |
variables. */ |
variables. */ |
Line 645 defined). However, RMATCH isn't like a function call b
|
Line 680 defined). However, RMATCH isn't like a function call b
|
complicated macro. It has to be used in one particular way. This shouldn't, |
complicated macro. It has to be used in one particular way. This shouldn't, |
however, impact performance when true recursion is being used. */ |
however, impact performance when true recursion is being used. */ |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
utf8 = md->utf8; /* Local copy of the flag */ | utf = md->utf; /* Local copy of the flag */ |
#else |
#else |
utf8 = FALSE; | utf = FALSE; |
#endif |
#endif |
|
|
/* First check that we haven't called match() too many times, or that we |
/* First check that we haven't called match() too many times, or that we |
Line 689 for (;;)
|
Line 724 for (;;)
|
case OP_MARK: |
case OP_MARK: |
md->nomatch_mark = ecode + 2; |
md->nomatch_mark = ecode + 2; |
md->mark = NULL; /* In case previously set by assertion */ |
md->mark = NULL; /* In case previously set by assertion */ |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md, | RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, |
eptrb, RM55); |
eptrb, RM55); |
if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && |
if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && |
md->mark == NULL) md->mark = ecode + 2; |
md->mark == NULL) md->mark = ecode + 2; |
Line 702 for (;;)
|
Line 737 for (;;)
|
unaltered. */ |
unaltered. */ |
|
|
else if (rrc == MATCH_SKIP_ARG && |
else if (rrc == MATCH_SKIP_ARG && |
strcmp((char *)(ecode + 2), (char *)(md->start_match_ptr)) == 0) | STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0) |
{ |
{ |
md->start_match_ptr = eptr; |
md->start_match_ptr = eptr; |
RRETURN(MATCH_SKIP); |
RRETURN(MATCH_SKIP); |
Line 715 for (;;)
|
Line 750 for (;;)
|
/* COMMIT overrides PRUNE, SKIP, and THEN */ |
/* COMMIT overrides PRUNE, SKIP, and THEN */ |
|
|
case OP_COMMIT: |
case OP_COMMIT: |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, | RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, |
eptrb, RM52); |
eptrb, RM52); |
if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && |
if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && |
rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG && |
rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG && |
Line 726 for (;;)
|
Line 761 for (;;)
|
/* PRUNE overrides THEN */ |
/* PRUNE overrides THEN */ |
|
|
case OP_PRUNE: |
case OP_PRUNE: |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, | RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, |
eptrb, RM51); |
eptrb, RM51); |
if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); |
RRETURN(MATCH_PRUNE); |
RRETURN(MATCH_PRUNE); |
Line 734 for (;;)
|
Line 769 for (;;)
|
case OP_PRUNE_ARG: |
case OP_PRUNE_ARG: |
md->nomatch_mark = ecode + 2; |
md->nomatch_mark = ecode + 2; |
md->mark = NULL; /* In case previously set by assertion */ |
md->mark = NULL; /* In case previously set by assertion */ |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md, | RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, |
eptrb, RM56); |
eptrb, RM56); |
if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && |
if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && |
md->mark == NULL) md->mark = ecode + 2; |
md->mark == NULL) md->mark = ecode + 2; |
Line 744 for (;;)
|
Line 779 for (;;)
|
/* SKIP overrides PRUNE and THEN */ |
/* SKIP overrides PRUNE and THEN */ |
|
|
case OP_SKIP: |
case OP_SKIP: |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, | RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, |
eptrb, RM53); |
eptrb, RM53); |
if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN) |
if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN) |
RRETURN(rrc); |
RRETURN(rrc); |
Line 758 for (;;)
|
Line 793 for (;;)
|
case OP_SKIP_ARG: |
case OP_SKIP_ARG: |
if (md->ignore_skip_arg) |
if (md->ignore_skip_arg) |
{ |
{ |
ecode += _pcre_OP_lengths[*ecode] + ecode[1]; | ecode += PRIV(OP_lengths)[*ecode] + ecode[1]; |
break; |
break; |
} |
} |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md, | RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md, |
eptrb, RM57); |
eptrb, RM57); |
if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN) |
if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN) |
RRETURN(rrc); |
RRETURN(rrc); |
Line 779 for (;;)
|
Line 814 for (;;)
|
match pointer to do this. */ |
match pointer to do this. */ |
|
|
case OP_THEN: |
case OP_THEN: |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, | RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, |
eptrb, RM54); |
eptrb, RM54); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
md->start_match_ptr = ecode; |
md->start_match_ptr = ecode; |
Line 788 for (;;)
|
Line 823 for (;;)
|
case OP_THEN_ARG: |
case OP_THEN_ARG: |
md->nomatch_mark = ecode + 2; |
md->nomatch_mark = ecode + 2; |
md->mark = NULL; /* In case previously set by assertion */ |
md->mark = NULL; /* In case previously set by assertion */ |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, | RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, |
md, eptrb, RM58); |
md, eptrb, RM58); |
if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && |
if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) && |
md->mark == NULL) md->mark = ecode + 2; |
md->mark == NULL) md->mark = ecode + 2; |
Line 812 for (;;)
|
Line 847 for (;;)
|
case OP_ONCE_NC: |
case OP_ONCE_NC: |
prev = ecode; |
prev = ecode; |
saved_eptr = eptr; |
saved_eptr = eptr; |
|
save_mark = md->mark; |
do |
do |
{ |
{ |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64); |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64); |
Line 830 for (;;)
|
Line 866 for (;;)
|
|
|
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
ecode += GET(ecode,1); |
ecode += GET(ecode,1); |
|
md->mark = save_mark; |
} |
} |
while (*ecode == OP_ALT); |
while (*ecode == OP_ALT); |
|
|
Line 869 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 909 for (;;)
|
Line 945 for (;;)
|
save_offset2 = md->offset_vector[offset+1]; |
save_offset2 = md->offset_vector[offset+1]; |
save_offset3 = md->offset_vector[md->offset_end - number]; |
save_offset3 = md->offset_vector[md->offset_end - number]; |
save_capture_last = md->capture_last; |
save_capture_last = md->capture_last; |
|
save_mark = md->mark; |
|
|
DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); |
DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); |
md->offset_vector[md->offset_end - number] = |
md->offset_vector[md->offset_end - number] = |
Line 917 for (;;)
|
Line 954 for (;;)
|
for (;;) |
for (;;) |
{ |
{ |
if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; |
if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, | RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, |
eptrb, RM1); |
eptrb, RM1); |
if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */ |
if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */ |
|
|
Line 945 for (;;)
|
Line 982 for (;;)
|
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
md->capture_last = save_capture_last; |
md->capture_last = save_capture_last; |
ecode += GET(ecode, 1); |
ecode += GET(ecode, 1); |
|
md->mark = save_mark; |
if (*ecode != OP_ALT) break; |
if (*ecode != OP_ALT) break; |
} |
} |
|
|
Line 996 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 1004 for (;;)
|
Line 1043 for (;;)
|
|
|
else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT) |
else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT) |
{ |
{ |
ecode += _pcre_OP_lengths[*ecode]; | ecode += PRIV(OP_lengths)[*ecode]; |
goto TAIL_RECURSE; |
goto TAIL_RECURSE; |
} |
} |
|
|
/* In all other cases, we have to make another call to match(). */ |
/* In all other cases, we have to make another call to match(). */ |
|
|
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, eptrb, | save_mark = md->mark; |
| RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, |
RM2); |
RM2); |
|
|
/* See comment in the code for capturing groups above about handling |
/* See comment in the code for capturing groups above about handling |
Line 1028 for (;;)
|
Line 1068 for (;;)
|
{ |
{ |
if (rrc == MATCH_ONCE) |
if (rrc == MATCH_ONCE) |
{ |
{ |
const uschar *scode = ecode; | const pcre_uchar *scode = ecode; |
if (*scode != OP_ONCE) /* If not at start, find it */ |
if (*scode != OP_ONCE) /* If not at start, find it */ |
{ |
{ |
while (*scode == OP_ALT) scode += GET(scode, 1); |
while (*scode == OP_ALT) scode += GET(scode, 1); |
Line 1039 for (;;)
|
Line 1079 for (;;)
|
RRETURN(rrc); |
RRETURN(rrc); |
} |
} |
ecode += GET(ecode, 1); |
ecode += GET(ecode, 1); |
|
md->mark = save_mark; |
if (*ecode != OP_ALT) break; |
if (*ecode != OP_ALT) break; |
} |
} |
|
|
Line 1093 for (;;)
|
Line 1134 for (;;)
|
md->offset_vector[md->offset_end - number] = |
md->offset_vector[md->offset_end - number] = |
(int)(eptr - md->start_subject); |
(int)(eptr - md->start_subject); |
if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; |
if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, | RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, |
eptrb, RM63); |
eptrb, RM63); |
if (rrc == MATCH_KETRPOS) |
if (rrc == MATCH_KETRPOS) |
{ |
{ |
Line 1165 for (;;)
|
Line 1206 for (;;)
|
for (;;) |
for (;;) |
{ |
{ |
if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; |
if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP; |
RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, | RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, |
eptrb, RM48); |
eptrb, RM48); |
if (rrc == MATCH_KETRPOS) |
if (rrc == MATCH_KETRPOS) |
{ |
{ |
Line 1215 for (;;)
|
Line 1256 for (;;)
|
|
|
if (ecode[LINK_SIZE+1] == OP_CALLOUT) |
if (ecode[LINK_SIZE+1] == OP_CALLOUT) |
{ |
{ |
if (pcre_callout != NULL) | if (PUBL(callout) != NULL) |
{ |
{ |
pcre_callout_block cb; | PUBL(callout_block) cb; |
cb.version = 2; /* Version 1 of the callout block */ |
cb.version = 2; /* Version 1 of the callout block */ |
cb.callout_number = ecode[LINK_SIZE+2]; |
cb.callout_number = ecode[LINK_SIZE+2]; |
cb.offset_vector = md->offset_vector; |
cb.offset_vector = md->offset_vector; |
|
#ifdef COMPILE_PCRE8 |
cb.subject = (PCRE_SPTR)md->start_subject; |
cb.subject = (PCRE_SPTR)md->start_subject; |
|
#else |
|
cb.subject = (PCRE_SPTR16)md->start_subject; |
|
#endif |
cb.subject_length = (int)(md->end_subject - md->start_subject); |
cb.subject_length = (int)(md->end_subject - md->start_subject); |
cb.start_match = (int)(mstart - md->start_subject); |
cb.start_match = (int)(mstart - md->start_subject); |
cb.current_position = (int)(eptr - md->start_subject); |
cb.current_position = (int)(eptr - md->start_subject); |
Line 1231 for (;;)
|
Line 1276 for (;;)
|
cb.capture_last = md->capture_last; |
cb.capture_last = md->capture_last; |
cb.callout_data = md->callout_data; |
cb.callout_data = md->callout_data; |
cb.mark = md->nomatch_mark; |
cb.mark = md->nomatch_mark; |
if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH); | if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH); |
if (rrc < 0) RRETURN(rrc); |
if (rrc < 0) RRETURN(rrc); |
} |
} |
ecode += _pcre_OP_lengths[OP_CALLOUT]; | ecode += PRIV(OP_lengths)[OP_CALLOUT]; |
} |
} |
|
|
condcode = ecode[LINK_SIZE+1]; |
condcode = ecode[LINK_SIZE+1]; |
Line 1260 for (;;)
|
Line 1305 for (;;)
|
|
|
if (!condition && condcode == OP_NRREF) |
if (!condition && condcode == OP_NRREF) |
{ |
{ |
uschar *slotA = md->name_table; | pcre_uchar *slotA = md->name_table; |
for (i = 0; i < md->name_count; i++) |
for (i = 0; i < md->name_count; i++) |
{ |
{ |
if (GET2(slotA, 0) == recno) break; |
if (GET2(slotA, 0) == recno) break; |
Line 1273 for (;;)
|
Line 1318 for (;;)
|
|
|
if (i < md->name_count) |
if (i < md->name_count) |
{ |
{ |
uschar *slotB = slotA; | pcre_uchar *slotB = slotA; |
while (slotB > md->name_table) |
while (slotB > md->name_table) |
{ |
{ |
slotB -= md->name_entry_size; |
slotB -= md->name_entry_size; |
if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) | if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) |
{ |
{ |
condition = GET2(slotB, 0) == md->recursive->group_num; |
condition = GET2(slotB, 0) == md->recursive->group_num; |
if (condition) break; |
if (condition) break; |
Line 1293 for (;;)
|
Line 1338 for (;;)
|
for (i++; i < md->name_count; i++) |
for (i++; i < md->name_count; i++) |
{ |
{ |
slotB += md->name_entry_size; |
slotB += md->name_entry_size; |
if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) | if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) |
{ |
{ |
condition = GET2(slotB, 0) == md->recursive->group_num; |
condition = GET2(slotB, 0) == md->recursive->group_num; |
if (condition) break; |
if (condition) break; |
Line 1306 for (;;)
|
Line 1351 for (;;)
|
|
|
/* Chose branch according to the condition */ |
/* Chose branch according to the condition */ |
|
|
ecode += condition? 3 : GET(ecode, 1); | ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1); |
} |
} |
} |
} |
|
|
Line 1323 for (;;)
|
Line 1368 for (;;)
|
if (!condition && condcode == OP_NCREF) |
if (!condition && condcode == OP_NCREF) |
{ |
{ |
int refno = offset >> 1; |
int refno = offset >> 1; |
uschar *slotA = md->name_table; | pcre_uchar *slotA = md->name_table; |
|
|
for (i = 0; i < md->name_count; i++) |
for (i = 0; i < md->name_count; i++) |
{ |
{ |
Line 1337 for (;;)
|
Line 1382 for (;;)
|
|
|
if (i < md->name_count) |
if (i < md->name_count) |
{ |
{ |
uschar *slotB = slotA; | pcre_uchar *slotB = slotA; |
while (slotB > md->name_table) |
while (slotB > md->name_table) |
{ |
{ |
slotB -= md->name_entry_size; |
slotB -= md->name_entry_size; |
if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) | if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) |
{ |
{ |
offset = GET2(slotB, 0) << 1; |
offset = GET2(slotB, 0) << 1; |
condition = offset < offset_top && |
condition = offset < offset_top && |
Line 1359 for (;;)
|
Line 1404 for (;;)
|
for (i++; i < md->name_count; i++) |
for (i++; i < md->name_count; i++) |
{ |
{ |
slotB += md->name_entry_size; |
slotB += md->name_entry_size; |
if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0) | if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) |
{ |
{ |
offset = GET2(slotB, 0) << 1; |
offset = GET2(slotB, 0) << 1; |
condition = offset < offset_top && |
condition = offset < offset_top && |
Line 1374 for (;;)
|
Line 1419 for (;;)
|
|
|
/* Chose branch according to the condition */ |
/* Chose branch according to the condition */ |
|
|
ecode += condition? 3 : GET(ecode, 1); | ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1); |
} |
} |
|
|
else if (condcode == OP_DEF) /* DEFINE - always false */ |
else if (condcode == OP_DEF) /* DEFINE - always false */ |
Line 1466 for (;;)
|
Line 1511 for (;;)
|
md->offset_vector[offset+1] = (int)(eptr - md->start_subject); |
md->offset_vector[offset+1] = (int)(eptr - md->start_subject); |
if (offset_top <= offset) offset_top = offset + 2; |
if (offset_top <= offset) offset_top = offset + 2; |
} |
} |
ecode += 3; | ecode += 1 + IMM2_SIZE; |
break; |
break; |
|
|
|
|
Line 1513 for (;;)
|
Line 1558 for (;;)
|
|
|
case OP_ASSERT: |
case OP_ASSERT: |
case OP_ASSERTBACK: |
case OP_ASSERTBACK: |
|
save_mark = md->mark; |
if (md->match_function_type == MATCH_CONDASSERT) |
if (md->match_function_type == MATCH_CONDASSERT) |
{ |
{ |
condassert = TRUE; |
condassert = TRUE; |
Line 1528 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); |
} |
} |
Line 1557 for (;;)
|
Line 1609 for (;;)
|
|
|
case OP_ASSERT_NOT: |
case OP_ASSERT_NOT: |
case OP_ASSERTBACK_NOT: |
case OP_ASSERTBACK_NOT: |
|
save_mark = md->mark; |
if (md->match_function_type == MATCH_CONDASSERT) |
if (md->match_function_type == MATCH_CONDASSERT) |
{ |
{ |
condassert = TRUE; |
condassert = TRUE; |
Line 1567 for (;;)
|
Line 1620 for (;;)
|
do |
do |
{ |
{ |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5); |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5); |
|
md->mark = save_mark; |
if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH); |
if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH); |
if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT) |
if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT) |
{ |
{ |
Line 1593 for (;;)
|
Line 1647 for (;;)
|
back a number of characters, not bytes. */ |
back a number of characters, not bytes. */ |
|
|
case OP_REVERSE: |
case OP_REVERSE: |
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
if (utf8) | if (utf) |
{ |
{ |
i = GET(ecode, 1); |
i = GET(ecode, 1); |
while (i-- > 0) |
while (i-- > 0) |
Line 1625 for (;;)
|
Line 1679 for (;;)
|
function is able to force a failure. */ |
function is able to force a failure. */ |
|
|
case OP_CALLOUT: |
case OP_CALLOUT: |
if (pcre_callout != NULL) | if (PUBL(callout) != NULL) |
{ |
{ |
pcre_callout_block cb; | PUBL(callout_block) cb; |
cb.version = 2; /* Version 1 of the callout block */ |
cb.version = 2; /* Version 1 of the callout block */ |
cb.callout_number = ecode[1]; |
cb.callout_number = ecode[1]; |
cb.offset_vector = md->offset_vector; |
cb.offset_vector = md->offset_vector; |
|
#ifdef COMPILE_PCRE8 |
cb.subject = (PCRE_SPTR)md->start_subject; |
cb.subject = (PCRE_SPTR)md->start_subject; |
|
#else |
|
cb.subject = (PCRE_SPTR16)md->start_subject; |
|
#endif |
cb.subject_length = (int)(md->end_subject - md->start_subject); |
cb.subject_length = (int)(md->end_subject - md->start_subject); |
cb.start_match = (int)(mstart - md->start_subject); |
cb.start_match = (int)(mstart - md->start_subject); |
cb.current_position = (int)(eptr - md->start_subject); |
cb.current_position = (int)(eptr - md->start_subject); |
Line 1641 for (;;)
|
Line 1699 for (;;)
|
cb.capture_last = md->capture_last; |
cb.capture_last = md->capture_last; |
cb.callout_data = md->callout_data; |
cb.callout_data = md->callout_data; |
cb.mark = md->nomatch_mark; |
cb.mark = md->nomatch_mark; |
if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH); | if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH); |
if (rrc < 0) RRETURN(rrc); |
if (rrc < 0) RRETURN(rrc); |
} |
} |
ecode += 2 + 2*LINK_SIZE; |
ecode += 2 + 2*LINK_SIZE; |
Line 1700 for (;;)
|
Line 1758 for (;;)
|
else |
else |
{ |
{ |
new_recursive.offset_save = |
new_recursive.offset_save = |
(int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int)); | (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int)); |
if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY); |
if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY); |
} |
} |
memcpy(new_recursive.offset_save, md->offset_vector, |
memcpy(new_recursive.offset_save, md->offset_vector, |
Line 1715 for (;;)
|
Line 1773 for (;;)
|
do |
do |
{ |
{ |
if (cbegroup) md->match_function_type = MATCH_CBEGROUP; |
if (cbegroup) md->match_function_type = MATCH_CBEGROUP; |
RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top, | RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top, |
md, eptrb, RM6); |
md, eptrb, RM6); |
memcpy(md->offset_vector, new_recursive.offset_save, |
memcpy(md->offset_vector, new_recursive.offset_save, |
new_recursive.saved_max * sizeof(int)); |
new_recursive.saved_max * sizeof(int)); |
Line 1724 for (;;)
|
Line 1782 for (;;)
|
{ |
{ |
DPRINTF(("Recursion matched\n")); |
DPRINTF(("Recursion matched\n")); |
if (new_recursive.offset_save != stacksave) |
if (new_recursive.offset_save != stacksave) |
(pcre_free)(new_recursive.offset_save); | (PUBL(free))(new_recursive.offset_save); |
|
|
/* Set where we got to in the subject, and reset the start in case |
/* Set where we got to in the subject, and reset the start in case |
it was changed by \K. This *is* propagated back out of a recursion, |
it was changed by \K. This *is* propagated back out of a recursion, |
Line 1735 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) |
(pcre_free)(new_recursive.offset_save); | (PUBL(free))(new_recursive.offset_save); |
RRETURN(rrc); |
RRETURN(rrc); |
} |
} |
|
|
Line 1754 for (;;)
|
Line 1813 for (;;)
|
DPRINTF(("Recursion didn't match\n")); |
DPRINTF(("Recursion didn't match\n")); |
md->recursive = new_recursive.prevrec; |
md->recursive = new_recursive.prevrec; |
if (new_recursive.offset_save != stacksave) |
if (new_recursive.offset_save != stacksave) |
(pcre_free)(new_recursive.offset_save); | (PUBL(free))(new_recursive.offset_save); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
|
|
Line 1949 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 1958 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 2015 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 2047 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 2066 for (;;)
|
Line 2148 for (;;)
|
be "non-word" characters. Remember the earliest consulted character for |
be "non-word" characters. Remember the earliest consulted character for |
partial matching. */ |
partial matching. */ |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
if (utf8) | if (utf) |
{ |
{ |
/* Get status of previous character */ |
/* Get status of previous character */ |
|
|
if (eptr == md->start_subject) prev_is_word = FALSE; else |
if (eptr == md->start_subject) prev_is_word = FALSE; else |
{ |
{ |
USPTR lastptr = eptr - 1; | PCRE_PUCHAR lastptr = eptr - 1; |
while((*lastptr & 0xc0) == 0x80) lastptr--; | BACKCHAR(lastptr); |
if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr; |
if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr; |
GETCHAR(c, lastptr); |
GETCHAR(c, lastptr); |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
Line 2139 for (;;)
|
Line 2221 for (;;)
|
} |
} |
else |
else |
#endif |
#endif |
prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0); | prev_is_word = MAX_255(eptr[-1]) |
| && ((md->ctypes[eptr[-1]] & ctype_word) != 0); |
} |
} |
|
|
/* Get status of next character */ |
/* Get status of next character */ |
Line 2162 for (;;)
|
Line 2245 for (;;)
|
} |
} |
else |
else |
#endif |
#endif |
cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0); | cur_is_word = MAX_255(*eptr) |
| && ((md->ctypes[*eptr] & ctype_word) != 0); |
} |
} |
|
|
/* Now see if the situation is what we want */ |
/* Now see if the situation is what we want */ |
Line 2173 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 2186 for (;;)
|
Line 2283 for (;;)
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
eptr++; |
eptr++; |
if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; | #ifdef SUPPORT_UTF |
| if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
| #endif |
ecode++; |
ecode++; |
break; |
break; |
|
|
Line 2211 for (;;)
|
Line 2310 for (;;)
|
} |
} |
GETCHARINCTEST(c, eptr); |
GETCHARINCTEST(c, eptr); |
if ( |
if ( |
#ifdef SUPPORT_UTF8 | #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) |
c < 256 && |
c < 256 && |
#endif |
#endif |
(md->ctypes[c] & ctype_digit) != 0 |
(md->ctypes[c] & ctype_digit) != 0 |
Line 2228 for (;;)
|
Line 2327 for (;;)
|
} |
} |
GETCHARINCTEST(c, eptr); |
GETCHARINCTEST(c, eptr); |
if ( |
if ( |
#ifdef SUPPORT_UTF8 | #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) |
c >= 256 || | c > 255 || |
#endif |
#endif |
(md->ctypes[c] & ctype_digit) == 0 |
(md->ctypes[c] & ctype_digit) == 0 |
) |
) |
Line 2245 for (;;)
|
Line 2344 for (;;)
|
} |
} |
GETCHARINCTEST(c, eptr); |
GETCHARINCTEST(c, eptr); |
if ( |
if ( |
#ifdef SUPPORT_UTF8 | #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) |
c < 256 && |
c < 256 && |
#endif |
#endif |
(md->ctypes[c] & ctype_space) != 0 |
(md->ctypes[c] & ctype_space) != 0 |
Line 2262 for (;;)
|
Line 2361 for (;;)
|
} |
} |
GETCHARINCTEST(c, eptr); |
GETCHARINCTEST(c, eptr); |
if ( |
if ( |
#ifdef SUPPORT_UTF8 | #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) |
c >= 256 || | c > 255 || |
#endif |
#endif |
(md->ctypes[c] & ctype_space) == 0 |
(md->ctypes[c] & ctype_space) == 0 |
) |
) |
Line 2279 for (;;)
|
Line 2378 for (;;)
|
} |
} |
GETCHARINCTEST(c, eptr); |
GETCHARINCTEST(c, eptr); |
if ( |
if ( |
#ifdef SUPPORT_UTF8 | #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) |
c < 256 && |
c < 256 && |
#endif |
#endif |
(md->ctypes[c] & ctype_word) != 0 |
(md->ctypes[c] & ctype_word) != 0 |
Line 2296 for (;;)
|
Line 2395 for (;;)
|
} |
} |
GETCHARINCTEST(c, eptr); |
GETCHARINCTEST(c, eptr); |
if ( |
if ( |
#ifdef SUPPORT_UTF8 | #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) |
c >= 256 || | c > 255 || |
#endif |
#endif |
(md->ctypes[c] & ctype_word) == 0 |
(md->ctypes[c] & ctype_word) == 0 |
) |
) |
Line 2317 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 2475 for (;;)
|
Line 2578 for (;;)
|
break; |
break; |
|
|
case PT_GC: |
case PT_GC: |
if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP)) | if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP)) |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
break; |
break; |
|
|
Line 2492 for (;;)
|
Line 2595 for (;;)
|
/* These are specials */ |
/* These are specials */ |
|
|
case PT_ALNUM: |
case PT_ALNUM: |
if ((_pcre_ucp_gentype[prop->chartype] == ucp_L || | if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || |
_pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP)) | PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP)) |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
break; |
break; |
|
|
case PT_SPACE: /* Perl space */ |
case PT_SPACE: /* Perl space */ |
if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z || | if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || |
c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) |
c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR) |
== (op == OP_NOTPROP)) |
== (op == OP_NOTPROP)) |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
break; |
break; |
|
|
case PT_PXSPACE: /* POSIX space */ |
case PT_PXSPACE: /* POSIX space */ |
if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z || | if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z || |
c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || |
c == CHAR_HT || c == CHAR_NL || c == CHAR_VT || |
c == CHAR_FF || c == CHAR_CR) |
c == CHAR_FF || c == CHAR_CR) |
== (op == OP_NOTPROP)) |
== (op == OP_NOTPROP)) |
Line 2513 for (;;)
|
Line 2616 for (;;)
|
break; |
break; |
|
|
case PT_WORD: |
case PT_WORD: |
if ((_pcre_ucp_gentype[prop->chartype] == ucp_L || | if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || |
_pcre_ucp_gentype[prop->chartype] == ucp_N || | PRIV(ucp_gentype)[prop->chartype] == ucp_N || |
c == CHAR_UNDERSCORE) == (op == OP_NOTPROP)) |
c == CHAR_UNDERSCORE) == (op == OP_NOTPROP)) |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
break; |
break; |
Line 2543 for (;;)
|
Line 2646 for (;;)
|
while (eptr < md->end_subject) |
while (eptr < md->end_subject) |
{ |
{ |
int len = 1; |
int len = 1; |
if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } | if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } |
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 2564 for (;;)
|
Line 2668 for (;;)
|
case OP_REFI: |
case OP_REFI: |
caseless = op == OP_REFI; |
caseless = op == OP_REFI; |
offset = GET2(ecode, 1) << 1; /* Doubled ref number */ |
offset = GET2(ecode, 1) << 1; /* Doubled ref number */ |
ecode += 3; | ecode += 1 + IMM2_SIZE; |
|
|
/* If the reference is unset, there are two possibilities: |
/* If the reference is unset, there are two possibilities: |
|
|
Line 2604 for (;;)
|
Line 2708 for (;;)
|
case OP_CRMINRANGE: |
case OP_CRMINRANGE: |
minimize = (*ecode == OP_CRMINRANGE); |
minimize = (*ecode == OP_CRMINRANGE); |
min = GET2(ecode, 1); |
min = GET2(ecode, 1); |
max = GET2(ecode, 3); | max = GET2(ecode, 1 + IMM2_SIZE); |
if (max == 0) max = INT_MAX; |
if (max == 0) max = INT_MAX; |
ecode += 5; | ecode += 1 + 2 * IMM2_SIZE; |
break; |
break; |
|
|
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 2620 for (;;)
|
Line 2725 for (;;)
|
} |
} |
|
|
/* Handle repeated back references. If the length of the reference is |
/* Handle repeated back references. If the length of the reference is |
zero, just continue with the main loop. */ | zero, just continue with the main loop. If the length is negative, it |
| means the reference is unset in non-Java-compatible mode. If the minimum is |
| zero, we can continue at the same level without recursion. For any other |
| minimum, carrying on will result in NOMATCH. */ |
|
|
if (length == 0) continue; |
if (length == 0) continue; |
|
if (length < 0 && min == 0) continue; |
|
|
/* First, ensure the minimum number of matches are present. We get back |
/* First, ensure the minimum number of matches are present. We get back |
the length of the reference string explicitly rather than passing the |
the length of the reference string explicitly rather than passing the |
Line 2633 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 2656 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 2674 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 2703 for (;;)
|
Line 2823 for (;;)
|
case OP_NCLASS: |
case OP_NCLASS: |
case OP_CLASS: |
case OP_CLASS: |
{ |
{ |
|
/* The data variable is saved across frames, so the byte map needs to |
|
be stored there. */ |
|
#define BYTE_MAP ((pcre_uint8 *)data) |
data = ecode + 1; /* Save for matching */ |
data = ecode + 1; /* Save for matching */ |
ecode += 33; /* Advance past the item */ | ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */ |
|
|
switch (*ecode) |
switch (*ecode) |
{ |
{ |
Line 2725 for (;;)
|
Line 2848 for (;;)
|
case OP_CRMINRANGE: |
case OP_CRMINRANGE: |
minimize = (*ecode == OP_CRMINRANGE); |
minimize = (*ecode == OP_CRMINRANGE); |
min = GET2(ecode, 1); |
min = GET2(ecode, 1); |
max = GET2(ecode, 3); | max = GET2(ecode, 1 + IMM2_SIZE); |
if (max == 0) max = INT_MAX; |
if (max == 0) max = INT_MAX; |
ecode += 5; | ecode += 1 + 2 * IMM2_SIZE; |
break; |
break; |
|
|
default: /* No repeat follows */ |
default: /* No repeat follows */ |
Line 2737 for (;;)
|
Line 2860 for (;;)
|
|
|
/* First, ensure the minimum number of matches are present. */ |
/* First, ensure the minimum number of matches are present. */ |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
/* UTF-8 mode */ | if (utf) |
if (utf8) | |
{ |
{ |
for (i = 1; i <= min; i++) |
for (i = 1; i <= min; i++) |
{ |
{ |
Line 2754 for (;;)
|
Line 2876 for (;;)
|
if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); |
if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); |
} |
} |
else |
else |
{ | if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); |
if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); | |
} | |
} |
} |
} |
} |
else |
else |
#endif |
#endif |
/* Not UTF-8 mode */ | /* Not UTF mode */ |
{ |
{ |
for (i = 1; i <= min; i++) |
for (i = 1; i <= min; i++) |
{ |
{ |
Line 2771 for (;;)
|
Line 2891 for (;;)
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
c = *eptr++; |
c = *eptr++; |
if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); | #ifndef COMPILE_PCRE8 |
| if (c > 255) |
| { |
| if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); |
| } |
| else |
| #endif |
| if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); |
} |
} |
} |
} |
|
|
Line 2785 for (;;)
|
Line 2912 for (;;)
|
|
|
if (minimize) |
if (minimize) |
{ |
{ |
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
/* UTF-8 mode */ | if (utf) |
if (utf8) | |
{ |
{ |
for (fi = min;; fi++) |
for (fi = min;; fi++) |
{ |
{ |
Line 2805 for (;;)
|
Line 2931 for (;;)
|
if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); |
if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); |
} |
} |
else |
else |
{ | if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); |
if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); | |
} | |
} |
} |
} |
} |
else |
else |
#endif |
#endif |
/* Not UTF-8 mode */ | /* Not UTF mode */ |
{ |
{ |
for (fi = min;; fi++) |
for (fi = min;; fi++) |
{ |
{ |
Line 2825 for (;;)
|
Line 2949 for (;;)
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
c = *eptr++; |
c = *eptr++; |
if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); | #ifndef COMPILE_PCRE8 |
| if (c > 255) |
| { |
| if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); |
| } |
| else |
| #endif |
| if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); |
} |
} |
} |
} |
/* Control never gets here */ |
/* Control never gets here */ |
Line 2837 for (;;)
|
Line 2968 for (;;)
|
{ |
{ |
pp = eptr; |
pp = eptr; |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
/* UTF-8 mode */ | if (utf) |
if (utf8) | |
{ |
{ |
for (i = min; i < max; i++) |
for (i = min; i < max; i++) |
{ |
{ |
Line 2855 for (;;)
|
Line 2985 for (;;)
|
if (op == OP_CLASS) break; |
if (op == OP_CLASS) break; |
} |
} |
else |
else |
{ | if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; |
if ((data[c/8] & (1 << (c&7))) == 0) break; | |
} | |
eptr += len; |
eptr += len; |
} |
} |
for (;;) |
for (;;) |
Line 2870 for (;;)
|
Line 2998 for (;;)
|
} |
} |
else |
else |
#endif |
#endif |
/* Not UTF-8 mode */ | /* Not UTF mode */ |
{ |
{ |
for (i = min; i < max; i++) |
for (i = min; i < max; i++) |
{ |
{ |
Line 2880 for (;;)
|
Line 3008 for (;;)
|
break; |
break; |
} |
} |
c = *eptr; |
c = *eptr; |
if ((data[c/8] & (1 << (c&7))) == 0) break; | #ifndef COMPILE_PCRE8 |
| if (c > 255) |
| { |
| if (op == OP_CLASS) break; |
| } |
| else |
| #endif |
| if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break; |
eptr++; |
eptr++; |
} |
} |
while (eptr >= pp) |
while (eptr >= pp) |
Line 2893 for (;;)
|
Line 3028 for (;;)
|
|
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
|
#undef BYTE_MAP |
} |
} |
/* Control never gets here */ |
/* Control never gets here */ |
|
|
Line 2901 for (;;)
|
Line 3037 for (;;)
|
when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8 |
when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8 |
mode, because Unicode properties are supported in non-UTF-8 mode. */ |
mode, because Unicode properties are supported in non-UTF-8 mode. */ |
|
|
#ifdef SUPPORT_UTF8 | #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
case OP_XCLASS: |
case OP_XCLASS: |
{ |
{ |
data = ecode + 1 + LINK_SIZE; /* Save for matching */ |
data = ecode + 1 + LINK_SIZE; /* Save for matching */ |
Line 2926 for (;;)
|
Line 3062 for (;;)
|
case OP_CRMINRANGE: |
case OP_CRMINRANGE: |
minimize = (*ecode == OP_CRMINRANGE); |
minimize = (*ecode == OP_CRMINRANGE); |
min = GET2(ecode, 1); |
min = GET2(ecode, 1); |
max = GET2(ecode, 3); | max = GET2(ecode, 1 + IMM2_SIZE); |
if (max == 0) max = INT_MAX; |
if (max == 0) max = INT_MAX; |
ecode += 5; | ecode += 1 + 2 * IMM2_SIZE; |
break; |
break; |
|
|
default: /* No repeat follows */ |
default: /* No repeat follows */ |
Line 2946 for (;;)
|
Line 3082 for (;;)
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
GETCHARINCTEST(c, eptr); |
GETCHARINCTEST(c, eptr); |
if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH); | if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); |
} |
} |
|
|
/* If max == min we can continue with the main loop without the |
/* If max == min we can continue with the main loop without the |
Line 2970 for (;;)
|
Line 3106 for (;;)
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
GETCHARINCTEST(c, eptr); |
GETCHARINCTEST(c, eptr); |
if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH); | if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH); |
} |
} |
/* Control never gets here */ |
/* Control never gets here */ |
} |
} |
Line 2988 for (;;)
|
Line 3124 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
break; |
break; |
} |
} |
|
#ifdef SUPPORT_UTF |
GETCHARLENTEST(c, eptr, len); |
GETCHARLENTEST(c, eptr, len); |
if (!_pcre_xclass(c, data)) break; | #else |
| c = *eptr; |
| #endif |
| if (!PRIV(xclass)(c, data, utf)) break; |
eptr += len; |
eptr += len; |
} |
} |
for(;;) |
for(;;) |
Line 2997 for (;;)
|
Line 3137 for (;;)
|
RMATCH(eptr, ecode, offset_top, md, eptrb, RM21); |
RMATCH(eptr, ecode, offset_top, md, eptrb, RM21); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (eptr-- == pp) break; /* Stop if tried at original pos */ |
if (eptr-- == pp) break; /* Stop if tried at original pos */ |
if (utf8) BACKCHAR(eptr); | #ifdef SUPPORT_UTF |
| if (utf) BACKCHAR(eptr); |
| #endif |
} |
} |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
Line 3009 for (;;)
|
Line 3151 for (;;)
|
/* Match a single character, casefully */ |
/* Match a single character, casefully */ |
|
|
case OP_CHAR: |
case OP_CHAR: |
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
if (utf8) | if (utf) |
{ |
{ |
length = 1; |
length = 1; |
ecode++; |
ecode++; |
Line 3024 for (;;)
|
Line 3166 for (;;)
|
} |
} |
else |
else |
#endif |
#endif |
| /* Not UTF mode */ |
/* Non-UTF-8 mode */ | |
{ |
{ |
if (md->end_subject - eptr < 1) |
if (md->end_subject - eptr < 1) |
{ |
{ |
Line 3047 for (;;)
|
Line 3188 for (;;)
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
if (utf8) | if (utf) |
{ |
{ |
length = 1; |
length = 1; |
ecode++; |
ecode++; |
Line 3061 for (;;)
|
Line 3202 for (;;)
|
|
|
if (fc < 128) |
if (fc < 128) |
{ |
{ |
if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); | if (md->lcc[fc] |
| != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH); |
| ecode++; |
| eptr++; |
} |
} |
|
|
/* Otherwise we must pick up the subject character. Note that we cannot |
/* Otherwise we must pick up the subject character. Note that we cannot |
Line 3087 for (;;)
|
Line 3231 for (;;)
|
} |
} |
} |
} |
else |
else |
#endif /* SUPPORT_UTF8 */ | #endif /* SUPPORT_UTF */ |
|
|
/* Non-UTF-8 mode */ | /* Not UTF mode */ |
{ |
{ |
if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); | if (TABLE_GET(ecode[1], md->lcc, ecode[1]) |
| != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH); |
| eptr++; |
ecode += 2; |
ecode += 2; |
} |
} |
break; |
break; |
Line 3101 for (;;)
|
Line 3247 for (;;)
|
case OP_EXACT: |
case OP_EXACT: |
case OP_EXACTI: |
case OP_EXACTI: |
min = max = GET2(ecode, 1); |
min = max = GET2(ecode, 1); |
ecode += 3; | ecode += 1 + IMM2_SIZE; |
goto REPEATCHAR; |
goto REPEATCHAR; |
|
|
case OP_POSUPTO: |
case OP_POSUPTO: |
Line 3116 for (;;)
|
Line 3262 for (;;)
|
min = 0; |
min = 0; |
max = GET2(ecode, 1); |
max = GET2(ecode, 1); |
minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI; |
minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI; |
ecode += 3; | ecode += 1 + IMM2_SIZE; |
goto REPEATCHAR; |
goto REPEATCHAR; |
|
|
case OP_POSSTAR: |
case OP_POSSTAR: |
Line 3164 for (;;)
|
Line 3310 for (;;)
|
/* Common code for all repeated single-character matches. */ |
/* Common code for all repeated single-character matches. */ |
|
|
REPEATCHAR: |
REPEATCHAR: |
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
if (utf8) | if (utf) |
{ |
{ |
length = 1; |
length = 1; |
charptr = ecode; |
charptr = ecode; |
Line 3181 for (;;)
|
Line 3327 for (;;)
|
unsigned int othercase; |
unsigned int othercase; |
if (op >= OP_STARI && /* Caseless */ |
if (op >= OP_STARI && /* Caseless */ |
(othercase = UCD_OTHERCASE(fc)) != fc) |
(othercase = UCD_OTHERCASE(fc)) != fc) |
oclength = _pcre_ord2utf8(othercase, occhars); | oclength = PRIV(ord2utf)(othercase, occhars); |
else oclength = 0; |
else oclength = 0; |
#endif /* SUPPORT_UCP */ |
#endif /* SUPPORT_UCP */ |
|
|
for (i = 1; i <= min; i++) |
for (i = 1; i <= min; i++) |
{ |
{ |
if (eptr <= md->end_subject - length && |
if (eptr <= md->end_subject - length && |
memcmp(eptr, charptr, length) == 0) eptr += length; | memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length; |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
else if (oclength > 0 && |
else if (oclength > 0 && |
eptr <= md->end_subject - oclength && |
eptr <= md->end_subject - oclength && |
memcmp(eptr, occhars, oclength) == 0) eptr += oclength; | memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength; |
#endif /* SUPPORT_UCP */ |
#endif /* SUPPORT_UCP */ |
else |
else |
{ |
{ |
Line 3211 for (;;)
|
Line 3357 for (;;)
|
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (fi >= max) RRETURN(MATCH_NOMATCH); |
if (fi >= max) RRETURN(MATCH_NOMATCH); |
if (eptr <= md->end_subject - length && |
if (eptr <= md->end_subject - length && |
memcmp(eptr, charptr, length) == 0) eptr += length; | memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length; |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
else if (oclength > 0 && |
else if (oclength > 0 && |
eptr <= md->end_subject - oclength && |
eptr <= md->end_subject - oclength && |
memcmp(eptr, occhars, oclength) == 0) eptr += oclength; | memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength; |
#endif /* SUPPORT_UCP */ |
#endif /* SUPPORT_UCP */ |
else |
else |
{ |
{ |
Line 3232 for (;;)
|
Line 3378 for (;;)
|
for (i = min; i < max; i++) |
for (i = min; i < max; i++) |
{ |
{ |
if (eptr <= md->end_subject - length && |
if (eptr <= md->end_subject - length && |
memcmp(eptr, charptr, length) == 0) eptr += length; | memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length; |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
else if (oclength > 0 && |
else if (oclength > 0 && |
eptr <= md->end_subject - oclength && |
eptr <= md->end_subject - oclength && |
memcmp(eptr, occhars, oclength) == 0) eptr += oclength; | memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength; |
#endif /* SUPPORT_UCP */ |
#endif /* SUPPORT_UCP */ |
else |
else |
{ |
{ |
Line 3268 for (;;)
|
Line 3414 for (;;)
|
value of fc will always be < 128. */ |
value of fc will always be < 128. */ |
} |
} |
else |
else |
#endif /* SUPPORT_UTF8 */ | #endif /* SUPPORT_UTF */ |
| /* When not in UTF-8 mode, load a single-byte character. */ |
| fc = *ecode++; |
|
|
/* When not in UTF-8 mode, load a single-byte character. */ | /* The value of fc at this point is always one character, though we may |
| or may not be in UTF mode. The code is duplicated for the caseless and |
fc = *ecode++; | |
| |
/* The value of fc at this point is always less than 256, though we may or | |
may not be in UTF-8 mode. The code is duplicated for the caseless and | |
caseful cases, for speed, since matching characters is likely to be quite |
caseful cases, for speed, since matching characters is likely to be quite |
common. First, ensure the minimum number of matches are present. If min = |
common. First, ensure the minimum number of matches are present. If min = |
max, continue at the same level without recursing. Otherwise, if |
max, continue at the same level without recursing. Otherwise, if |
Line 3284 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 */ |
{ |
{ |
fc = md->lcc[fc]; | #ifdef COMPILE_PCRE8 |
| /* fc must be < 128 if UTF is enabled. */ |
| foc = md->fcc[fc]; |
| #else |
| #ifdef SUPPORT_UTF |
| #ifdef SUPPORT_UCP |
| if (utf && fc > 127) |
| foc = UCD_OTHERCASE(fc); |
| #else |
| if (utf && fc > 127) |
| foc = fc; |
| #endif /* SUPPORT_UCP */ |
| else |
| #endif /* SUPPORT_UTF */ |
| foc = TABLE_GET(fc, md->fcc, fc); |
| #endif /* COMPILE_PCRE8 */ |
| |
for (i = 1; i <= min; i++) |
for (i = 1; i <= min; i++) |
{ |
{ |
if (eptr >= md->end_subject) |
if (eptr >= md->end_subject) |
Line 3296 for (;;)
|
Line 3456 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); | if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH); |
| eptr++; |
} |
} |
if (min == max) continue; |
if (min == max) continue; |
if (minimize) |
if (minimize) |
Line 3311 for (;;)
|
Line 3472 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); | if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH); |
| eptr++; |
} |
} |
/* Control never gets here */ |
/* Control never gets here */ |
} |
} |
Line 3325 for (;;)
|
Line 3487 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
break; |
break; |
} |
} |
if (fc != md->lcc[*eptr]) break; | if (fc != *eptr && foc != *eptr) break; |
eptr++; |
eptr++; |
} |
} |
|
|
Line 3410 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 */ | |
{ |
{ |
#ifdef SUPPORT_UTF8 | register unsigned int ch, och; |
if (c < 256) | |
#endif | ecode++; |
c = md->lcc[c]; | GETCHARINC(ch, ecode); |
if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH); | GETCHARINC(c, eptr); |
| |
| if (op == OP_NOT) |
| { |
| if (ch == c) RRETURN(MATCH_NOMATCH); |
| } |
| else |
| { |
| #ifdef SUPPORT_UCP |
| if (ch > 127) |
| och = UCD_OTHERCASE(ch); |
| #else |
| if (ch > 127) |
| och = ch; |
| #endif /* SUPPORT_UCP */ |
| else |
| och = TABLE_GET(ch, md->fcc, ch); |
| 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 3436 for (;;)
|
Line 3620 for (;;)
|
case OP_NOTEXACT: |
case OP_NOTEXACT: |
case OP_NOTEXACTI: |
case OP_NOTEXACTI: |
min = max = GET2(ecode, 1); |
min = max = GET2(ecode, 1); |
ecode += 3; | ecode += 1 + IMM2_SIZE; |
goto REPEATNOTCHAR; |
goto REPEATNOTCHAR; |
|
|
case OP_NOTUPTO: |
case OP_NOTUPTO: |
Line 3446 for (;;)
|
Line 3630 for (;;)
|
min = 0; |
min = 0; |
max = GET2(ecode, 1); |
max = GET2(ecode, 1); |
minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI; |
minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI; |
ecode += 3; | ecode += 1 + IMM2_SIZE; |
goto REPEATNOTCHAR; |
goto REPEATNOTCHAR; |
|
|
case OP_NOTPOSSTAR: |
case OP_NOTPOSSTAR: |
Line 3478 for (;;)
|
Line 3662 for (;;)
|
possessive = TRUE; |
possessive = TRUE; |
min = 0; |
min = 0; |
max = GET2(ecode, 1); |
max = GET2(ecode, 1); |
ecode += 3; | ecode += 1 + IMM2_SIZE; |
goto REPEATNOTCHAR; |
goto REPEATNOTCHAR; |
|
|
case OP_NOTSTAR: |
case OP_NOTSTAR: |
Line 3502 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 3513 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 */ |
{ |
{ |
fc = md->lcc[fc]; | #ifdef SUPPORT_UTF |
| #ifdef SUPPORT_UCP |
| if (utf && fc > 127) |
| foc = UCD_OTHERCASE(fc); |
| #else |
| if (utf && fc > 127) |
| foc = fc; |
| #endif /* SUPPORT_UCP */ |
| else |
| #endif /* SUPPORT_UTF */ |
| foc = TABLE_GET(fc, md->fcc, fc); |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
/* UTF-8 mode */ | if (utf) |
if (utf8) | |
{ |
{ |
register unsigned int d; |
register unsigned int d; |
for (i = 1; i <= min; i++) |
for (i = 1; i <= min; i++) |
Line 3532 for (;;)
|
Line 3725 for (;;)
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
GETCHARINC(d, eptr); |
GETCHARINC(d, eptr); |
if (d < 256) d = md->lcc[d]; | if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH); |
if (fc == d) RRETURN(MATCH_NOMATCH); | |
} |
} |
} |
} |
else |
else |
#endif |
#endif |
| /* Not UTF mode */ |
/* Not UTF-8 mode */ | |
{ |
{ |
for (i = 1; i <= min; i++) |
for (i = 1; i <= min; i++) |
{ |
{ |
Line 3548 for (;;)
|
Line 3739 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); | if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); |
| eptr++; |
} |
} |
} |
} |
|
|
Line 3556 for (;;)
|
Line 3748 for (;;)
|
|
|
if (minimize) |
if (minimize) |
{ |
{ |
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
/* UTF-8 mode */ | if (utf) |
if (utf8) | |
{ |
{ |
register unsigned int d; |
register unsigned int d; |
for (fi = min;; fi++) |
for (fi = min;; fi++) |
Line 3572 for (;;)
|
Line 3763 for (;;)
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
GETCHARINC(d, eptr); |
GETCHARINC(d, eptr); |
if (d < 256) d = md->lcc[d]; | if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH); |
if (fc == d) RRETURN(MATCH_NOMATCH); | |
} |
} |
} |
} |
else |
else |
#endif |
#endif |
/* Not UTF-8 mode */ | /* Not UTF mode */ |
{ |
{ |
for (fi = min;; fi++) |
for (fi = min;; fi++) |
{ |
{ |
Line 3590 for (;;)
|
Line 3780 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); | if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH); |
| eptr++; |
} |
} |
} |
} |
/* Control never gets here */ |
/* Control never gets here */ |
Line 3602 for (;;)
|
Line 3793 for (;;)
|
{ |
{ |
pp = eptr; |
pp = eptr; |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
/* UTF-8 mode */ | if (utf) |
if (utf8) | |
{ |
{ |
register unsigned int d; |
register unsigned int d; |
for (i = min; i < max; i++) |
for (i = min; i < max; i++) |
Line 3616 for (;;)
|
Line 3806 for (;;)
|
break; |
break; |
} |
} |
GETCHARLEN(d, eptr, len); |
GETCHARLEN(d, eptr, len); |
if (d < 256) d = md->lcc[d]; | if (fc == d || (unsigned int)foc == d) break; |
if (fc == d) break; | |
eptr += len; |
eptr += len; |
} |
} |
if (possessive) continue; | if (possessive) continue; |
for(;;) | for(;;) |
{ |
{ |
RMATCH(eptr, ecode, offset_top, md, eptrb, RM30); |
RMATCH(eptr, ecode, offset_top, md, eptrb, RM30); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
Line 3631 for (;;)
|
Line 3820 for (;;)
|
} |
} |
else |
else |
#endif |
#endif |
/* Not UTF-8 mode */ | /* Not UTF mode */ |
{ |
{ |
for (i = min; i < max; i++) |
for (i = min; i < max; i++) |
{ |
{ |
Line 3640 for (;;)
|
Line 3829 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
break; |
break; |
} |
} |
if (fc == md->lcc[*eptr]) break; | if (fc == *eptr || foc == *eptr) break; |
eptr++; |
eptr++; |
} |
} |
if (possessive) continue; |
if (possessive) continue; |
Line 3661 for (;;)
|
Line 3850 for (;;)
|
|
|
else |
else |
{ |
{ |
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
/* UTF-8 mode */ | if (utf) |
if (utf8) | |
{ |
{ |
register unsigned int d; |
register unsigned int d; |
for (i = 1; i <= min; i++) |
for (i = 1; i <= min; i++) |
Line 3679 for (;;)
|
Line 3867 for (;;)
|
} |
} |
else |
else |
#endif |
#endif |
/* Not UTF-8 mode */ | /* Not UTF mode */ |
{ |
{ |
for (i = 1; i <= min; i++) |
for (i = 1; i <= min; i++) |
{ |
{ |
Line 3696 for (;;)
|
Line 3884 for (;;)
|
|
|
if (minimize) |
if (minimize) |
{ |
{ |
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
/* UTF-8 mode */ | if (utf) |
if (utf8) | |
{ |
{ |
register unsigned int d; |
register unsigned int d; |
for (fi = min;; fi++) |
for (fi = min;; fi++) |
Line 3717 for (;;)
|
Line 3904 for (;;)
|
} |
} |
else |
else |
#endif |
#endif |
/* Not UTF-8 mode */ | /* Not UTF mode */ |
{ |
{ |
for (fi = min;; fi++) |
for (fi = min;; fi++) |
{ |
{ |
Line 3741 for (;;)
|
Line 3928 for (;;)
|
{ |
{ |
pp = eptr; |
pp = eptr; |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
/* UTF-8 mode */ | if (utf) |
if (utf8) | |
{ |
{ |
register unsigned int d; |
register unsigned int d; |
for (i = min; i < max; i++) |
for (i = min; i < max; i++) |
Line 3769 for (;;)
|
Line 3955 for (;;)
|
} |
} |
else |
else |
#endif |
#endif |
/* Not UTF-8 mode */ | /* Not UTF mode */ |
{ |
{ |
for (i = min; i < max; i++) |
for (i = min; i < max; i++) |
{ |
{ |
Line 3802 for (;;)
|
Line 3988 for (;;)
|
case OP_TYPEEXACT: |
case OP_TYPEEXACT: |
min = max = GET2(ecode, 1); |
min = max = GET2(ecode, 1); |
minimize = TRUE; |
minimize = TRUE; |
ecode += 3; | ecode += 1 + IMM2_SIZE; |
goto REPEATTYPE; |
goto REPEATTYPE; |
|
|
case OP_TYPEUPTO: |
case OP_TYPEUPTO: |
Line 3810 for (;;)
|
Line 3996 for (;;)
|
min = 0; |
min = 0; |
max = GET2(ecode, 1); |
max = GET2(ecode, 1); |
minimize = *ecode == OP_TYPEMINUPTO; |
minimize = *ecode == OP_TYPEMINUPTO; |
ecode += 3; | ecode += 1 + IMM2_SIZE; |
goto REPEATTYPE; |
goto REPEATTYPE; |
|
|
case OP_TYPEPOSSTAR: |
case OP_TYPEPOSSTAR: |
Line 3838 for (;;)
|
Line 4024 for (;;)
|
possessive = TRUE; |
possessive = TRUE; |
min = 0; |
min = 0; |
max = GET2(ecode, 1); |
max = GET2(ecode, 1); |
ecode += 3; | ecode += 1 + IMM2_SIZE; |
goto REPEATTYPE; |
goto REPEATTYPE; |
|
|
case OP_TYPESTAR: |
case OP_TYPESTAR: |
Line 4045 for (;;)
|
Line 4231 for (;;)
|
while (eptr < md->end_subject) |
while (eptr < md->end_subject) |
{ |
{ |
int len = 1; |
int len = 1; |
if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } | if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } |
if (UCD_CATEGORY(c) != ucp_M) break; |
if (UCD_CATEGORY(c) != ucp_M) break; |
eptr += len; |
eptr += len; |
} |
} |
|
CHECK_PARTIAL(); |
} |
} |
} |
} |
|
|
Line 4057 for (;;)
|
Line 4244 for (;;)
|
|
|
/* Handle all other cases when the coding is UTF-8 */ |
/* Handle all other cases when the coding is UTF-8 */ |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
if (utf8) switch(ctype) | if (utf) switch(ctype) |
{ |
{ |
case OP_ANY: |
case OP_ANY: |
for (i = 1; i <= min; i++) |
for (i = 1; i <= min; i++) |
Line 4069 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++; |
while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; | ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
} |
} |
break; |
break; |
|
|
Line 4083 for (;;)
|
Line 4279 for (;;)
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
eptr++; |
eptr++; |
while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; | ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
} |
} |
break; |
break; |
|
|
Line 4265 for (;;)
|
Line 4461 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0) | if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0) |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
|
eptr++; |
/* No need to skip more bytes - we know it's a 1-byte character */ |
/* No need to skip more bytes - we know it's a 1-byte character */ |
} |
} |
break; |
break; |
Line 4281 for (;;)
|
Line 4478 for (;;)
|
} |
} |
if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0) |
if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0) |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80); | eptr++; |
| ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
} |
} |
break; |
break; |
|
|
Line 4293 for (;;)
|
Line 4491 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0) | if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0) |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
|
eptr++; |
/* No need to skip more bytes - we know it's a 1-byte character */ |
/* No need to skip more bytes - we know it's a 1-byte character */ |
} |
} |
break; |
break; |
Line 4309 for (;;)
|
Line 4508 for (;;)
|
} |
} |
if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0) |
if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0) |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80); | eptr++; |
| ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
} |
} |
break; |
break; |
|
|
Line 4321 for (;;)
|
Line 4521 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0) | if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0) |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
|
eptr++; |
/* No need to skip more bytes - we know it's a 1-byte character */ |
/* No need to skip more bytes - we know it's a 1-byte character */ |
} |
} |
break; |
break; |
Line 4332 for (;;)
|
Line 4533 for (;;)
|
} /* End switch(ctype) */ |
} /* End switch(ctype) */ |
|
|
else |
else |
#endif /* SUPPORT_UTF8 */ | #endif /* SUPPORT_UTF */ |
|
|
/* Code for the non-UTF-8 case for minimum matching of operators other |
/* Code for the non-UTF-8 case for minimum matching of operators other |
than OP_PROP and OP_NOTPROP. */ |
than OP_PROP and OP_NOTPROP. */ |
Line 4348 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 4392 for (;;)
|
Line 4602 for (;;)
|
case 0x000b: |
case 0x000b: |
case 0x000c: |
case 0x000c: |
case 0x0085: |
case 0x0085: |
|
#ifdef COMPILE_PCRE16 |
|
case 0x2028: |
|
case 0x2029: |
|
#endif |
if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); |
if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); |
break; |
break; |
} |
} |
Line 4412 for (;;)
|
Line 4626 for (;;)
|
case 0x09: /* HT */ |
case 0x09: /* HT */ |
case 0x20: /* SPACE */ |
case 0x20: /* SPACE */ |
case 0xa0: /* NBSP */ |
case 0xa0: /* NBSP */ |
|
#ifdef COMPILE_PCRE16 |
|
case 0x1680: /* OGHAM SPACE MARK */ |
|
case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ |
|
case 0x2000: /* EN QUAD */ |
|
case 0x2001: /* EM QUAD */ |
|
case 0x2002: /* EN SPACE */ |
|
case 0x2003: /* EM SPACE */ |
|
case 0x2004: /* THREE-PER-EM SPACE */ |
|
case 0x2005: /* FOUR-PER-EM SPACE */ |
|
case 0x2006: /* SIX-PER-EM SPACE */ |
|
case 0x2007: /* FIGURE SPACE */ |
|
case 0x2008: /* PUNCTUATION SPACE */ |
|
case 0x2009: /* THIN SPACE */ |
|
case 0x200A: /* HAIR SPACE */ |
|
case 0x202f: /* NARROW NO-BREAK SPACE */ |
|
case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ |
|
case 0x3000: /* IDEOGRAPHIC SPACE */ |
|
#endif |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
} |
} |
Line 4431 for (;;)
|
Line 4663 for (;;)
|
case 0x09: /* HT */ |
case 0x09: /* HT */ |
case 0x20: /* SPACE */ |
case 0x20: /* SPACE */ |
case 0xa0: /* NBSP */ |
case 0xa0: /* NBSP */ |
|
#ifdef COMPILE_PCRE16 |
|
case 0x1680: /* OGHAM SPACE MARK */ |
|
case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ |
|
case 0x2000: /* EN QUAD */ |
|
case 0x2001: /* EM QUAD */ |
|
case 0x2002: /* EN SPACE */ |
|
case 0x2003: /* EM SPACE */ |
|
case 0x2004: /* THREE-PER-EM SPACE */ |
|
case 0x2005: /* FOUR-PER-EM SPACE */ |
|
case 0x2006: /* SIX-PER-EM SPACE */ |
|
case 0x2007: /* FIGURE SPACE */ |
|
case 0x2008: /* PUNCTUATION SPACE */ |
|
case 0x2009: /* THIN SPACE */ |
|
case 0x200A: /* HAIR SPACE */ |
|
case 0x202f: /* NARROW NO-BREAK SPACE */ |
|
case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ |
|
case 0x3000: /* IDEOGRAPHIC SPACE */ |
|
#endif |
break; |
break; |
} |
} |
} |
} |
Line 4452 for (;;)
|
Line 4702 for (;;)
|
case 0x0c: /* FF */ |
case 0x0c: /* FF */ |
case 0x0d: /* CR */ |
case 0x0d: /* CR */ |
case 0x85: /* NEL */ |
case 0x85: /* NEL */ |
|
#ifdef COMPILE_PCRE16 |
|
case 0x2028: /* LINE SEPARATOR */ |
|
case 0x2029: /* PARAGRAPH SEPARATOR */ |
|
#endif |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
} |
} |
Line 4473 for (;;)
|
Line 4727 for (;;)
|
case 0x0c: /* FF */ |
case 0x0c: /* FF */ |
case 0x0d: /* CR */ |
case 0x0d: /* CR */ |
case 0x85: /* NEL */ |
case 0x85: /* NEL */ |
|
#ifdef COMPILE_PCRE16 |
|
case 0x2028: /* LINE SEPARATOR */ |
|
case 0x2029: /* PARAGRAPH SEPARATOR */ |
|
#endif |
break; |
break; |
} |
} |
} |
} |
Line 4486 for (;;)
|
Line 4744 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); | if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) |
| RRETURN(MATCH_NOMATCH); |
| eptr++; |
} |
} |
break; |
break; |
|
|
Line 4498 for (;;)
|
Line 4758 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); | if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) |
| RRETURN(MATCH_NOMATCH); |
| eptr++; |
} |
} |
break; |
break; |
|
|
Line 4510 for (;;)
|
Line 4772 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); | if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) |
| RRETURN(MATCH_NOMATCH); |
| eptr++; |
} |
} |
break; |
break; |
|
|
Line 4522 for (;;)
|
Line 4786 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); | if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) |
| RRETURN(MATCH_NOMATCH); |
| eptr++; |
} |
} |
break; |
break; |
|
|
Line 4534 for (;;)
|
Line 4800 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if ((md->ctypes[*eptr++] & ctype_word) != 0) | if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
|
eptr++; |
} |
} |
break; |
break; |
|
|
Line 4547 for (;;)
|
Line 4814 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
if ((md->ctypes[*eptr++] & ctype_word) == 0) | if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
|
eptr++; |
} |
} |
break; |
break; |
|
|
Line 4766 for (;;)
|
Line 5034 for (;;)
|
while (eptr < md->end_subject) |
while (eptr < md->end_subject) |
{ |
{ |
int len = 1; |
int len = 1; |
if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } | if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } |
if (UCD_CATEGORY(c) != ucp_M) break; |
if (UCD_CATEGORY(c) != ucp_M) break; |
eptr += len; |
eptr += len; |
} |
} |
|
CHECK_PARTIAL(); |
} |
} |
} |
} |
else |
else |
#endif /* SUPPORT_UCP */ |
#endif /* SUPPORT_UCP */ |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
/* UTF-8 mode */ | if (utf) |
if (utf8) | |
{ |
{ |
for (fi = min;; fi++) |
for (fi = min;; fi++) |
{ |
{ |
Line 4794 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 4919 for (;;)
|
Line 5198 for (;;)
|
break; |
break; |
|
|
case OP_WHITESPACE: |
case OP_WHITESPACE: |
if (c >= 256 || (md->ctypes[c] & ctype_space) == 0) | if (c >= 256 || (md->ctypes[c] & ctype_space) == 0) |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
break; |
break; |
|
|
Line 4940 for (;;)
|
Line 5219 for (;;)
|
} |
} |
else |
else |
#endif |
#endif |
/* Not UTF-8 mode */ | /* Not UTF mode */ |
{ |
{ |
for (fi = min;; fi++) |
for (fi = min;; fi++) |
{ |
{ |
Line 4957 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 4976 for (;;)
|
Line 5266 for (;;)
|
case 0x000b: |
case 0x000b: |
case 0x000c: |
case 0x000c: |
case 0x0085: |
case 0x0085: |
|
#ifdef COMPILE_PCRE16 |
|
case 0x2028: |
|
case 0x2029: |
|
#endif |
if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); |
if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); |
break; |
break; |
} |
} |
Line 4988 for (;;)
|
Line 5282 for (;;)
|
case 0x09: /* HT */ |
case 0x09: /* HT */ |
case 0x20: /* SPACE */ |
case 0x20: /* SPACE */ |
case 0xa0: /* NBSP */ |
case 0xa0: /* NBSP */ |
|
#ifdef COMPILE_PCRE16 |
|
case 0x1680: /* OGHAM SPACE MARK */ |
|
case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ |
|
case 0x2000: /* EN QUAD */ |
|
case 0x2001: /* EM QUAD */ |
|
case 0x2002: /* EN SPACE */ |
|
case 0x2003: /* EM SPACE */ |
|
case 0x2004: /* THREE-PER-EM SPACE */ |
|
case 0x2005: /* FOUR-PER-EM SPACE */ |
|
case 0x2006: /* SIX-PER-EM SPACE */ |
|
case 0x2007: /* FIGURE SPACE */ |
|
case 0x2008: /* PUNCTUATION SPACE */ |
|
case 0x2009: /* THIN SPACE */ |
|
case 0x200A: /* HAIR SPACE */ |
|
case 0x202f: /* NARROW NO-BREAK SPACE */ |
|
case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ |
|
case 0x3000: /* IDEOGRAPHIC SPACE */ |
|
#endif |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
break; |
break; |
Line 4999 for (;;)
|
Line 5311 for (;;)
|
case 0x09: /* HT */ |
case 0x09: /* HT */ |
case 0x20: /* SPACE */ |
case 0x20: /* SPACE */ |
case 0xa0: /* NBSP */ |
case 0xa0: /* NBSP */ |
|
#ifdef COMPILE_PCRE16 |
|
case 0x1680: /* OGHAM SPACE MARK */ |
|
case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ |
|
case 0x2000: /* EN QUAD */ |
|
case 0x2001: /* EM QUAD */ |
|
case 0x2002: /* EN SPACE */ |
|
case 0x2003: /* EM SPACE */ |
|
case 0x2004: /* THREE-PER-EM SPACE */ |
|
case 0x2005: /* FOUR-PER-EM SPACE */ |
|
case 0x2006: /* SIX-PER-EM SPACE */ |
|
case 0x2007: /* FIGURE SPACE */ |
|
case 0x2008: /* PUNCTUATION SPACE */ |
|
case 0x2009: /* THIN SPACE */ |
|
case 0x200A: /* HAIR SPACE */ |
|
case 0x202f: /* NARROW NO-BREAK SPACE */ |
|
case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ |
|
case 0x3000: /* IDEOGRAPHIC SPACE */ |
|
#endif |
break; |
break; |
} |
} |
break; |
break; |
Line 5012 for (;;)
|
Line 5342 for (;;)
|
case 0x0c: /* FF */ |
case 0x0c: /* FF */ |
case 0x0d: /* CR */ |
case 0x0d: /* CR */ |
case 0x85: /* NEL */ |
case 0x85: /* NEL */ |
|
#ifdef COMPILE_PCRE16 |
|
case 0x2028: /* LINE SEPARATOR */ |
|
case 0x2029: /* PARAGRAPH SEPARATOR */ |
|
#endif |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
break; |
break; |
Line 5025 for (;;)
|
Line 5359 for (;;)
|
case 0x0c: /* FF */ |
case 0x0c: /* FF */ |
case 0x0d: /* CR */ |
case 0x0d: /* CR */ |
case 0x85: /* NEL */ |
case 0x85: /* NEL */ |
|
#ifdef COMPILE_PCRE16 |
|
case 0x2028: /* LINE SEPARATOR */ |
|
case 0x2029: /* PARAGRAPH SEPARATOR */ |
|
#endif |
break; |
break; |
} |
} |
break; |
break; |
|
|
case OP_NOT_DIGIT: |
case OP_NOT_DIGIT: |
if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); | if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); |
break; |
break; |
|
|
case OP_DIGIT: |
case OP_DIGIT: |
if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); | if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); |
break; |
break; |
|
|
case OP_NOT_WHITESPACE: |
case OP_NOT_WHITESPACE: |
if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); | if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); |
break; |
break; |
|
|
case OP_WHITESPACE: |
case OP_WHITESPACE: |
if ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); | if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); |
break; |
break; |
|
|
case OP_NOT_WORDCHAR: |
case OP_NOT_WORDCHAR: |
if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); | if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); |
break; |
break; |
|
|
case OP_WORDCHAR: |
case OP_WORDCHAR: |
if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); | if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); |
break; |
break; |
|
|
default: |
default: |
Line 5239 for (;;)
|
Line 5577 for (;;)
|
RMATCH(eptr, ecode, offset_top, md, eptrb, RM44); |
RMATCH(eptr, ecode, offset_top, md, eptrb, RM44); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (eptr-- == pp) break; /* Stop if tried at original pos */ |
if (eptr-- == pp) break; /* Stop if tried at original pos */ |
if (utf8) BACKCHAR(eptr); | if (utf) BACKCHAR(eptr); |
} |
} |
} |
} |
|
|
Line 5256 for (;;)
|
Line 5594 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
break; |
break; |
} |
} |
if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } | if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } |
if (UCD_CATEGORY(c) == ucp_M) break; |
if (UCD_CATEGORY(c) == ucp_M) break; |
eptr += len; |
eptr += len; |
while (eptr < md->end_subject) |
while (eptr < md->end_subject) |
{ |
{ |
len = 1; |
len = 1; |
if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } | if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } |
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 5279 for (;;)
|
Line 5618 for (;;)
|
if (eptr-- == pp) break; /* Stop if tried at original pos */ |
if (eptr-- == pp) break; /* Stop if tried at original pos */ |
for (;;) /* Move back over one extended */ |
for (;;) /* Move back over one extended */ |
{ |
{ |
if (!utf8) c = *eptr; else | if (!utf) c = *eptr; else |
{ |
{ |
BACKCHAR(eptr); |
BACKCHAR(eptr); |
GETCHAR(c, eptr); |
GETCHAR(c, eptr); |
Line 5293 for (;;)
|
Line 5632 for (;;)
|
else |
else |
#endif /* SUPPORT_UCP */ |
#endif /* SUPPORT_UCP */ |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
/* UTF-8 mode */ | if (utf) |
| |
if (utf8) | |
{ |
{ |
switch(ctype) |
switch(ctype) |
{ |
{ |
Line 5311 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++; |
while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; | ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
} |
} |
} |
} |
|
|
Line 5328 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++; |
while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; | ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
} |
} |
} |
} |
break; |
break; |
Line 5345 for (;;)
|
Line 5700 for (;;)
|
break; |
break; |
} |
} |
eptr++; |
eptr++; |
while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; | ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
} |
} |
} |
} |
else |
else |
Line 5578 for (;;)
|
Line 5933 for (;;)
|
} |
} |
} |
} |
else |
else |
#endif /* SUPPORT_UTF8 */ | #endif /* SUPPORT_UTF */ |
| /* Not UTF mode */ |
/* Not UTF-8 mode */ | |
{ |
{ |
switch(ctype) |
switch(ctype) |
{ |
{ |
Line 5593 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 5624 for (;;)
|
Line 5987 for (;;)
|
} |
} |
else |
else |
{ |
{ |
if (c != 0x000a && | if (c != 0x000a && (md->bsr_anycrlf || |
(md->bsr_anycrlf || | (c != 0x000b && c != 0x000c && c != 0x0085 |
(c != 0x000b && c != 0x000c && c != 0x0085))) | #ifdef COMPILE_PCRE16 |
break; | && c != 0x2028 && c != 0x2029 |
| #endif |
| ))) break; |
eptr++; |
eptr++; |
} |
} |
} |
} |
Line 5642 for (;;)
|
Line 6007 for (;;)
|
break; |
break; |
} |
} |
c = *eptr; |
c = *eptr; |
if (c == 0x09 || c == 0x20 || c == 0xa0) break; | if (c == 0x09 || c == 0x20 || c == 0xa0 |
| #ifdef COMPILE_PCRE16 |
| || c == 0x1680 || c == 0x180e || (c >= 0x2000 && c <= 0x200A) |
| || c == 0x202f || c == 0x205f || c == 0x3000 |
| #endif |
| ) break; |
eptr++; |
eptr++; |
} |
} |
break; |
break; |
Line 5656 for (;;)
|
Line 6026 for (;;)
|
break; |
break; |
} |
} |
c = *eptr; |
c = *eptr; |
if (c != 0x09 && c != 0x20 && c != 0xa0) break; | if (c != 0x09 && c != 0x20 && c != 0xa0 |
| #ifdef COMPILE_PCRE16 |
| && c != 0x1680 && c != 0x180e && (c < 0x2000 || c > 0x200A) |
| && c != 0x202f && c != 0x205f && c != 0x3000 |
| #endif |
| ) break; |
eptr++; |
eptr++; |
} |
} |
break; |
break; |
Line 5670 for (;;)
|
Line 6045 for (;;)
|
break; |
break; |
} |
} |
c = *eptr; |
c = *eptr; |
if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85) | if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85 |
break; | #ifdef COMPILE_PCRE16 |
| || c == 0x2028 || c == 0x2029 |
| #endif |
| ) break; |
eptr++; |
eptr++; |
} |
} |
break; |
break; |
Line 5685 for (;;)
|
Line 6063 for (;;)
|
break; |
break; |
} |
} |
c = *eptr; |
c = *eptr; |
if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85) | if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85 |
break; | #ifdef COMPILE_PCRE16 |
| && c != 0x2028 && c != 0x2029 |
| #endif |
| ) break; |
eptr++; |
eptr++; |
} |
} |
break; |
break; |
Line 5699 for (;;)
|
Line 6080 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
break; |
break; |
} |
} |
if ((md->ctypes[*eptr] & ctype_digit) != 0) break; | if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break; |
eptr++; |
eptr++; |
} |
} |
break; |
break; |
Line 5712 for (;;)
|
Line 6093 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
break; |
break; |
} |
} |
if ((md->ctypes[*eptr] & ctype_digit) == 0) break; | if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break; |
eptr++; |
eptr++; |
} |
} |
break; |
break; |
Line 5725 for (;;)
|
Line 6106 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
break; |
break; |
} |
} |
if ((md->ctypes[*eptr] & ctype_space) != 0) break; | if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break; |
eptr++; |
eptr++; |
} |
} |
break; |
break; |
Line 5738 for (;;)
|
Line 6119 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
break; |
break; |
} |
} |
if ((md->ctypes[*eptr] & ctype_space) == 0) break; | if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break; |
eptr++; |
eptr++; |
} |
} |
break; |
break; |
Line 5751 for (;;)
|
Line 6132 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
break; |
break; |
} |
} |
if ((md->ctypes[*eptr] & ctype_word) != 0) break; | if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break; |
eptr++; |
eptr++; |
} |
} |
break; |
break; |
Line 5764 for (;;)
|
Line 6145 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
break; |
break; |
} |
} |
if ((md->ctypes[*eptr] & ctype_word) == 0) break; | if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break; |
eptr++; |
eptr++; |
} |
} |
break; |
break; |
Line 5827 switch (frame->Xwhere)
|
Line 6208 switch (frame->Xwhere)
|
LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52) |
LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52) |
LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64) |
LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64) |
LBL(65) LBL(66) |
LBL(65) LBL(66) |
#ifdef SUPPORT_UTF8 | #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30) | LBL(21) |
| #endif |
| #ifdef SUPPORT_UTF |
| LBL(16) LBL(18) LBL(20) |
| LBL(22) LBL(23) LBL(28) LBL(30) |
LBL(32) LBL(34) LBL(42) LBL(46) |
LBL(32) LBL(34) LBL(42) LBL(46) |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45) |
LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45) |
LBL(59) LBL(60) LBL(61) LBL(62) |
LBL(59) LBL(60) LBL(61) LBL(62) |
#endif /* SUPPORT_UCP */ |
#endif /* SUPPORT_UCP */ |
#endif /* SUPPORT_UTF8 */ | #endif /* SUPPORT_UTF */ |
default: |
default: |
DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere)); |
DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere)); |
|
|
|
printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere); |
|
|
return PCRE_ERROR_INTERNAL; |
return PCRE_ERROR_INTERNAL; |
} |
} |
#undef LBL |
#undef LBL |
Line 5898 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 5923 Returns: > 0 => success; value is the number
|
Line 6336 Returns: > 0 => success; value is the number
|
< -1 => some kind of unexpected problem |
< -1 => some kind of unexpected problem |
*/ |
*/ |
|
|
|
#ifdef COMPILE_PCRE8 |
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION |
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION |
pcre_exec(const pcre *argument_re, const pcre_extra *extra_data, |
pcre_exec(const pcre *argument_re, const pcre_extra *extra_data, |
PCRE_SPTR subject, int length, int start_offset, int options, int *offsets, |
PCRE_SPTR subject, int length, int start_offset, int options, int *offsets, |
int offsetcount) |
int offsetcount) |
|
#else |
|
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION |
|
pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data, |
|
PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets, |
|
int offsetcount) |
|
#endif |
{ |
{ |
int rc, ocount, arg_offset_max; |
int rc, ocount, arg_offset_max; |
int first_byte = -1; |
|
int req_byte = -1; |
|
int req_byte2 = -1; |
|
int newline; |
int newline; |
BOOL using_temporary_offsets = FALSE; |
BOOL using_temporary_offsets = FALSE; |
BOOL anchored; |
BOOL anchored; |
BOOL startline; |
BOOL startline; |
BOOL firstline; |
BOOL firstline; |
BOOL first_byte_caseless = FALSE; | BOOL utf; |
BOOL req_byte_caseless = FALSE; | BOOL has_first_char = FALSE; |
BOOL utf8; | BOOL has_req_char = FALSE; |
| pcre_uchar first_char = 0; |
| pcre_uchar first_char2 = 0; |
| pcre_uchar req_char = 0; |
| pcre_uchar req_char2 = 0; |
match_data match_block; |
match_data match_block; |
match_data *md = &match_block; |
match_data *md = &match_block; |
const uschar *tables; | const pcre_uint8 *tables; |
const uschar *start_bits = NULL; | const pcre_uint8 *start_bits = NULL; |
USPTR start_match = (USPTR)subject + start_offset; | PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset; |
USPTR end_subject; | PCRE_PUCHAR end_subject; |
USPTR start_partial = NULL; | PCRE_PUCHAR start_partial = NULL; |
USPTR req_byte_ptr = start_match - 1; | PCRE_PUCHAR req_char_ptr = start_match - 1; |
|
|
pcre_study_data internal_study; |
|
const pcre_study_data *study; |
const pcre_study_data *study; |
|
const REAL_PCRE *re = (const REAL_PCRE *)argument_re; |
|
|
real_pcre internal_re; | #ifdef NO_RECURSE |
const real_pcre *external_re = (const real_pcre *)argument_re; | heapframe frame_zero; |
const real_pcre *re = external_re; | 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 |
|
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 && |
|
start_offset == -999) |
|
#ifdef NO_RECURSE |
|
return -((int)sizeof(heapframe)); |
|
#else |
|
return match(NULL, NULL, NULL, 0, NULL, NULL, 0); |
|
#endif |
|
|
/* Plausibility checks */ |
/* Plausibility checks */ |
|
|
if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; |
if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; |
if (re == NULL || subject == NULL || | if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0)) |
(offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL; | return PCRE_ERROR_NULL; |
if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; |
if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; |
if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET; |
if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET; |
|
|
|
/* Check that the first field in the block is the magic number. If it is not, |
|
return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to |
|
REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which |
|
means that the pattern is likely compiled with different endianness. */ |
|
|
|
if (re->magic_number != MAGIC_NUMBER) |
|
return re->magic_number == REVERSED_MAGIC_NUMBER? |
|
PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC; |
|
if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE; |
|
|
/* These two settings are used in the code for checking a UTF-8 string that |
/* These two settings are used in the code for checking a UTF-8 string that |
follows immediately afterwards. Other values in the md block are used only |
follows immediately afterwards. Other values in the md block are used only |
during "normal" pcre_exec() processing, not when the JIT support is in use, |
during "normal" pcre_exec() processing, not when the JIT support is in use, |
so they are set up later. */ |
so they are set up later. */ |
|
|
utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0; | /* PCRE_UTF16 has the same value as PCRE_UTF8. */ |
| utf = md->utf = (re->options & PCRE_UTF8) != 0; |
md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 : |
md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 : |
((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0; |
((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0; |
|
|
/* Check a UTF-8 string if required. Pass back the character offset and error |
/* Check a UTF-8 string if required. Pass back the character offset and error |
code for an invalid string if a results vector is available. */ |
code for an invalid string if a results vector is available. */ |
|
|
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0) | if (utf && (options & PCRE_NO_UTF8_CHECK) == 0) |
{ |
{ |
int erroroffset; |
int erroroffset; |
int errorcode = _pcre_valid_utf8((USPTR)subject, length, &erroroffset); | int errorcode = PRIV(valid_utf)((PCRE_PUCHAR)subject, length, &erroroffset); |
if (errorcode != 0) |
if (errorcode != 0) |
{ |
{ |
if (offsetcount >= 2) |
if (offsetcount >= 2) |
Line 5988 if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
|
Line 6436 if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
|
offsets[0] = erroroffset; |
offsets[0] = erroroffset; |
offsets[1] = errorcode; |
offsets[1] = errorcode; |
} |
} |
|
#ifdef COMPILE_PCRE16 |
|
return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)? |
|
PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16; |
|
#else |
return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)? |
return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)? |
PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; |
PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; |
|
#endif |
} |
} |
|
|
/* Check that a start_offset points to the start of a UTF-8 character. */ | /* Check that a start_offset points to the start of a UTF character. */ |
if (start_offset > 0 && start_offset < length && |
if (start_offset > 0 && start_offset < length && |
(((USPTR)subject)[start_offset] & 0xc0) == 0x80) | NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset])) |
return PCRE_ERROR_BADUTF8_OFFSET; |
return PCRE_ERROR_BADUTF8_OFFSET; |
} |
} |
#endif |
#endif |
Line 6002 if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
|
Line 6455 if (utf8 && (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 _pcre_jit_exec(re, extra_data->executable_jit, subject, length, | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0) |
start_offset, options, ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) | { |
? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount); | rc = PRIV(jit_exec)(re, extra_data, (const pcre_uchar *)subject, length, |
| 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 |
numbers associated with a given name, for condition testing. */ |
numbers associated with a given name, for condition testing. */ |
|
|
md->name_table = (uschar *)re + re->name_table_offset; | md->name_table = (pcre_uchar *)re + re->name_table_offset; |
md->name_count = re->name_count; |
md->name_count = re->name_count; |
md->name_entry_size = re->name_entry_size; |
md->name_entry_size = re->name_entry_size; |
|
|
Line 6034 md->callout_data = NULL;
|
Line 6493 md->callout_data = NULL;
|
|
|
/* The table pointer is always in native byte order. */ |
/* The table pointer is always in native byte order. */ |
|
|
tables = external_re->tables; | tables = re->tables; |
|
|
if (extra_data != NULL) |
if (extra_data != NULL) |
{ |
{ |
Line 6054 if (extra_data != NULL)
|
Line 6513 if (extra_data != NULL)
|
is a feature that makes it possible to save compiled regex and re-use them |
is a feature that makes it possible to save compiled regex and re-use them |
in other programs later. */ |
in other programs later. */ |
|
|
if (tables == NULL) tables = _pcre_default_tables; | if (tables == NULL) tables = PRIV(default_tables); |
|
|
/* Check that the first field in the block is the magic number. If it is not, |
|
test for a regex that was compiled on a host of opposite endianness. If this is |
|
the case, flipped values are put in internal_re and internal_study if there was |
|
study data too. */ |
|
|
|
if (re->magic_number != MAGIC_NUMBER) |
|
{ |
|
re = _pcre_try_flipped(re, &internal_re, study, &internal_study); |
|
if (re == NULL) return PCRE_ERROR_BADMAGIC; |
|
if (study != NULL) study = &internal_study; |
|
} |
|
|
|
/* Set up other data */ |
/* Set up other data */ |
|
|
anchored = ((re->options | options) & PCRE_ANCHORED) != 0; |
anchored = ((re->options | options) & PCRE_ANCHORED) != 0; |
Line 6076 firstline = (re->options & PCRE_FIRSTLINE) != 0;
|
Line 6523 firstline = (re->options & PCRE_FIRSTLINE) != 0;
|
|
|
/* The code starts after the real_pcre block and the capture name table. */ |
/* The code starts after the real_pcre block and the capture name table. */ |
|
|
md->start_code = (const uschar *)external_re + re->name_table_offset + | md->start_code = (const pcre_uchar *)re + re->name_table_offset + |
re->name_count * re->name_entry_size; |
re->name_count * re->name_entry_size; |
|
|
md->start_subject = (USPTR)subject; | md->start_subject = (PCRE_PUCHAR)subject; |
md->start_offset = start_offset; |
md->start_offset = start_offset; |
md->end_subject = md->start_subject + length; |
md->end_subject = md->start_subject + length; |
end_subject = md->end_subject; |
end_subject = md->end_subject; |
Line 6104 md->recursive = NULL; /* No recursio
|
Line 6551 md->recursive = NULL; /* No recursio
|
md->hasthen = (re->flags & PCRE_HASTHEN) != 0; |
md->hasthen = (re->flags & PCRE_HASTHEN) != 0; |
|
|
md->lcc = tables + lcc_offset; |
md->lcc = tables + lcc_offset; |
|
md->fcc = tables + fcc_offset; |
md->ctypes = tables + ctypes_offset; |
md->ctypes = tables + ctypes_offset; |
|
|
/* Handle different \R options. */ |
/* Handle different \R options. */ |
Line 6190 arg_offset_max = (2*ocount)/3;
|
Line 6638 arg_offset_max = (2*ocount)/3;
|
if (re->top_backref > 0 && re->top_backref >= ocount/3) |
if (re->top_backref > 0 && re->top_backref >= ocount/3) |
{ |
{ |
ocount = re->top_backref * 3 + 3; |
ocount = re->top_backref * 3 + 3; |
md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int)); | md->offset_vector = (int *)(PUBL(malloc))(ocount * sizeof(int)); |
if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY; |
if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY; |
using_temporary_offsets = TRUE; |
using_temporary_offsets = TRUE; |
DPRINTF(("Got memory to hold back references\n")); |
DPRINTF(("Got memory to hold back references\n")); |
Line 6217 if (md->offset_vector != NULL)
|
Line 6665 if (md->offset_vector != NULL)
|
md->offset_vector[0] = md->offset_vector[1] = -1; |
md->offset_vector[0] = md->offset_vector[1] = -1; |
} |
} |
|
|
/* Set up the first character to match, if available. The first_byte value is | /* Set up the first character to match, if available. The first_char value is |
never set for an anchored regular expression, but the anchoring may be forced |
never set for an anchored regular expression, but the anchoring may be forced |
at run time, so we have to test for anchoring. The first char may be unset for |
at run time, so we have to test for anchoring. The first char may be unset for |
an unanchored pattern, of course. If there's no first char and the pattern was |
an unanchored pattern, of course. If there's no first char and the pattern was |
Line 6227 if (!anchored)
|
Line 6675 if (!anchored)
|
{ |
{ |
if ((re->flags & PCRE_FIRSTSET) != 0) |
if ((re->flags & PCRE_FIRSTSET) != 0) |
{ |
{ |
first_byte = re->first_byte & 255; | has_first_char = TRUE; |
if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE) | first_char = first_char2 = (pcre_uchar)(re->first_char); |
first_byte = md->lcc[first_byte]; | if ((re->flags & PCRE_FCH_CASELESS) != 0) |
| { |
| first_char2 = TABLE_GET(first_char, md->fcc, first_char); |
| #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) |
| if (utf && first_char > 127) |
| first_char2 = UCD_OTHERCASE(first_char); |
| #endif |
| } |
} |
} |
else |
else |
if (!startline && study != NULL && |
if (!startline && study != NULL && |
Line 6242 character" set. */
|
Line 6697 character" set. */
|
|
|
if ((re->flags & PCRE_REQCHSET) != 0) |
if ((re->flags & PCRE_REQCHSET) != 0) |
{ |
{ |
req_byte = re->req_byte & 255; | has_req_char = TRUE; |
req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0; | req_char = req_char2 = (pcre_uchar)(re->req_char); |
req_byte2 = (tables + fcc_offset)[req_byte]; /* case flipped */ | if ((re->flags & PCRE_RCH_CASELESS) != 0) |
| { |
| req_char2 = TABLE_GET(req_char, md->fcc, req_char); |
| #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) |
| if (utf && req_char > 127) |
| req_char2 = UCD_OTHERCASE(req_char); |
| #endif |
| } |
} |
} |
|
|
|
|
|
|
|
|
/* ==========================================================================*/ |
/* ==========================================================================*/ |
|
|
/* Loop for handling unanchored repeated matching attempts; for anchored regexs |
/* Loop for handling unanchored repeated matching attempts; for anchored regexs |
Line 6257 the loop runs just once. */
|
Line 6717 the loop runs just once. */
|
|
|
for(;;) |
for(;;) |
{ |
{ |
USPTR save_end_subject = end_subject; | PCRE_PUCHAR save_end_subject = end_subject; |
USPTR new_start_match; | PCRE_PUCHAR new_start_match; |
|
|
/* If firstline is TRUE, the start of the match is constrained to the first |
/* If firstline is TRUE, the start of the match is constrained to the first |
line of a multiline string. That is, the match must be before or at the first |
line of a multiline string. That is, the match must be before or at the first |
Line 6268 for(;;)
|
Line 6728 for(;;)
|
|
|
if (firstline) |
if (firstline) |
{ |
{ |
USPTR t = start_match; | PCRE_PUCHAR t = start_match; |
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
if (utf8) | if (utf) |
{ |
{ |
while (t < md->end_subject && !IS_NEWLINE(t)) |
while (t < md->end_subject && !IS_NEWLINE(t)) |
{ |
{ |
t++; |
t++; |
while (t < end_subject && (*t & 0xc0) == 0x80) t++; | ACROSSCHAR(t < end_subject, *t, t++); |
} |
} |
} |
} |
else |
else |
Line 6292 for(;;)
|
Line 6752 for(;;)
|
|
|
if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0) |
if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0) |
{ |
{ |
/* Advance to a unique first byte if there is one. */ | /* Advance to a unique first char if there is one. */ |
|
|
if (first_byte >= 0) | if (has_first_char) |
{ |
{ |
if (first_byte_caseless) | if (first_char != first_char2) |
while (start_match < end_subject && md->lcc[*start_match] != first_byte) | while (start_match < end_subject && |
| *start_match != first_char && *start_match != first_char2) |
start_match++; |
start_match++; |
else |
else |
while (start_match < end_subject && *start_match != first_byte) | while (start_match < end_subject && *start_match != first_char) |
start_match++; |
start_match++; |
} |
} |
|
|
Line 6310 for(;;)
|
Line 6771 for(;;)
|
{ |
{ |
if (start_match > md->start_subject + start_offset) |
if (start_match > md->start_subject + start_offset) |
{ |
{ |
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
if (utf8) | if (utf) |
{ |
{ |
while (start_match < end_subject && !WAS_NEWLINE(start_match)) |
while (start_match < end_subject && !WAS_NEWLINE(start_match)) |
{ |
{ |
start_match++; |
start_match++; |
while(start_match < end_subject && (*start_match & 0xc0) == 0x80) | ACROSSCHAR(start_match < end_subject, *start_match, |
start_match++; | start_match++); |
} |
} |
} |
} |
else |
else |
Line 6344 for(;;)
|
Line 6805 for(;;)
|
while (start_match < end_subject) |
while (start_match < end_subject) |
{ |
{ |
register unsigned int c = *start_match; |
register unsigned int c = *start_match; |
|
#ifndef COMPILE_PCRE8 |
|
if (c > 255) c = 255; |
|
#endif |
if ((start_bits[c/8] & (1 << (c&7))) == 0) |
if ((start_bits[c/8] & (1 << (c&7))) == 0) |
{ |
{ |
start_match++; |
start_match++; |
#ifdef SUPPORT_UTF8 | #if defined SUPPORT_UTF && defined COMPILE_PCRE8 |
if (utf8) | /* In non 8-bit mode, the iteration will stop for |
while(start_match < end_subject && (*start_match & 0xc0) == 0x80) | characters > 255 at the beginning or not stop at all. */ |
start_match++; | if (utf) |
| ACROSSCHAR(start_match < end_subject, *start_match, |
| start_match++); |
#endif |
#endif |
} |
} |
else break; |
else break; |
Line 6379 for(;;)
|
Line 6845 for(;;)
|
break; |
break; |
} |
} |
|
|
/* If req_byte is set, we know that that character must appear in the | /* If req_char is set, we know that that character must appear in the |
subject for the match to succeed. If the first character is set, req_byte | subject for the match to succeed. If the first character is set, req_char |
must be later in the subject; otherwise the test starts at the match point. |
must be later in the subject; otherwise the test starts at the match point. |
This optimization can save a huge amount of backtracking in patterns with |
This optimization can save a huge amount of backtracking in patterns with |
nested unlimited repeats that aren't going to match. Writing separate code |
nested unlimited repeats that aren't going to match. Writing separate code |
Line 6393 for(;;)
|
Line 6859 for(;;)
|
32-megabyte string... so we don't do this when the string is sufficiently |
32-megabyte string... so we don't do this when the string is sufficiently |
long. */ |
long. */ |
|
|
if (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX) | if (has_req_char && end_subject - start_match < REQ_BYTE_MAX) |
{ |
{ |
register USPTR p = start_match + ((first_byte >= 0)? 1 : 0); | register PCRE_PUCHAR p = start_match + (has_first_char? 1:0); |
|
|
/* We don't need to repeat the search if we haven't yet reached the |
/* We don't need to repeat the search if we haven't yet reached the |
place we found it at last time. */ |
place we found it at last time. */ |
|
|
if (p > req_byte_ptr) | if (p > req_char_ptr) |
{ |
{ |
if (req_byte_caseless) | if (req_char != req_char2) |
{ |
{ |
while (p < end_subject) |
while (p < end_subject) |
{ |
{ |
register int pp = *p++; |
register int pp = *p++; |
if (pp == req_byte || pp == req_byte2) { p--; break; } | if (pp == req_char || pp == req_char2) { p--; break; } |
} |
} |
} |
} |
else |
else |
{ |
{ |
while (p < end_subject) |
while (p < end_subject) |
{ |
{ |
if (*p++ == req_byte) { p--; break; } | if (*p++ == req_char) { p--; break; } |
} |
} |
} |
} |
|
|
Line 6431 for(;;)
|
Line 6897 for(;;)
|
found it, so that we don't search again next time round the loop if |
found it, so that we don't search again next time round the loop if |
the start hasn't passed this character yet. */ |
the start hasn't passed this character yet. */ |
|
|
req_byte_ptr = p; | req_char_ptr = p; |
} |
} |
} |
} |
} |
} |
Line 6486 for(;;)
|
Line 6952 for(;;)
|
case MATCH_THEN: |
case MATCH_THEN: |
md->ignore_skip_arg = FALSE; |
md->ignore_skip_arg = FALSE; |
new_start_match = start_match + 1; |
new_start_match = start_match + 1; |
#ifdef SUPPORT_UTF8 | #ifdef SUPPORT_UTF |
if (utf8) | if (utf) |
while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80) | ACROSSCHAR(new_start_match < end_subject, *new_start_match, |
new_start_match++; | new_start_match++); |
#endif |
#endif |
break; |
break; |
|
|
Line 6527 for(;;)
|
Line 6993 for(;;)
|
|
|
/* If we have just passed a CR and we are now at a LF, and the pattern does |
/* If we have just passed a CR and we are now at a LF, and the pattern does |
not contain any explicit matches for \r or \n, and the newline option is CRLF |
not contain any explicit matches for \r or \n, and the newline option is CRLF |
or ANY or ANYCRLF, advance the match position by one more character. */ | or ANY or ANYCRLF, advance the match position by one more character. In |
| normal matching start_match will aways be greater than the first position at |
| this stage, but a failed *SKIP can cause a return at the same point, which is |
| why the first test exists. */ |
|
|
if (start_match[-1] == CHAR_CR && | if (start_match > (PCRE_PUCHAR)subject + start_offset && |
| start_match[-1] == CHAR_CR && |
start_match < end_subject && |
start_match < end_subject && |
*start_match == CHAR_NL && |
*start_match == CHAR_NL && |
(re->flags & PCRE_HASCRORLF) == 0 && |
(re->flags & PCRE_HASCRORLF) == 0 && |
Line 6575 if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
|
Line 7045 if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
|
} |
} |
if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE; |
if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE; |
DPRINTF(("Freeing temporary memory\n")); |
DPRINTF(("Freeing temporary memory\n")); |
(pcre_free)(md->offset_vector); | (PUBL(free))(md->offset_vector); |
} |
} |
|
|
/* Set the return code to the number of captured strings, or 0 if there were |
/* Set the return code to the number of captured strings, or 0 if there were |
Line 6597 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 6616 if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
|
Line 7086 if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
|
/* Return MARK data if requested */ |
/* Return MARK data if requested */ |
|
|
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) = (unsigned char *)(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 6627 attempt has failed at all permitted starting positions
|
Line 7100 attempt has failed at all permitted starting positions
|
if (using_temporary_offsets) |
if (using_temporary_offsets) |
{ |
{ |
DPRINTF(("Freeing temporary memory\n")); |
DPRINTF(("Freeing temporary memory\n")); |
(pcre_free)(md->offset_vector); | (PUBL(free))(md->offset_vector); |
} |
} |
|
|
/* For anything other than nomatch or partial match, just return the code. */ |
/* For anything other than nomatch or partial match, just return the code. */ |
Line 6635 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 6646 if (start_partial != NULL)
|
Line 7122 if (start_partial != NULL)
|
md->mark = NULL; |
md->mark = NULL; |
if (offsetcount > 1) |
if (offsetcount > 1) |
{ |
{ |
offsets[0] = (int)(start_partial - (USPTR)subject); | offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject); |
offsets[1] = (int)(end_subject - (USPTR)subject); | offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject); |
} |
} |
rc = PCRE_ERROR_PARTIAL; |
rc = PCRE_ERROR_PARTIAL; |
} |
} |
Line 6663 else
|
Line 7139 else
|
/* Return the MARK data if it has been requested. */ |
/* Return the MARK data if it has been requested. */ |
|
|
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) = (unsigned char *)(md->nomatch_mark); | *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark; |
| #ifdef NO_RECURSE |
| release_match_heapframes(&frame_zero); |
| #endif |
return rc; |
return rc; |
} |
} |
|
|