Skip to content

Commit 0f1b17e

Browse files
committed
Fix #72809: Locale::lookup() wrong result with canonicalize option
Canonicalization converts the locale to ICU format[1]. However, the lookup described in RFC 4647, section 3.4, is about POSIX format. To make that lookup work for ICU format, we also need to cater to keyword separators. The results are somewhat unexpected, but apparently canonical lookup is explicitly supposed to return canonical language tags[2]. [1] <https://unicode-org.github.io/icu/userguide/locale/#canonicalization> [2] <https://github.com/php/php-src/blob/php-7.4.20/ext/intl/locale/locale_methods.c#L1504> Closes GH-7151.
1 parent 8370a08 commit 0f1b17e

File tree

3 files changed

+22
-1
lines changed

3 files changed

+22
-1
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 7.4.22
44

5+
- Intl:
6+
. Fixed bug #72809 (Locale::lookup() wrong result with canonicalize option).
7+
(cmb)
58

69
01 Jul 2021, PHP 7.4.21
710

ext/intl/locale/locale_methods.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ static zend_off_t getStrrtokenPos(char* str, zend_off_t savedPos)
149149
zend_off_t i;
150150

151151
for(i=savedPos-1; i>=0; i--) {
152-
if(isIDSeparator(*(str+i)) ){
152+
if(isIDSeparator(*(str+i)) || isKeywordSeparator(*(str+i))){
153153
/* delimiter found; check for singleton */
154154
if(i>=2 && isIDSeparator(*(str+i-2)) ){
155155
/* a singleton; so send the position of token before the singleton */

ext/intl/tests/locale/bug72809.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Bug #72809 (Locale::lookup() wrong result with canonicalize option)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('intl')) die("skip intl extension not avaible");
6+
?>
7+
--FILE--
8+
<?php
9+
var_dump(
10+
Locale::lookup(['en', 'en-US'], 'en-US-u-cu-EUR-tz-deber-fw-mon', true),
11+
Locale::lookup(['en', 'en_US'], 'en_US@currency=eur;fw=mon;timezone=Europe/Berlin', false),
12+
Locale::lookup(['en', 'en_US'], 'en_US@currency=eur;fw=mon;timezone=Europe/Berlin', true),
13+
);
14+
?>
15+
--EXPECT--
16+
string(5) "en_us"
17+
string(5) "en_US"
18+
string(5) "en_us"

0 commit comments

Comments
 (0)