1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

ext/intl: wrap DateTimeZone constructor exception in an IntlException (#19410)

The motivation is two fold:
- Userland code that deals with ext/intl can be expected to handle IntlException but not necessarily ext/date exceptions
- This removes the possibility of superfluous warnings being emitted by ext/intl when an exception has already been thrown
This commit is contained in:
Gina Peter Banyard
2025-08-09 11:24:11 +01:00
committed by GitHub
parent 8c5c03e33a
commit 1e108e9ab2
3 changed files with 44 additions and 43 deletions

View File

@@ -9,31 +9,43 @@ $cal = new IntlGregorianCalendar("Etc/Unknown");
try {
var_dump($cal->toDateTime());
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
$previous = $e->getPrevious();
echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL;
}
try {
var_dump(intlcal_to_date_time($cal));
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
$previous = $e->getPrevious();
echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL;
}
$cal = IntlCalendar::createInstance("Etc/Unknown");
try {
var_dump($cal->toDateTime());
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
$previous = $e->getPrevious();
echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL;
}
try {
var_dump(intlcal_to_date_time($cal));
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
$previous = $e->getPrevious();
echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL;
}
?>
--EXPECT--
DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)
DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)
DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)
DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)
IntlException: DateTimeZone constructor threw exception
DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)
IntlException: DateTimeZone constructor threw exception
DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)
IntlException: DateTimeZone constructor threw exception
DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)
IntlException: DateTimeZone constructor threw exception
DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)

View File

@@ -4,17 +4,18 @@ IntlTimeZone::toDateTimeZone(): errors
intl
--FILE--
<?php
ini_set("intl.error_level", E_WARNING);
$tz = IntlTimeZone::createTimeZone('Etc/Unknown');
try {
var_dump($tz->toDateTimeZone());
} catch (Exception $e) {
var_dump($e->getMessage());
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
$previous = $e->getPrevious();
echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL;
}
?>
--EXPECTF--
Warning: IntlTimeZone::toDateTimeZone(): DateTimeZone constructor threw exception in %s on line %d
string(66) "DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)"
--EXPECT--
IntlException: DateTimeZone constructor threw exception
DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)

View File

@@ -64,56 +64,44 @@ U_CFUNC zval *timezone_convert_to_datetimezone(const TimeZone *timeZone,
intl_error *outside_error,
zval *ret)
{
UnicodeString id;
php_timezone_obj *tzobj;
zval arg;
UnicodeString id;
timeZone->getID(id);
if (id.isBogus()) {
intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR,
"could not obtain TimeZone id");
goto error;
return nullptr;
}
object_init_ex(ret, php_date_get_timezone_ce());
tzobj = Z_PHPTIMEZONE_P(ret);
if (id.compare(0, 3, UnicodeString("GMT", sizeof("GMT")-1, US_INV)) == 0) {
/* The DateTimeZone constructor doesn't support offset time zones,
* so we must mess with DateTimeZone structure ourselves */
tzobj->initialized = 1;
* so we must mess with DateTimeZone structure ourselves */
object_init_ex(ret, php_date_get_timezone_ce());
php_timezone_obj *tzobj = Z_PHPTIMEZONE_P(ret);
tzobj->initialized = true;
tzobj->type = TIMELIB_ZONETYPE_OFFSET;
//convert offset from milliseconds to seconds
tzobj->tzi.utc_offset = timeZone->getRawOffset() / 1000;
} else {
zend_string *u8str;
/* Call the constructor! */
u8str = intl_charFromString(id, &INTL_ERROR_CODE(*outside_error));
zend_string *u8str = intl_charFromString(id, &INTL_ERROR_CODE(*outside_error));
if (!u8str) {
intl_errors_set(outside_error, INTL_ERROR_CODE(*outside_error),
"could not convert id to UTF-8");
goto error;
return nullptr;
}
zval arg;
ZVAL_STR(&arg, u8str);
zend_call_known_instance_method_with_1_params(
Z_OBJCE_P(ret)->constructor, Z_OBJ_P(ret), NULL, &arg);
if (EG(exception)) {
intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR,
"DateTimeZone constructor threw exception");
zend_object_store_ctor_failed(Z_OBJ_P(ret));
zval_ptr_dtor(&arg);
goto error;
}
/* Instantiate the object and call the constructor */
zend_result status = object_init_with_constructor(ret, php_date_get_timezone_ce(), 1, &arg, nullptr);
zval_ptr_dtor(&arg);
if (UNEXPECTED(status == FAILURE)) {
zend_throw_exception(IntlException_ce_ptr, "DateTimeZone constructor threw exception", 0);
return nullptr;
}
}
if (0) {
error:
if (ret) {
zval_ptr_dtor(ret);
}
ret = NULL;
}
return ret;
}
/* }}} */