Skip to content

Commit 683e787

Browse files
committed
Fix GH-12727: NumberFormatter constructor throws an exception on invalid locale.
Also re-establishing exception throwing on IntlDateFormatter constructor overwritten by accident most likely so postponing it for next major release. Close GH-12868
1 parent d751e61 commit 683e787

File tree

7 files changed

+57
-18
lines changed

7 files changed

+57
-18
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ FTP:
2626

2727
Intl:
2828
. Added IntlDateFormatter::PATTERN constant. (David Carlier)
29+
. Fixed Numberformatter::__construct when the locale is invalid, now
30+
throws an exception. (David Carlier)
2931

3032
MBString:
3133
. Added mb_trim, mb_ltrim and mb_rtrim. (Yuya Hamada)

UPGRADING

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ PHP 8.4 UPGRADE NOTES
190190
5. Changed Functions
191191
========================================
192192

193+
- Intl:
194+
. IntlDateFormatter::__construct() throws a ValueError if the locale is invalid.
195+
. NumberFormatter::__construct() throws a ValueError if the locale is invalid.
196+
193197
- MBString:
194198
. The behavior of mb_strcut is more consistent now on invalid UTF-8 and UTF-16
195199
strings. (For valid UTF-8 and UTF-16 strings, there is no change.)

ext/intl/dateformat/dateformat_create.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin
113113
locale = Locale::createFromName(locale_str);
114114
/* get*Name accessors being set does not preclude being bogus */
115115
if (locale.isBogus() || strlen(locale.getISO3Language()) == 0) {
116-
goto error;
116+
zend_argument_value_error(1, "\"%s\" is invalid", locale_str);
117+
return FAILURE;
117118
}
118119

119120
/* process calendar */

ext/intl/formatter/formatter_main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#endif
1818

1919
#include <unicode/ustring.h>
20+
#include <unicode/uloc.h>
2021

2122
#include "php_intl.h"
2223
#include "formatter_class.h"
@@ -63,6 +64,11 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_
6364
locale = intl_locale_get_default();
6465
}
6566

67+
if (strlen(uloc_getISO3Language(locale)) == 0) {
68+
zend_argument_value_error(1, "\"%s\" is invalid", locale);
69+
return FAILURE;
70+
}
71+
6672
/* Create an ICU number formatter. */
6773
FORMATTER_OBJECT(nfo) = unum_open(style, spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(nfo));
6874

ext/intl/tests/formatter_fail.phpt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,14 @@ Deprecated: numfmt_create(): Passing null to parameter #1 ($locale) of type stri
119119

120120
Deprecated: numfmt_create(): Passing null to parameter #2 ($style) of type int is deprecated in %s on line %d
121121

122-
IntlException: Constructor failed in %s on line %d
123-
'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR'
124-
'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR'
125-
'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR'
122+
ValueError: NumberFormatter::__construct(): Argument #1 ($locale) "%s" is invalid in %s on line %d
123+
'U_ZERO_ERROR'
124+
125+
ValueError: NumberFormatter::create(): Argument #1 ($locale) "%s" is invalid in %s on line %d
126+
'U_ZERO_ERROR'
127+
128+
ValueError: numfmt_create(): Argument #1 ($locale) "%s" is invalid in %s on line %d
129+
'U_ZERO_ERROR'
126130

127131
TypeError: NumberFormatter::__construct(): Argument #1 ($locale) must be of type string, array given in %s on line %d
128132
'U_ZERO_ERROR'

ext/intl/tests/gh12282.phpt

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,25 @@ intl
55
--FILE--
66
<?php
77

8-
var_dump(new IntlDateFormatter(
9-
'xx',
10-
IntlDateFormatter::FULL,
11-
IntlDateFormatter::FULL,
12-
null,
13-
null,
14-
'w'
15-
));
16-
Locale::setDefault('xx');
17-
var_dump(new IntlDateFormatter(Locale::getDefault()));
18-
--EXPECT--
19-
object(IntlDateFormatter)#1 (0) {
8+
try {
9+
new IntlDateFormatter(
10+
'xx',
11+
IntlDateFormatter::FULL,
12+
IntlDateFormatter::FULL,
13+
null,
14+
null,
15+
'w'
16+
);
17+
} catch (\ValueError $e) {
18+
echo $e->getMessage() . PHP_EOL;
2019
}
21-
object(IntlDateFormatter)#1 (0) {
20+
21+
Locale::setDefault('xx');
22+
try {
23+
new IntlDateFormatter(Locale::getDefault());
24+
} catch (\ValueError $e) {
25+
echo $e->getMessage();
2226
}
27+
--EXPECT--
28+
IntlDateFormatter::__construct(): Argument #1 ($locale) "xx" is invalid
29+
IntlDateFormatter::__construct(): Argument #1 ($locale) "xx" is invalid

ext/intl/tests/gh12727.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
numfmt creation failures
3+
--EXTENSIONS--
4+
intl
5+
--FILE--
6+
<?php
7+
8+
try {
9+
new NumberFormatter('xx', NumberFormatter::DECIMAL);
10+
} catch (ValueError $e) {
11+
echo $e->getMessage();
12+
}
13+
?>
14+
--EXPECTF--
15+
NumberFormatter::__construct(): Argument #1 ($locale) "%s" is invalid

0 commit comments

Comments
 (0)