summaryrefslogtreecommitdiff
path: root/ext/mbstring/php_unicode.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2017-07-27 20:39:14 +0200
committerNikita Popov <nikita.ppv@gmail.com>2017-07-28 12:32:50 +0200
commit9ac7c1e71d956ddac63b042be6ad8b105e584c10 (patch)
treee806a1d4a179dfbc3e45e6f403d363055b0e575f /ext/mbstring/php_unicode.c
parent80a0601fe52b9dddbef34a168a2c1136177bda23 (diff)
downloadphp-git-9ac7c1e71d956ddac63b042be6ad8b105e584c10.tar.gz
Use case-folding for case insensitive comparisons
Instead of using lowercasing.
Diffstat (limited to 'ext/mbstring/php_unicode.c')
-rw-r--r--ext/mbstring/php_unicode.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/ext/mbstring/php_unicode.c b/ext/mbstring/php_unicode.c
index 0d4ccdcec5..d9f2f23634 100644
--- a/ext/mbstring/php_unicode.c
+++ b/ext/mbstring/php_unicode.c
@@ -196,6 +196,26 @@ unsigned php_unicode_totitle(unsigned code, enum mbfl_no_encoding enc)
return php_unicode_toupper(code, enc);
}
+unsigned php_unicode_tofold(unsigned code, enum mbfl_no_encoding enc)
+{
+ if (code < 0x80) {
+ /* Fast path for ASCII */
+ if (code >= 0x41 && code <= 0x5A) {
+ if (enc == mbfl_no_encoding_8859_9 && code == 0x0049L) {
+ return 0x0131L;
+ }
+ return code + 0x20;
+ }
+ return code;
+ } else {
+ unsigned new_code = CASE_LOOKUP(code, fold);
+ if (new_code != CODE_NOT_FOUND) {
+ return new_code;
+ }
+ return code;
+ }
+}
+
struct convert_case_data {
mbfl_convert_filter *next_filter;
enum mbfl_no_encoding no_encoding;
@@ -233,6 +253,10 @@ static int convert_case_filter(int c, void *void_data)
}
break;
}
+
+ case PHP_UNICODE_CASE_FOLD:
+ c = php_unicode_tofold(c, data->no_encoding);
+ break;
}
return (*data->next_filter->filter_function)(c, data->next_filter);
}