1737 |
*************************************************/ |
*************************************************/ |
1738 |
|
|
1739 |
/* This function is called when the sequence "[:" or "[." or "[=" is |
/* This function is called when the sequence "[:" or "[." or "[=" is |
1740 |
encountered in a character class. It checks whether this is followed by an |
encountered in a character class. It checks whether this is followed by a |
1741 |
optional ^ and then a sequence of letters, terminated by a matching ":]" or |
sequence of characters terminated by a matching ":]" or ".]" or "=]". If we |
1742 |
".]" or "=]". |
reach an unescaped ']' without the special preceding character, return FALSE. |
1743 |
|
|
1744 |
|
Originally, this function only recognized a sequence of letters between the |
1745 |
|
terminators, but it seems that Perl recognizes any sequence of characters, |
1746 |
|
though of course unknown POSIX names are subsequently rejected. Perl gives an |
1747 |
|
"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE |
1748 |
|
didn't consider this to be a POSIX class. Likewise for [:1234:]. |
1749 |
|
|
1750 |
|
The problem in trying to be exactly like Perl is in the handling of escapes. We |
1751 |
|
have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX |
1752 |
|
class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code |
1753 |
|
below handles the special case of \], but does not try to do any other escape |
1754 |
|
processing. This makes it different from Perl for cases such as [:l\ower:] |
1755 |
|
where Perl recognizes it as the POSIX class "lower" but PCRE does not recognize |
1756 |
|
"l\ower". This is a lesser evil that not diagnosing bad classes when Perl does, |
1757 |
|
I think. |
1758 |
|
|
1759 |
Argument: |
Arguments: |
1760 |
ptr pointer to the initial [ |
ptr pointer to the initial [ |
1761 |
endptr where to return the end pointer |
endptr where to return the end pointer |
|
cd pointer to compile data |
|
1762 |
|
|
1763 |
Returns: TRUE or FALSE |
Returns: TRUE or FALSE |
1764 |
*/ |
*/ |
1765 |
|
|
1766 |
static BOOL |
static BOOL |
1767 |
check_posix_syntax(const uschar *ptr, const uschar **endptr, compile_data *cd) |
check_posix_syntax(const uschar *ptr, const uschar **endptr) |
1768 |
{ |
{ |
1769 |
int terminator; /* Don't combine these lines; the Solaris cc */ |
int terminator; /* Don't combine these lines; the Solaris cc */ |
1770 |
terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */ |
terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */ |
1771 |
if (*(++ptr) == '^') ptr++; |
for (++ptr; *ptr != 0; ptr++) |
|
while ((cd->ctypes[*ptr] & ctype_letter) != 0) ptr++; |
|
|
if (*ptr == terminator && ptr[1] == ']') |
|
1772 |
{ |
{ |
1773 |
*endptr = ptr; |
if (*ptr == '\\' && ptr[1] == ']') ptr++; else |
1774 |
return TRUE; |
{ |
1775 |
} |
if (*ptr == ']') return FALSE; |
1776 |
|
if (*ptr == terminator && ptr[1] == ']') |
1777 |
|
{ |
1778 |
|
*endptr = ptr; |
1779 |
|
return TRUE; |
1780 |
|
} |
1781 |
|
} |
1782 |
|
} |
1783 |
return FALSE; |
return FALSE; |
1784 |
} |
} |
1785 |
|
|
2639 |
they are encountered at the top level, so we'll do that too. */ |
they are encountered at the top level, so we'll do that too. */ |
2640 |
|
|
2641 |
if ((ptr[1] == ':' || ptr[1] == '.' || ptr[1] == '=') && |
if ((ptr[1] == ':' || ptr[1] == '.' || ptr[1] == '=') && |
2642 |
check_posix_syntax(ptr, &tempptr, cd)) |
check_posix_syntax(ptr, &tempptr)) |
2643 |
{ |
{ |
2644 |
*errorcodeptr = (ptr[1] == ':')? ERR13 : ERR31; |
*errorcodeptr = (ptr[1] == ':')? ERR13 : ERR31; |
2645 |
goto FAILED; |
goto FAILED; |
2725 |
|
|
2726 |
if (c == '[' && |
if (c == '[' && |
2727 |
(ptr[1] == ':' || ptr[1] == '.' || ptr[1] == '=') && |
(ptr[1] == ':' || ptr[1] == '.' || ptr[1] == '=') && |
2728 |
check_posix_syntax(ptr, &tempptr, cd)) |
check_posix_syntax(ptr, &tempptr)) |
2729 |
{ |
{ |
2730 |
BOOL local_negate = FALSE; |
BOOL local_negate = FALSE; |
2731 |
int posix_class, taboffset, tabopt; |
int posix_class, taboffset, tabopt; |