[php-src] PR #24559: Fix GH-24552: Case-insensitive substr_compare(), ksort() and krsort() are locale-dependent
| From: | sirreal | Date: | Thu, 22 Oct 2026 16:30:22 +0000 |
| Subject: | [php-src] PR #24559: Fix GH-24552: Case-insensitive substr_compare(), ksort() and krsort() are locale-dependent | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-39721@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/24559
Author: sirreal
Fixes GH-24552.
Case-insensitive
substr_compare() and ksort()/krsort() with
SORT_FLAG_CASE now use ASCII case conversion, as the [strtolower-ascii
RFC](https://wiki.php.net/rfc/strtolower-ascii) and the PHP 8.2 UPGRADING notes say they do. They
called zend_binary_strncasecmp_l() and zend_binary_strcasecmp_l(), which
use the C library's tolower() and follow LC_CTYPE. #7506 switched
string_case_compare_function() to ASCII, which changed sort(), but not
these two callers.
```php
setlocale(LC_CTYPE, 'tr_TR.UTF-8'); // glibc
var_dump(substr_compare('I', 'i', 0, 1, true)); // before: int(-32), after:
int(0)
$keys = ['I' => 0, 'h' => 0];
ksort($keys, SORT_STRING | SORT_FLAG_CASE);
echo implode(',', array_keys($keys)); // before: I,h, after: h,I, as sort() orders values
```
This changes results under a non-C LC_CTYPE in a patch release. It targets PHP-8.4
because 8.2's UPGRADING already documents the ASCII behavior; I can retarget it to master
instead.
Each test needs a tr_TR.UTF-8 locale and skips without one. The CI workflows generate
no locales, so the tests probably skip in CI. On a PHP-8.4 debug build on Debian trixie (glibc
2.41), each test fails without its fix and passes with it, and ext/standard/tests/array
and ext/standard/tests/strings pass.
zend_binary_strcasecmp_l() and zend_binary_strncasecmp_l() now have no
callers in php-src. They stay because they are ZEND_API on a stable branch.