From 7779d194c15cfd43ddf048c999fc065563f24011 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Sun, 16 Aug 2026 11:18:39 -0400 Subject: [PATCH] Fix Calendar::createInstance double-free of the adopted TimeZone ICU 57+ Calendar::createInstance wraps the TimeZone in a LocalPointer and deletes it when the calendar cannot be created. PHP deleted the same pointer again on that failure. Drop the extra delete in createInstance and fromDateTime. --- NEWS | 4 ++++ ext/intl/calendar/calendar_methods.cpp | 2 -- ...alendar_createinstance_adopt_timezone.phpt | 24 +++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 ext/intl/tests/calendar_createinstance_adopt_timezone.phpt diff --git a/NEWS b/NEWS index 9977ea3b3409..36d506a6babf 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,10 @@ PHP NEWS left busy for the next fetch, and rows delivered from a result another statement took over. (KentarouTakeda) +- Intl: + . Fixed a double-free when Calendar::createInstance() or + IntlCalendar::fromDateTime() fails after adopting a TimeZone. (iliaal) + - Phar: . Fixed Phar archives being automatically detected when ".phar" only occurs in a directory name or is not a filename extension in an included file's diff --git a/ext/intl/calendar/calendar_methods.cpp b/ext/intl/calendar/calendar_methods.cpp index 0c6e68a65e21..f4c9cb36cded 100644 --- a/ext/intl/calendar/calendar_methods.cpp +++ b/ext/intl/calendar/calendar_methods.cpp @@ -96,7 +96,6 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(intlcal_create_instance) Calendar *cal = Calendar::createInstance(timeZone, Locale::createFromName(locale_str), status); if (UNEXPECTED(cal == NULL)) { - delete timeZone; intl_error_set(NULL, status, "Error creating ICU Calendar object"); RETURN_NULL(); } @@ -1073,7 +1072,6 @@ PHP_INTL_FUNCTION_WITH_ERROR_RESET(intlcal_from_date_time) cal = Calendar::createInstance(timeZone, Locale::createFromName(locale_str), status); if (UNEXPECTED(cal == NULL)) { - delete timeZone; intl_error_set(NULL, status, "error creating ICU Calendar object"); goto error; diff --git a/ext/intl/tests/calendar_createinstance_adopt_timezone.phpt b/ext/intl/tests/calendar_createinstance_adopt_timezone.phpt new file mode 100644 index 000000000000..d5c8cd0ba87d --- /dev/null +++ b/ext/intl/tests/calendar_createinstance_adopt_timezone.phpt @@ -0,0 +1,24 @@ +--TEST-- +IntlCalendar::createInstance() and fromDateTime() adopt the TimeZone +--EXTENSIONS-- +intl +--INI-- +date.timezone=UTC +--FILE-- +getTimeZone()->getID(), "\n"; +echo $cal->getType(), "\n"; + +$dt = new DateTime('2024-01-15 12:00:00', new DateTimeZone('America/New_York')); +$cal2 = IntlCalendar::fromDateTime($dt, 'en_US'); +echo $cal2->getTimeZone()->getID(), "\n"; +echo $cal2->getType(), "\n"; + +?> +--EXPECT-- +Europe/Amsterdam +gregorian +America/New_York +gregorian