| 487 |
/* 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 |
| 488 |
preserved over calls to RMATCH() are part of a "frame". We set up the top-level |
preserved over calls to RMATCH() are part of a "frame". We set up the top-level |
| 489 |
frame on the stack here; subsequent instantiations are obtained from the heap |
frame on the stack here; subsequent instantiations are obtained from the heap |
| 490 |
whenever RMATCH() does a "recursion". See the macro definitions above. Putting |
whenever RMATCH() does a "recursion". See the macro definitions above. Putting |
| 491 |
the top-level on the stack rather than malloc-ing them all gives a performance |
the top-level on the stack rather than malloc-ing them all gives a performance |
| 492 |
boost in many cases where there is not much "recursion". */ |
boost in many cases where there is not much "recursion". */ |
| 493 |
|
|
| 494 |
#ifdef NO_RECURSE |
#ifdef NO_RECURSE |
| 495 |
heapframe frame_zero; |
heapframe frame_zero; |
| 496 |
heapframe *frame = &frame_zero; |
heapframe *frame = &frame_zero; |
| 497 |
frame->Xprevframe = NULL; /* Marks the top level */ |
frame->Xprevframe = NULL; /* Marks the top level */ |
| 498 |
|
|
| 499 |
/* Copy in the original argument variables */ |
/* Copy in the original argument variables */ |
| 616 |
|
|
| 617 |
eptrblock newptrb; |
eptrblock newptrb; |
| 618 |
|
|
| 619 |
/* There is a special fudge for calling match() in a way that causes it to |
/* There is a special fudge for calling match() in a way that causes it to |
| 620 |
measure the size of its basic stack frame when the stack is being used for |
measure the size of its basic stack frame when the stack is being used for |
| 621 |
recursion. The second argument (ecode) being NULL triggers this behaviour. It |
recursion. The second argument (ecode) being NULL triggers this behaviour. It |
| 622 |
cannot normally every be NULL. The return is the negated value of the frame |
cannot normally ever be NULL. The return is the negated value of the frame |
| 623 |
size. */ |
size. */ |
| 624 |
|
|
| 625 |
if (ecode == NULL) |
if (ecode == NULL) |
| 631 |
int len = (char *)&rdepth - (char *)eptr; |
int len = (char *)&rdepth - (char *)eptr; |
| 632 |
return (len > 0)? -len : len; |
return (len > 0)? -len : len; |
| 633 |
} |
} |
| 634 |
} |
} |
| 635 |
#endif /* NO_RECURSE */ |
#endif /* NO_RECURSE */ |
| 636 |
|
|
| 637 |
/* 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 |
| 838 |
case OP_ONCE_NC: |
case OP_ONCE_NC: |
| 839 |
prev = ecode; |
prev = ecode; |
| 840 |
saved_eptr = eptr; |
saved_eptr = eptr; |
| 841 |
save_mark = md->mark; |
save_mark = md->mark; |
| 842 |
do |
do |
| 843 |
{ |
{ |
| 844 |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64); |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64); |
| 857 |
|
|
| 858 |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH) RRETURN(rrc); |
| 859 |
ecode += GET(ecode,1); |
ecode += GET(ecode,1); |
| 860 |
md->mark = save_mark; |
md->mark = save_mark; |
| 861 |
} |
} |
| 862 |
while (*ecode == OP_ALT); |
while (*ecode == OP_ALT); |
| 863 |
|
|
| 937 |
save_offset2 = md->offset_vector[offset+1]; |
save_offset2 = md->offset_vector[offset+1]; |
| 938 |
save_offset3 = md->offset_vector[md->offset_end - number]; |
save_offset3 = md->offset_vector[md->offset_end - number]; |
| 939 |
save_capture_last = md->capture_last; |
save_capture_last = md->capture_last; |
| 940 |
save_mark = md->mark; |
save_mark = md->mark; |
| 941 |
|
|
| 942 |
DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); |
DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); |
| 943 |
md->offset_vector[md->offset_end - number] = |
md->offset_vector[md->offset_end - number] = |
| 1043 |
save_mark = md->mark; |
save_mark = md->mark; |
| 1044 |
RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, |
RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb, |
| 1045 |
RM2); |
RM2); |
| 1046 |
|
|
| 1047 |
/* See comment in the code for capturing groups above about handling |
/* See comment in the code for capturing groups above about handling |
| 1048 |
THEN. */ |
THEN. */ |
| 1049 |
|
|
| 1070 |
RRETURN(rrc); |
RRETURN(rrc); |
| 1071 |
} |
} |
| 1072 |
ecode += GET(ecode, 1); |
ecode += GET(ecode, 1); |
| 1073 |
md->mark = save_mark; |
md->mark = save_mark; |
| 1074 |
if (*ecode != OP_ALT) break; |
if (*ecode != OP_ALT) break; |
| 1075 |
} |
} |
| 1076 |
|
|
| 1549 |
|
|
| 1550 |
case OP_ASSERT: |
case OP_ASSERT: |
| 1551 |
case OP_ASSERTBACK: |
case OP_ASSERTBACK: |
| 1552 |
save_mark = md->mark; |
save_mark = md->mark; |
| 1553 |
if (md->match_function_type == MATCH_CONDASSERT) |
if (md->match_function_type == MATCH_CONDASSERT) |
| 1554 |
{ |
{ |
| 1555 |
condassert = TRUE; |
condassert = TRUE; |
| 1571 |
|
|
| 1572 |
if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); |
if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); |
| 1573 |
ecode += GET(ecode, 1); |
ecode += GET(ecode, 1); |
| 1574 |
md->mark = save_mark; |
md->mark = save_mark; |
| 1575 |
} |
} |
| 1576 |
while (*ecode == OP_ALT); |
while (*ecode == OP_ALT); |
| 1577 |
|
|
| 1595 |
|
|
| 1596 |
case OP_ASSERT_NOT: |
case OP_ASSERT_NOT: |
| 1597 |
case OP_ASSERTBACK_NOT: |
case OP_ASSERTBACK_NOT: |
| 1598 |
save_mark = md->mark; |
save_mark = md->mark; |
| 1599 |
if (md->match_function_type == MATCH_CONDASSERT) |
if (md->match_function_type == MATCH_CONDASSERT) |
| 1600 |
{ |
{ |
| 1601 |
condassert = TRUE; |
condassert = TRUE; |
| 1606 |
do |
do |
| 1607 |
{ |
{ |
| 1608 |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5); |
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5); |
| 1609 |
md->mark = save_mark; |
md->mark = save_mark; |
| 1610 |
if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH); |
if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH); |
| 1611 |
if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT) |
if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT) |
| 1612 |
{ |
{ |
| 3508 |
GETCHARINCTEST(c, eptr); |
GETCHARINCTEST(c, eptr); |
| 3509 |
if (op == OP_NOTI) /* The caseless case */ |
if (op == OP_NOTI) /* The caseless case */ |
| 3510 |
{ |
{ |
| 3511 |
register int ch, och; |
register unsigned int ch, och; |
| 3512 |
ch = *ecode++; |
ch = *ecode++; |
| 3513 |
#ifdef COMPILE_PCRE8 |
#ifdef COMPILE_PCRE8 |
| 3514 |
/* ch must be < 128 if UTF is enabled. */ |
/* ch must be < 128 if UTF is enabled. */ |
| 3654 |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
| 3655 |
} |
} |
| 3656 |
GETCHARINC(d, eptr); |
GETCHARINC(d, eptr); |
| 3657 |
if (fc == d || foc == d) RRETURN(MATCH_NOMATCH); |
if (fc == d || (unsigned int) foc == d) RRETURN(MATCH_NOMATCH); |
| 3658 |
} |
} |
| 3659 |
} |
} |
| 3660 |
else |
else |
| 3692 |
RRETURN(MATCH_NOMATCH); |
RRETURN(MATCH_NOMATCH); |
| 3693 |
} |
} |
| 3694 |
GETCHARINC(d, eptr); |
GETCHARINC(d, eptr); |
| 3695 |
if (fc == d || foc == d) RRETURN(MATCH_NOMATCH); |
if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH); |
| 3696 |
} |
} |
| 3697 |
} |
} |
| 3698 |
else |
else |
| 3735 |
break; |
break; |
| 3736 |
} |
} |
| 3737 |
GETCHARLEN(d, eptr, len); |
GETCHARLEN(d, eptr, len); |
| 3738 |
if (fc == d || foc == d) break; |
if (fc == d || (unsigned int)foc == d) break; |
| 3739 |
eptr += len; |
eptr += len; |
| 3740 |
} |
} |
| 3741 |
if (possessive) continue; |
if (possessive) continue; |
| 6207 |
const pcre_study_data *study; |
const pcre_study_data *study; |
| 6208 |
const REAL_PCRE *re = (const REAL_PCRE *)argument_re; |
const REAL_PCRE *re = (const REAL_PCRE *)argument_re; |
| 6209 |
|
|
| 6210 |
/* Check for the special magic call that measures the size of the stack used |
/* Check for the special magic call that measures the size of the stack used |
| 6211 |
per recursive call of match(). */ |
per recursive call of match(). Without the funny casting for sizeof, a Windows |
| 6212 |
|
compiler gave this error: "unary minus operator applied to unsigned type, |
| 6213 |
|
result still unsigned". Hopefully the cast fixes that. */ |
| 6214 |
|
|
| 6215 |
if (re == NULL && extra_data == NULL && subject == NULL && length == -1) |
if (re == NULL && extra_data == NULL && subject == NULL && length == -999 && |
| 6216 |
|
start_offset == -999) |
| 6217 |
#ifdef NO_RECURSE |
#ifdef NO_RECURSE |
| 6218 |
return -sizeof(heapframe); |
return -((int)sizeof(heapframe)); |
| 6219 |
#else |
#else |
| 6220 |
return match(NULL, NULL, NULL, 0, NULL, NULL, 0); |
return match(NULL, NULL, NULL, 0, NULL, NULL, 0); |
| 6221 |
#endif |
#endif |
| 6222 |
|
|
| 6223 |
/* Plausibility checks */ |
/* Plausibility checks */ |
| 6224 |
|
|
| 6225 |
if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; |
if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; |
| 6226 |
if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0)) |
if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0)) |
| 6227 |
return PCRE_ERROR_NULL; |
return PCRE_ERROR_NULL; |
| 6228 |
if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; |
if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; |
| 6229 |
if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET; |
if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET; |
| 6287 |
|
|
| 6288 |
#ifdef SUPPORT_JIT |
#ifdef SUPPORT_JIT |
| 6289 |
if (extra_data != NULL |
if (extra_data != NULL |
| 6290 |
&& (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 |
&& (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT | |
| 6291 |
|
PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT |
| 6292 |
&& extra_data->executable_jit != NULL |
&& extra_data->executable_jit != NULL |
|
&& (extra_data->flags & PCRE_EXTRA_TABLES) == 0 |
|
| 6293 |
&& (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL | |
&& (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL | |
| 6294 |
PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0) |
PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | |
| 6295 |
return PRIV(jit_exec)(re, extra_data->executable_jit, |
PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0) |
| 6296 |
|
{ |
| 6297 |
|
rc = PRIV(jit_exec)(re, extra_data->executable_jit, |
| 6298 |
(const pcre_uchar *)subject, length, start_offset, options, |
(const pcre_uchar *)subject, length, start_offset, options, |
| 6299 |
((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) |
((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) |
| 6300 |
? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount); |
? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount); |
| 6301 |
|
/* PCRE_ERROR_NULL means that the selected normal or partial matching |
| 6302 |
|
mode is not compiled. In this case we simply fallback to interpreter. */ |
| 6303 |
|
if (rc != PCRE_ERROR_NULL) |
| 6304 |
|
return rc; |
| 6305 |
|
} |
| 6306 |
#endif |
#endif |
| 6307 |
|
|
| 6308 |
/* 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 |
| 6505 |
if ((re->flags & PCRE_FIRSTSET) != 0) |
if ((re->flags & PCRE_FIRSTSET) != 0) |
| 6506 |
{ |
{ |
| 6507 |
has_first_char = TRUE; |
has_first_char = TRUE; |
| 6508 |
first_char = first_char2 = re->first_char; |
first_char = first_char2 = (pcre_uchar)(re->first_char); |
| 6509 |
if ((re->flags & PCRE_FCH_CASELESS) != 0) |
if ((re->flags & PCRE_FCH_CASELESS) != 0) |
| 6510 |
{ |
{ |
| 6511 |
first_char2 = TABLE_GET(first_char, md->fcc, first_char); |
first_char2 = TABLE_GET(first_char, md->fcc, first_char); |
| 6527 |
if ((re->flags & PCRE_REQCHSET) != 0) |
if ((re->flags & PCRE_REQCHSET) != 0) |
| 6528 |
{ |
{ |
| 6529 |
has_req_char = TRUE; |
has_req_char = TRUE; |
| 6530 |
req_char = req_char2 = re->req_char; |
req_char = req_char2 = (pcre_uchar)(re->req_char); |
| 6531 |
if ((re->flags & PCRE_RCH_CASELESS) != 0) |
if ((re->flags & PCRE_RCH_CASELESS) != 0) |
| 6532 |
{ |
{ |
| 6533 |
req_char2 = TABLE_GET(req_char, md->fcc, req_char); |
req_char2 = TABLE_GET(req_char, md->fcc, req_char); |