Skip to content

Commit

Permalink
Fix phpGH-12727: NumberFormatter constructor throws an exception on i…
Browse files Browse the repository at this point in the history
…nvalid locale.

Also re-establishing exception throwing on IntlDateFormatter constructor
overwritten by accident most likely so postponing it for next major
release.

Close phpGH-12868
  • Loading branch information
devnexen committed Dec 6, 2023
1 parent d751e61 commit 683e787
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 18 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ FTP:

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

MBString:
. Added mb_trim, mb_ltrim and mb_rtrim. (Yuya Hamada)
Expand Down
4 changes: 4 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ PHP 8.4 UPGRADE NOTES
5. Changed Functions
========================================

- Intl:
. IntlDateFormatter::__construct() throws a ValueError if the locale is invalid.
. NumberFormatter::__construct() throws a ValueError if the locale is invalid.

- MBString:
. The behavior of mb_strcut is more consistent now on invalid UTF-8 and UTF-16
strings. (For valid UTF-8 and UTF-16 strings, there is no change.)
Expand Down
3 changes: 2 additions & 1 deletion ext/intl/dateformat/dateformat_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin
locale = Locale::createFromName(locale_str);
/* get*Name accessors being set does not preclude being bogus */
if (locale.isBogus() || strlen(locale.getISO3Language()) == 0) {
goto error;
zend_argument_value_error(1, "\"%s\" is invalid", locale_str);
return FAILURE;
}

/* process calendar */
Expand Down
6 changes: 6 additions & 0 deletions ext/intl/formatter/formatter_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#endif

#include <unicode/ustring.h>
#include <unicode/uloc.h>

#include "php_intl.h"
#include "formatter_class.h"
Expand Down Expand Up @@ -63,6 +64,11 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_
locale = intl_locale_get_default();
}

if (strlen(uloc_getISO3Language(locale)) == 0) {
zend_argument_value_error(1, "\"%s\" is invalid", locale);
return FAILURE;
}

/* Create an ICU number formatter. */
FORMATTER_OBJECT(nfo) = unum_open(style, spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(nfo));

Expand Down
12 changes: 8 additions & 4 deletions ext/intl/tests/formatter_fail.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,14 @@ Deprecated: numfmt_create(): Passing null to parameter #1 ($locale) of type stri

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

IntlException: Constructor failed in %s on line %d
'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR'
'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR'
'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR'
ValueError: NumberFormatter::__construct(): Argument #1 ($locale) "%s" is invalid in %s on line %d
'U_ZERO_ERROR'

ValueError: NumberFormatter::create(): Argument #1 ($locale) "%s" is invalid in %s on line %d
'U_ZERO_ERROR'

ValueError: numfmt_create(): Argument #1 ($locale) "%s" is invalid in %s on line %d
'U_ZERO_ERROR'

TypeError: NumberFormatter::__construct(): Argument #1 ($locale) must be of type string, array given in %s on line %d
'U_ZERO_ERROR'
Expand Down
33 changes: 20 additions & 13 deletions ext/intl/tests/gh12282.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,25 @@ intl
--FILE--
<?php

var_dump(new IntlDateFormatter(
'xx',
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
null,
null,
'w'
));
Locale::setDefault('xx');
var_dump(new IntlDateFormatter(Locale::getDefault()));
--EXPECT--
object(IntlDateFormatter)#1 (0) {
try {
new IntlDateFormatter(
'xx',
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
null,
null,
'w'
);
} catch (\ValueError $e) {
echo $e->getMessage() . PHP_EOL;
}
object(IntlDateFormatter)#1 (0) {

Locale::setDefault('xx');
try {
new IntlDateFormatter(Locale::getDefault());
} catch (\ValueError $e) {
echo $e->getMessage();
}
--EXPECT--
IntlDateFormatter::__construct(): Argument #1 ($locale) "xx" is invalid
IntlDateFormatter::__construct(): Argument #1 ($locale) "xx" is invalid
15 changes: 15 additions & 0 deletions ext/intl/tests/gh12727.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
numfmt creation failures
--EXTENSIONS--
intl
--FILE--
<?php

try {
new NumberFormatter('xx', NumberFormatter::DECIMAL);
} catch (ValueError $e) {
echo $e->getMessage();
}
?>
--EXPECTF--
NumberFormatter::__construct(): Argument #1 ($locale) "%s" is invalid

0 comments on commit 683e787

Please sign in to comment.