summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/mbstring/php_unicode.c27
-rw-r--r--ext/mbstring/tests/bug69267.phpt9
-rw-r--r--ext/mbstring/ucgendat/ucgendat.c2
-rw-r--r--ext/mbstring/unicode_data.h2
4 files changed, 25 insertions, 15 deletions
diff --git a/ext/mbstring/php_unicode.c b/ext/mbstring/php_unicode.c
index 8b6a52156a..9771289cd0 100644
--- a/ext/mbstring/php_unicode.c
+++ b/ext/mbstring/php_unicode.c
@@ -122,6 +122,7 @@ MBSTRING_API int php_unicode_is_prop(unsigned long code, unsigned long mask1,
static unsigned long case_lookup(unsigned long code, long l, long r, int field)
{
long m;
+ const unsigned int *tmp;
/*
* Do the binary search.
@@ -132,13 +133,13 @@ static unsigned long case_lookup(unsigned long code, long l, long r, int field)
* the beginning of a case mapping triple.
*/
m = (l + r) >> 1;
- m -= (m % 3);
- if (code > _uccase_map[m])
- l = m + 3;
- else if (code < _uccase_map[m])
- r = m - 3;
- else if (code == _uccase_map[m])
- return _uccase_map[m + field];
+ tmp = &_uccase_map[m*3];
+ if (code > *tmp)
+ l = m + 1;
+ else if (code < *tmp)
+ r = m - 1;
+ else if (code == *tmp)
+ return tmp[field];
}
return code;
@@ -174,7 +175,7 @@ MBSTRING_API unsigned long php_unicode_toupper(unsigned long code, enum mbfl_no_
*/
field = 2;
l = _uccase_len[0];
- r = (l + _uccase_len[1]) - 3;
+ r = (l + _uccase_len[1]) - 1;
if (enc == mbfl_no_encoding_8859_9) {
return php_turkish_toupper(code, l, r, field);
@@ -186,7 +187,7 @@ MBSTRING_API unsigned long php_unicode_toupper(unsigned long code, enum mbfl_no_
*/
field = 1;
l = _uccase_len[0] + _uccase_len[1];
- r = _uccase_size - 3;
+ r = _uccase_size - 1;
}
return case_lookup(code, l, r, field);
}
@@ -205,7 +206,7 @@ MBSTRING_API unsigned long php_unicode_tolower(unsigned long code, enum mbfl_no_
*/
field = 1;
l = 0;
- r = _uccase_len[0] - 3;
+ r = _uccase_len[0] - 1;
if (enc == mbfl_no_encoding_8859_9) {
return php_turkish_tolower(code, l, r, field);
@@ -217,7 +218,7 @@ MBSTRING_API unsigned long php_unicode_tolower(unsigned long code, enum mbfl_no_
*/
field = 2;
l = _uccase_len[0] + _uccase_len[1];
- r = _uccase_size - 3;
+ r = _uccase_size - 1;
}
return case_lookup(code, l, r, field);
}
@@ -240,13 +241,13 @@ MBSTRING_API unsigned long php_unicode_totitle(unsigned long code, enum mbfl_no_
* The character is upper case.
*/
l = 0;
- r = _uccase_len[0] - 3;
+ r = _uccase_len[0] - 1;
} else {
/*
* The character is lower case.
*/
l = _uccase_len[0];
- r = (l + _uccase_len[1]) - 3;
+ r = (l + _uccase_len[1]) - 1;
}
return case_lookup(code, l, r, field);
diff --git a/ext/mbstring/tests/bug69267.phpt b/ext/mbstring/tests/bug69267.phpt
new file mode 100644
index 0000000000..c00e5e129a
--- /dev/null
+++ b/ext/mbstring/tests/bug69267.phpt
@@ -0,0 +1,9 @@
+--TEST--
+Bug #69267: mb_strtolower fails on titlecase characters
+--FILE--
+<?php
+$str = "DžLjNjDz";
+var_dump(mb_strtolower($str));
+?>
+--EXPECT--
+string(8) "džljnjdz"
diff --git a/ext/mbstring/ucgendat/ucgendat.c b/ext/mbstring/ucgendat/ucgendat.c
index f7b8ab5498..80977c5310 100644
--- a/ext/mbstring/ucgendat/ucgendat.c
+++ b/ext/mbstring/ucgendat/ucgendat.c
@@ -1442,7 +1442,7 @@ write_cdata(char *opath)
" * LowerIndex = _uccase_len[0]\n"
" * TitleIndex = LowerIndex + _uccase_len[1] */\n\n");
fprintf(out, PREF "unsigned short _uccase_len[2] = {%ld, %ld};\n\n",
- (long) upper_used * 3, (long) lower_used * 3);
+ (long) upper_used, (long) lower_used);
fprintf(out, PREF "unsigned int _uccase_map[] = {");
if (upper_used > 0)
diff --git a/ext/mbstring/unicode_data.h b/ext/mbstring/unicode_data.h
index 16ceb6a975..51b1ea65c9 100644
--- a/ext/mbstring/unicode_data.h
+++ b/ext/mbstring/unicode_data.h
@@ -2469,7 +2469,7 @@ static const unsigned int _uccase_size = 2470;
* LowerIndex = _uccase_len[0]
* TitleIndex = LowerIndex + _uccase_len[1] */
-static const unsigned short _uccase_len[2] = {3687, 3711};
+static const unsigned short _uccase_len[2] = {1229, 1237};
static const unsigned int _uccase_map[] = {
0x00000041, 0x00000061, 0x00000041,