| 195 |
|
|
| 196 |
static const char verbnames[] = |
static const char verbnames[] = |
| 197 |
"\0" /* Empty name is a shorthand for MARK */ |
"\0" /* Empty name is a shorthand for MARK */ |
| 198 |
STRING_MARK0 |
STRING_MARK0 |
| 199 |
STRING_ACCEPT0 |
STRING_ACCEPT0 |
| 200 |
STRING_COMMIT0 |
STRING_COMMIT0 |
| 201 |
STRING_F0 |
STRING_F0 |
| 206 |
|
|
| 207 |
static const verbitem verbs[] = { |
static const verbitem verbs[] = { |
| 208 |
{ 0, -1, OP_MARK }, |
{ 0, -1, OP_MARK }, |
| 209 |
{ 4, -1, OP_MARK }, |
{ 4, -1, OP_MARK }, |
| 210 |
{ 6, OP_ACCEPT, -1 }, |
{ 6, OP_ACCEPT, -1 }, |
| 211 |
{ 6, OP_COMMIT, -1 }, |
{ 6, OP_COMMIT, -1 }, |
| 212 |
{ 1, OP_FAIL, -1 }, |
{ 1, OP_FAIL, -1 }, |
| 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" |
"(*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 |
| 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, and for MARK/PRUNE/SKIP/THEN with an argument, we |
two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we |
| 1626 |
must add in its length. */ |
must add in its length. */ |
| 1627 |
|
|
| 1628 |
else |
else |
| 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: |
case OP_MARK: |
| 1652 |
case OP_PRUNE_ARG: |
case OP_PRUNE_ARG: |
| 1653 |
case OP_SKIP_ARG: |
case OP_SKIP_ARG: |
| 1654 |
case OP_THEN_ARG: |
case OP_THEN_ARG: |
| 1655 |
code += code[1]; |
code += code[1]; |
| 1656 |
break; |
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, and for MARK/PRUNE/SKIP/THEN with an argument, we |
two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we |
| 1729 |
must add in its length. */ |
must add in its length. */ |
| 1730 |
|
|
| 1731 |
else |
else |
| 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: |
case OP_MARK: |
| 1755 |
case OP_PRUNE_ARG: |
case OP_PRUNE_ARG: |
| 1756 |
case OP_SKIP_ARG: |
case OP_SKIP_ARG: |
| 1757 |
case OP_THEN_ARG: |
case OP_THEN_ARG: |
| 1758 |
code += code[1]; |
code += code[1]; |
| 1759 |
break; |
break; |
| 1760 |
} |
} |
| 1761 |
|
|
| 1762 |
/* Add in the fixed length from the table */ |
/* Add in the fixed length from the table */ |
| 2034 |
case OP_SKIP_ARG: |
case OP_SKIP_ARG: |
| 2035 |
case OP_THEN_ARG: |
case OP_THEN_ARG: |
| 2036 |
code += code[1]; |
code += code[1]; |
| 2037 |
break; |
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 |
|
|
| 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 && |
if (*(++ptr) == CHAR_ASTERISK && |
| 4551 |
((cd->ctypes[ptr[1]] & ctype_letter) != 0 || ptr[1] == ':')) |
((cd->ctypes[ptr[1]] & ctype_letter) != 0 || ptr[1] == ':')) |
| 4552 |
{ |
{ |
| 4553 |
int i, namelen; |
int i, namelen; |
| 4554 |
int arglen = 0; |
int arglen = 0; |
| 4555 |
const char *vn = verbnames; |
const char *vn = verbnames; |
| 4556 |
const uschar *name = ptr + 1; |
const uschar *name = ptr + 1; |
| 4557 |
const uschar *arg = NULL; |
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; |
namelen = ptr - name; |
| 4561 |
|
|
| 4562 |
if (*ptr == CHAR_COLON) |
if (*ptr == CHAR_COLON) |
| 4563 |
{ |
{ |
| 4564 |
arg = ++ptr; |
arg = ++ptr; |
| 4566 |
|| *ptr == '_') ptr++; |
|| *ptr == '_') ptr++; |
| 4567 |
arglen = ptr - arg; |
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 |
|
|
| 4576 |
/* Scan the table of verb names */ |
/* 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 |
|
|
| 4596 |
/* Handle the cases with/without an argument */ |
/* Handle the cases with/without an argument */ |
| 4597 |
|
|
| 4598 |
if (arglen == 0) |
if (arglen == 0) |
| 4599 |
{ |
{ |
| 4600 |
if (verbs[i].op < 0) /* Argument is mandatory */ |
if (verbs[i].op < 0) /* Argument is mandatory */ |
| 4601 |
{ |
{ |
| 4602 |
*errorcodeptr = ERR66; |
*errorcodeptr = ERR66; |
| 4603 |
goto FAILED; |
goto FAILED; |
| 4604 |
} |
} |
| 4605 |
*code++ = verbs[i].op; |
*code++ = verbs[i].op; |
| 4606 |
} |
} |
| 4607 |
|
|
| 4608 |
else |
else |
| 4609 |
{ |
{ |
| 4610 |
if (verbs[i].op_arg < 0) /* Argument is forbidden */ |
if (verbs[i].op_arg < 0) /* Argument is forbidden */ |
| 4611 |
{ |
{ |
| 4612 |
*errorcodeptr = ERR59; |
*errorcodeptr = ERR59; |
| 4613 |
goto FAILED; |
goto FAILED; |
| 4614 |
} |
} |
| 4615 |
*code++ = verbs[i].op_arg; |
*code++ = verbs[i].op_arg; |
| 4616 |
*code++ = arglen; |
*code++ = arglen; |
| 4617 |
memcpy(code, arg, arglen); |
memcpy(code, arg, arglen); |
| 4618 |
code += arglen; |
code += arglen; |
| 4619 |
*code++ = 0; |
*code++ = 0; |
| 4620 |
} |
} |
| 4621 |
|
|
| 4622 |
break; /* Found verb, exit loop */ |
break; /* Found verb, exit loop */ |
| 4623 |
} |
} |
| 4624 |
|
|
| 4625 |
vn += verbs[i].len + 1; |
vn += verbs[i].len + 1; |
| 4626 |
} |
} |
| 4627 |
|
|
| 4628 |
if (i < verbcount) continue; /* Successfully handled a verb */ |
if (i < verbcount) continue; /* Successfully handled a verb */ |
| 4629 |
*errorcodeptr = ERR60; /* Verb not recognized */ |
*errorcodeptr = ERR60; /* Verb not recognized */ |
| 4630 |
goto FAILED; |
goto FAILED; |