| 188 |
platforms. */ |
platforms. */ |
| 189 |
|
|
| 190 |
typedef struct verbitem { |
typedef struct verbitem { |
| 191 |
int len; |
int len; /* Length of verb name */ |
| 192 |
int op; |
int op; /* Op when no arg, or -1 if arg mandatory */ |
| 193 |
|
int op_arg; /* Op when arg present, or -1 if not allowed */ |
| 194 |
} verbitem; |
} verbitem; |
| 195 |
|
|
| 196 |
static const char verbnames[] = |
static const char verbnames[] = |
| 197 |
|
"\0" /* Empty name is a shorthand for MARK */ |
| 198 |
|
STRING_MARK0 |
| 199 |
STRING_ACCEPT0 |
STRING_ACCEPT0 |
| 200 |
STRING_COMMIT0 |
STRING_COMMIT0 |
| 201 |
STRING_F0 |
STRING_F0 |
| 205 |
STRING_THEN; |
STRING_THEN; |
| 206 |
|
|
| 207 |
static const verbitem verbs[] = { |
static const verbitem verbs[] = { |
| 208 |
{ 6, OP_ACCEPT }, |
{ 0, -1, OP_MARK }, |
| 209 |
{ 6, OP_COMMIT }, |
{ 4, -1, OP_MARK }, |
| 210 |
{ 1, OP_FAIL }, |
{ 6, OP_ACCEPT, -1 }, |
| 211 |
{ 4, OP_FAIL }, |
{ 6, OP_COMMIT, -1 }, |
| 212 |
{ 5, OP_PRUNE }, |
{ 1, OP_FAIL, -1 }, |
| 213 |
{ 4, OP_SKIP }, |
{ 4, OP_FAIL, -1 }, |
| 214 |
{ 4, OP_THEN } |
{ 5, OP_PRUNE, OP_PRUNE_ARG }, |
| 215 |
|
{ 4, OP_SKIP, OP_SKIP_ARG }, |
| 216 |
|
{ 4, OP_THEN, OP_THEN_ARG } |
| 217 |
}; |
}; |
| 218 |
|
|
| 219 |
static const int verbcount = sizeof(verbs)/sizeof(verbitem); |
static const int verbcount = sizeof(verbs)/sizeof(verbitem); |
| 350 |
"inconsistent NEWLINE options\0" |
"inconsistent NEWLINE options\0" |
| 351 |
"\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0" |
"\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0" |
| 352 |
"a numbered reference must not be zero\0" |
"a numbered reference must not be zero\0" |
| 353 |
"(*VERB) with an argument is not supported\0" |
"an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0" |
| 354 |
/* 60 */ |
/* 60 */ |
| 355 |
"(*VERB) not recognized\0" |
"(*VERB) not recognized\0" |
| 356 |
"number is too big\0" |
"number is too big\0" |
| 358 |
"digit expected after (?+\0" |
"digit expected after (?+\0" |
| 359 |
"] is an invalid data character in JavaScript compatibility mode\0" |
"] is an invalid data character in JavaScript compatibility mode\0" |
| 360 |
/* 65 */ |
/* 65 */ |
| 361 |
"different names for subpatterns of the same number are not allowed\0"; |
"different names for subpatterns of the same number are not allowed\0" |
| 362 |
|
"(*MARK) must have an argument\0" |
| 363 |
|
; |
| 364 |
|
|
| 365 |
/* Table to identify digits and hex digits. This is used when compiling |
/* Table to identify digits and hex digits. This is used when compiling |
| 366 |
patterns. Note that the tables in chartables are dependent on the locale, and |
patterns. Note that the tables in chartables are dependent on the locale, and |
| 1622 |
|
|
| 1623 |
/* Otherwise, we can get the item's length from the table, except that for |
/* Otherwise, we can get the item's length from the table, except that for |
| 1624 |
repeated character types, we have to test for \p and \P, which have an extra |
repeated character types, we have to test for \p and \P, which have an extra |
| 1625 |
two bytes of parameters. */ |
two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we |
| 1626 |
|
must add in its length. */ |
| 1627 |
|
|
| 1628 |
else |
else |
| 1629 |
{ |
{ |
| 1647 |
case OP_TYPEPOSUPTO: |
case OP_TYPEPOSUPTO: |
| 1648 |
if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2; |
if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2; |
| 1649 |
break; |
break; |
| 1650 |
|
|
| 1651 |
|
case OP_MARK: |
| 1652 |
|
case OP_PRUNE_ARG: |
| 1653 |
|
case OP_SKIP_ARG: |
| 1654 |
|
case OP_THEN_ARG: |
| 1655 |
|
code += code[1]; |
| 1656 |
|
break; |
| 1657 |
} |
} |
| 1658 |
|
|
| 1659 |
/* Add in the fixed length from the table */ |
/* Add in the fixed length from the table */ |
| 1725 |
|
|
| 1726 |
/* Otherwise, we can get the item's length from the table, except that for |
/* Otherwise, we can get the item's length from the table, except that for |
| 1727 |
repeated character types, we have to test for \p and \P, which have an extra |
repeated character types, we have to test for \p and \P, which have an extra |
| 1728 |
two bytes of parameters. */ |
two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we |
| 1729 |
|
must add in its length. */ |
| 1730 |
|
|
| 1731 |
else |
else |
| 1732 |
{ |
{ |
| 1750 |
case OP_TYPEEXACT: |
case OP_TYPEEXACT: |
| 1751 |
if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2; |
if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2; |
| 1752 |
break; |
break; |
| 1753 |
|
|
| 1754 |
|
case OP_MARK: |
| 1755 |
|
case OP_PRUNE_ARG: |
| 1756 |
|
case OP_SKIP_ARG: |
| 1757 |
|
case OP_THEN_ARG: |
| 1758 |
|
code += code[1]; |
| 1759 |
|
break; |
| 1760 |
} |
} |
| 1761 |
|
|
| 1762 |
/* Add in the fixed length from the table */ |
/* Add in the fixed length from the table */ |
| 2026 |
break; |
break; |
| 2027 |
#endif |
#endif |
| 2028 |
|
|
| 2029 |
|
/* MARK, and PRUNE/SKIP/THEN with an argument must skip over the argument |
| 2030 |
|
string. */ |
| 2031 |
|
|
| 2032 |
|
case OP_MARK: |
| 2033 |
|
case OP_PRUNE_ARG: |
| 2034 |
|
case OP_SKIP_ARG: |
| 2035 |
|
case OP_THEN_ARG: |
| 2036 |
|
code += code[1]; |
| 2037 |
|
break; |
| 2038 |
|
|
| 2039 |
/* None of the remaining opcodes are required to match a character. */ |
/* None of the remaining opcodes are required to match a character. */ |
| 2040 |
|
|
| 2041 |
default: |
default: |
| 4547 |
|
|
| 4548 |
/* First deal with various "verbs" that can be introduced by '*'. */ |
/* First deal with various "verbs" that can be introduced by '*'. */ |
| 4549 |
|
|
| 4550 |
if (*(++ptr) == CHAR_ASTERISK && (cd->ctypes[ptr[1]] & ctype_letter) != 0) |
if (*(++ptr) == CHAR_ASTERISK && |
| 4551 |
|
((cd->ctypes[ptr[1]] & ctype_letter) != 0 || ptr[1] == ':')) |
| 4552 |
{ |
{ |
| 4553 |
int i, namelen; |
int i, namelen; |
| 4554 |
|
int arglen = 0; |
| 4555 |
const char *vn = verbnames; |
const char *vn = verbnames; |
| 4556 |
const uschar *name = ++ptr; |
const uschar *name = ptr + 1; |
| 4557 |
|
const uschar *arg = NULL; |
| 4558 |
previous = NULL; |
previous = NULL; |
| 4559 |
while ((cd->ctypes[*++ptr] & ctype_letter) != 0) {}; |
while ((cd->ctypes[*++ptr] & ctype_letter) != 0) {}; |
| 4560 |
|
namelen = ptr - name; |
| 4561 |
|
|
| 4562 |
if (*ptr == CHAR_COLON) |
if (*ptr == CHAR_COLON) |
| 4563 |
{ |
{ |
| 4564 |
*errorcodeptr = ERR59; /* Not supported */ |
arg = ++ptr; |
| 4565 |
goto FAILED; |
while ((cd->ctypes[*ptr] & (ctype_letter|ctype_digit)) != 0 |
| 4566 |
|
|| *ptr == '_') ptr++; |
| 4567 |
|
arglen = ptr - arg; |
| 4568 |
} |
} |
| 4569 |
|
|
| 4570 |
if (*ptr != CHAR_RIGHT_PARENTHESIS) |
if (*ptr != CHAR_RIGHT_PARENTHESIS) |
| 4571 |
{ |
{ |
| 4572 |
*errorcodeptr = ERR60; |
*errorcodeptr = ERR60; |
| 4573 |
goto FAILED; |
goto FAILED; |
| 4574 |
} |
} |
| 4575 |
namelen = ptr - name; |
|
| 4576 |
|
/* Scan the table of verb names */ |
| 4577 |
|
|
| 4578 |
for (i = 0; i < verbcount; i++) |
for (i = 0; i < verbcount; i++) |
| 4579 |
{ |
{ |
| 4580 |
if (namelen == verbs[i].len && |
if (namelen == verbs[i].len && |
| 4592 |
PUT2INC(code, 0, oc->number); |
PUT2INC(code, 0, oc->number); |
| 4593 |
} |
} |
| 4594 |
} |
} |
| 4595 |
*code++ = verbs[i].op; |
|
| 4596 |
break; |
/* Handle the cases with/without an argument */ |
| 4597 |
|
|
| 4598 |
|
if (arglen == 0) |
| 4599 |
|
{ |
| 4600 |
|
if (verbs[i].op < 0) /* Argument is mandatory */ |
| 4601 |
|
{ |
| 4602 |
|
*errorcodeptr = ERR66; |
| 4603 |
|
goto FAILED; |
| 4604 |
|
} |
| 4605 |
|
*code++ = verbs[i].op; |
| 4606 |
|
} |
| 4607 |
|
|
| 4608 |
|
else |
| 4609 |
|
{ |
| 4610 |
|
if (verbs[i].op_arg < 0) /* Argument is forbidden */ |
| 4611 |
|
{ |
| 4612 |
|
*errorcodeptr = ERR59; |
| 4613 |
|
goto FAILED; |
| 4614 |
|
} |
| 4615 |
|
*code++ = verbs[i].op_arg; |
| 4616 |
|
*code++ = arglen; |
| 4617 |
|
memcpy(code, arg, arglen); |
| 4618 |
|
code += arglen; |
| 4619 |
|
*code++ = 0; |
| 4620 |
|
} |
| 4621 |
|
|
| 4622 |
|
break; /* Found verb, exit loop */ |
| 4623 |
} |
} |
| 4624 |
|
|
| 4625 |
vn += verbs[i].len + 1; |
vn += verbs[i].len + 1; |
| 4626 |
} |
} |
| 4627 |
if (i < verbcount) continue; |
|
| 4628 |
*errorcodeptr = ERR60; |
if (i < verbcount) continue; /* Successfully handled a verb */ |
| 4629 |
|
*errorcodeptr = ERR60; /* Verb not recognized */ |
| 4630 |
goto FAILED; |
goto FAILED; |
| 4631 |
} |
} |
| 4632 |
|
|
| 5409 |
} /* End of switch for character following (? */ |
} /* End of switch for character following (? */ |
| 5410 |
} /* End of (? handling */ |
} /* End of (? handling */ |
| 5411 |
|
|
| 5412 |
/* Opening parenthesis not followed by '?'. If PCRE_NO_AUTO_CAPTURE is set, |
/* Opening parenthesis not followed by '*' or '?'. If PCRE_NO_AUTO_CAPTURE |
| 5413 |
all unadorned brackets become non-capturing and behave like (?:...) |
is set, all unadorned brackets become non-capturing and behave like (?:...) |
| 5414 |
brackets. */ |
brackets. */ |
| 5415 |
|
|
| 5416 |
else if ((options & PCRE_NO_AUTO_CAPTURE) != 0) |
else if ((options & PCRE_NO_AUTO_CAPTURE) != 0) |