version 1.1.1.1, 2012/02/21 23:05:51
|
version 1.1.1.2, 2012/02/21 23:50:25
|
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 113 Returns: nothing
|
Line 113 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 144 Returns: < 0 if not matched, otherwise the number
|
Line 144 Returns: < 0 if not matched, otherwise the number
|
*/ |
*/ |
|
|
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 173 ASCII characters. */
|
Line 173 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 185 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; |
Line 204 if (caseless)
|
Line 204 if (caseless)
|
{ |
{ |
if (eptr + length > md->end_subject) return -1; |
if (eptr + length > md->end_subject) return -1; |
while (length-- > 0) |
while (length-- > 0) |
{ if (md->lcc[*p++] != md->lcc[*eptr++]) return -1; } | { |
| if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1; |
| p++; |
| eptr++; |
| } |
} |
} |
} |
} |
|
|
Line 307 argument of match(), which never changes. */
|
Line 311 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 = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\ |
if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\ |
if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\ |
frame->Xwhere = rw; \ |
frame->Xwhere = rw; \ |
newframe->Xeptr = ra;\ |
newframe->Xeptr = ra;\ |
Line 328 argument of match(), which never changes. */
|
Line 332 argument of match(), which never changes. */
|
{\ |
{\ |
heapframe *oldframe = frame;\ |
heapframe *oldframe = frame;\ |
frame = oldframe->Xprevframe;\ |
frame = oldframe->Xprevframe;\ |
(pcre_stack_free)(oldframe);\ | if (oldframe != &frame_zero) (PUBL(stack_free))(oldframe);\ |
if (frame != NULL)\ |
if (frame != NULL)\ |
{\ |
{\ |
rrc = ra;\ |
rrc = ra;\ |
Line 345 typedef struct heapframe {
|
Line 349 typedef struct heapframe {
|
|
|
/* 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 379 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 444 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 467 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 478 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_zero; |
if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY); | heapframe *frame = &frame_zero; |
frame->Xprevframe = NULL; /* Marks the top level */ |
frame->Xprevframe = NULL; /* Marks the top level */ |
|
|
/* Copy in the original argument variables */ |
/* Copy in the original argument variables */ |
Line 513 HEAP_RECURSE:
|
Line 520 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 578 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 599 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 615 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 644 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 671 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 715 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 728 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 741 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 752 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 760 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 770 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 784 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 805 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 814 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 838 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 857 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 909 for (;;)
|
Line 937 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 946 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 974 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 1004 for (;;)
|
Line 1034 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 1059 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 1070 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 1125 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 1197 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 1247 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 1267 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 1296 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 1309 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 1329 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 1342 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 1359 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 1373 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 1395 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 1410 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 1502 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 1549 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 1534 for (;;)
|
Line 1571 for (;;)
|
|
|
if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); |
ecode += GET(ecode, 1); |
ecode += GET(ecode, 1); |
|
md->mark = save_mark; |
} |
} |
while (*ecode == OP_ALT); |
while (*ecode == OP_ALT); |
|
|
Line 1557 for (;;)
|
Line 1595 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 1606 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 1633 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 1665 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 1685 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 1744 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 1759 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 1768 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 1742 for (;;)
|
Line 1786 for (;;)
|
{ |
{ |
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 1798 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 2066 for (;;)
|
Line 2110 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 2183 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 2207 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 2186 for (;;)
|
Line 2232 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 2259 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 2276 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 2293 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 2310 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 2327 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 2344 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 2475 for (;;)
|
Line 2523 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 2540 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 2561 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 2591 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; |
} |
} |
Line 2564 for (;;)
|
Line 2612 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 2652 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 2620 for (;;)
|
Line 2668 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 2703 for (;;)
|
Line 2755 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 2780 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 2792 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 2808 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 2823 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 2844 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 2863 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 2881 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 2900 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 2917 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 2930 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 2940 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 2960 for (;;)
|
|
|
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
} |
} |
|
#undef BYTE_MAP |
} |
} |
/* Control never gets here */ |
/* Control never gets here */ |
|
|
Line 2901 for (;;)
|
Line 2969 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 2994 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 3014 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 3038 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 3056 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 3069 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 3083 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 3098 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 3120 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 3134 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 3163 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 3179 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 3194 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 3242 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 3259 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 3289 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 3310 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 3346 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 3288 for (;;)
|
Line 3364 for (;;)
|
|
|
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 3388 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 3404 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 3419 for (;;)
|
SCHECK_PARTIAL(); |
SCHECK_PARTIAL(); |
break; |
break; |
} |
} |
if (fc != md->lcc[*eptr]) break; | if (fc != *eptr && foc != *eptr) break; |
eptr++; |
eptr++; |
} |
} |
|
|
Line 3414 for (;;)
|
Line 3508 for (;;)
|
GETCHARINCTEST(c, eptr); |
GETCHARINCTEST(c, eptr); |
if (op == OP_NOTI) /* The caseless case */ |
if (op == OP_NOTI) /* The caseless case */ |
{ |
{ |
#ifdef SUPPORT_UTF8 | register unsigned int ch, och; |
if (c < 256) | ch = *ecode++; |
#endif | #ifdef COMPILE_PCRE8 |
c = md->lcc[c]; | /* ch must be < 128 if UTF is enabled. */ |
if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH); | och = md->fcc[ch]; |
| #else |
| #ifdef SUPPORT_UTF |
| #ifdef SUPPORT_UCP |
| if (utf && ch > 127) |
| och = UCD_OTHERCASE(ch); |
| #else |
| if (utf && ch > 127) |
| och = ch; |
| #endif /* SUPPORT_UCP */ |
| else |
| #endif /* SUPPORT_UTF */ |
| och = TABLE_GET(ch, md->fcc, ch); |
| #endif /* COMPILE_PCRE8 */ |
| if (ch == c || och == c) RRETURN(MATCH_NOMATCH); |
} |
} |
else /* Caseful */ |
else /* Caseful */ |
{ |
{ |
Line 3436 for (;;)
|
Line 3544 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 3554 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 3586 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 3517 for (;;)
|
Line 3625 for (;;)
|
|
|
if (op >= OP_NOTSTARI) /* Caseless */ |
if (op >= OP_NOTSTARI) /* 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 */ |
|
|
#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 3654 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 3668 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 3677 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 3692 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 3709 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 3722 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 3735 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 3749 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 3758 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 3779 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 3796 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 3813 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 3833 for (;;)
|
} |
} |
else |
else |
#endif |
#endif |
/* Not UTF-8 mode */ | /* Not UTF mode */ |
{ |
{ |
for (fi = min;; fi++) |
for (fi = min;; fi++) |
{ |
{ |
Line 3741 for (;;)
|
Line 3857 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 3884 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 3917 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 3925 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 3953 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 4160 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; |
} |
} |
Line 4057 for (;;)
|
Line 4172 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 4070 for (;;)
|
Line 4185 for (;;)
|
} |
} |
if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); |
if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); |
eptr++; |
eptr++; |
while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; | ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
} |
} |
break; |
break; |
|
|
Line 4083 for (;;)
|
Line 4198 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 4380 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 4397 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 4410 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 4427 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 4440 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 4452 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 4392 for (;;)
|
Line 4512 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 4536 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 4573 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 4612 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 4637 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 4654 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 4668 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 4682 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 4696 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 4710 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 4724 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 4944 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; |
} |
} |
Line 4775 for (;;)
|
Line 4953 for (;;)
|
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 4919 for (;;)
|
Line 5096 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 5117 for (;;)
|
} |
} |
else |
else |
#endif |
#endif |
/* Not UTF-8 mode */ | /* Not UTF mode */ |
{ |
{ |
for (fi = min;; fi++) |
for (fi = min;; fi++) |
{ |
{ |
Line 4976 for (;;)
|
Line 5153 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 5169 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 5198 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 5229 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 5246 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 5464 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 5481 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; |
} |
} |
Line 5279 for (;;)
|
Line 5504 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 5518 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 5312 for (;;)
|
Line 5535 for (;;)
|
} |
} |
if (IS_NEWLINE(eptr)) break; |
if (IS_NEWLINE(eptr)) break; |
eptr++; |
eptr++; |
while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; | ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
} |
} |
} |
} |
|
|
Line 5329 for (;;)
|
Line 5552 for (;;)
|
} |
} |
if (IS_NEWLINE(eptr)) break; |
if (IS_NEWLINE(eptr)) break; |
eptr++; |
eptr++; |
while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; | ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); |
} |
} |
} |
} |
break; |
break; |
Line 5345 for (;;)
|
Line 5568 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 5801 for (;;)
|
} |
} |
} |
} |
else |
else |
#endif /* SUPPORT_UTF8 */ | #endif /* SUPPORT_UTF */ |
| /* Not UTF mode */ |
/* Not UTF-8 mode */ | |
{ |
{ |
switch(ctype) |
switch(ctype) |
{ |
{ |
Line 5624 for (;;)
|
Line 5846 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 5866 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 5885 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 5904 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 5922 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 5939 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 5952 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 5965 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 5978 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 5991 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 6004 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 6067 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 5923 Returns: > 0 => success; value is the number
|
Line 6170 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; | /* Check for the special magic call that measures the size of the stack used |
const real_pcre *external_re = (const real_pcre *)argument_re; | per recursive call of match(). */ |
const real_pcre *re = external_re; | |
|
|
|
if (re == NULL && extra_data == NULL && subject == NULL && length == -999 && |
|
start_offset == -999) |
|
#ifdef NO_RECURSE |
|
return -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 6261 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 6012 if (extra_data != NULL
|
Line 6290 if (extra_data != NULL
|
&& (extra_data->flags & PCRE_EXTRA_TABLES) == 0 |
&& (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)) == 0) |
return _pcre_jit_exec(re, extra_data->executable_jit, subject, length, | return PRIV(jit_exec)(re, extra_data->executable_jit, |
start_offset, options, ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) | (const pcre_uchar *)subject, length, start_offset, options, |
| ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) |
? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount); |
? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount); |
#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 6313 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 6333 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 6343 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 6371 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 6458 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 6485 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 6495 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 6517 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 6537 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 6548 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 6572 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 6591 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 6625 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 6665 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 6679 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 6717 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 6772 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 6813 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 6865 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 6616 if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
|
Line 6906 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)); |
return rc; |
return rc; |
} |
} |
Line 6627 attempt has failed at all permitted starting positions
|
Line 6917 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 6646 if (start_partial != NULL)
|
Line 6936 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 6953 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; |
return rc; |
return rc; |
} |
} |
|
|