summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2016-02-20 13:03:20 +0200
committerEli Zaretskii <eliz@gnu.org>2016-02-20 13:03:20 +0200
commit1e996cfbd0ab64e4d74d92a80ef3aefc39249462 (patch)
tree9f184ee745d6ca7d263d62f6633ad698586ecc95
parent896f993dec0e7b18ed701a5dee6c224083d6e1dd (diff)
downloademacs-1e996cfbd0ab64e4d74d92a80ef3aefc39249462.tar.gz
Fix "[:upper:]" for non-ASCII characters
* src/regex.c (re_match_2_internal): Support [:upper:] and [:lower:] for non-ASCII characters. (Bug#18150)
-rw-r--r--src/regex.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/regex.c b/src/regex.c
index dd3f2b3cd67..164eb4612ae 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -5444,7 +5444,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
case charset:
case charset_not:
{
- register unsigned int c;
+ register unsigned int c, corig;
boolean not = (re_opcode_t) *(p - 1) == charset_not;
int len;
@@ -5473,7 +5473,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
}
PREFETCH ();
- c = RE_STRING_CHAR_AND_LENGTH (d, len, target_multibyte);
+ corig = c = RE_STRING_CHAR_AND_LENGTH (d, len, target_multibyte);
if (target_multibyte)
{
int c1;
@@ -5517,11 +5517,17 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
{
int class_bits = CHARSET_RANGE_TABLE_BITS (&p[-1]);
- if ( (class_bits & BIT_LOWER && ISLOWER (c))
+ if ( (class_bits & BIT_LOWER
+ && (ISLOWER (c)
+ || (corig != c
+ && c == upcase (corig) && ISUPPER(c))))
| (class_bits & BIT_MULTIBYTE)
| (class_bits & BIT_PUNCT && ISPUNCT (c))
| (class_bits & BIT_SPACE && ISSPACE (c))
- | (class_bits & BIT_UPPER && ISUPPER (c))
+ | (class_bits & BIT_UPPER
+ && (ISUPPER (c)
+ || (corig != c
+ && c == downcase (corig) && ISLOWER (c))))
| (class_bits & BIT_WORD && ISWORD (c))
| (class_bits & BIT_ALPHA && ISALPHA (c))
| (class_bits & BIT_ALNUM && ISALNUM (c))