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
This commit is contained in:
David Carlier 2023-12-04 22:00:17 +00:00
parent d751e61504
commit 683e787860
7 changed files with 57 additions and 18 deletions

2
NEWS
View file

@ -26,6 +26,8 @@ FTP:
Intl: Intl:
. Added IntlDateFormatter::PATTERN constant. (David Carlier) . Added IntlDateFormatter::PATTERN constant. (David Carlier)
. Fixed Numberformatter::__construct when the locale is invalid, now
throws an exception. (David Carlier)
MBString: MBString:
. Added mb_trim, mb_ltrim and mb_rtrim. (Yuya Hamada) . Added mb_trim, mb_ltrim and mb_rtrim. (Yuya Hamada)

View file

@ -190,6 +190,10 @@ PHP 8.4 UPGRADE NOTES
5. Changed Functions 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: - MBString:
. The behavior of mb_strcut is more consistent now on invalid UTF-8 and UTF-16 . 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.) strings. (For valid UTF-8 and UTF-16 strings, there is no change.)

View file

@ -113,7 +113,8 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin
locale = Locale::createFromName(locale_str); locale = Locale::createFromName(locale_str);
/* get*Name accessors being set does not preclude being bogus */ /* get*Name accessors being set does not preclude being bogus */
if (locale.isBogus() || strlen(locale.getISO3Language()) == 0) { if (locale.isBogus() || strlen(locale.getISO3Language()) == 0) {
goto error; zend_argument_value_error(1, "\"%s\" is invalid", locale_str);
return FAILURE;
} }
/* process calendar */ /* process calendar */

View file

@ -17,6 +17,7 @@
#endif #endif
#include <unicode/ustring.h> #include <unicode/ustring.h>
#include <unicode/uloc.h>
#include "php_intl.h" #include "php_intl.h"
#include "formatter_class.h" #include "formatter_class.h"
@ -63,6 +64,11 @@ static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_
locale = intl_locale_get_default(); 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. */ /* Create an ICU number formatter. */
FORMATTER_OBJECT(nfo) = unum_open(style, spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(nfo)); FORMATTER_OBJECT(nfo) = unum_open(style, spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(nfo));

View file

@ -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 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 ValueError: NumberFormatter::__construct(): Argument #1 ($locale) "%s" is invalid in %s on line %d
'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR' 'U_ZERO_ERROR'
'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR'
'numfmt_create: number formatter creation failed: U_UNSUPPORTED_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 TypeError: NumberFormatter::__construct(): Argument #1 ($locale) must be of type string, array given in %s on line %d
'U_ZERO_ERROR' 'U_ZERO_ERROR'

View file

@ -5,18 +5,25 @@ intl
--FILE-- --FILE--
<?php <?php
var_dump(new IntlDateFormatter( try {
'xx', new IntlDateFormatter(
IntlDateFormatter::FULL, 'xx',
IntlDateFormatter::FULL, IntlDateFormatter::FULL,
null, IntlDateFormatter::FULL,
null, null,
'w' null,
)); 'w'
);
} catch (\ValueError $e) {
echo $e->getMessage() . PHP_EOL;
}
Locale::setDefault('xx'); Locale::setDefault('xx');
var_dump(new IntlDateFormatter(Locale::getDefault())); try {
new IntlDateFormatter(Locale::getDefault());
} catch (\ValueError $e) {
echo $e->getMessage();
}
--EXPECT-- --EXPECT--
object(IntlDateFormatter)#1 (0) { IntlDateFormatter::__construct(): Argument #1 ($locale) "xx" is invalid
} IntlDateFormatter::__construct(): Argument #1 ($locale) "xx" is invalid
object(IntlDateFormatter)#1 (0) {
}

View file

@ -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