[php-src] Issue #24235: DateTime::createFromFormat() segfaults when "!" follows a parsed time zone and the passed zone is an abbreviation or offset

From: Date: Sat, 10 Oct 2026 08:07:06 +0000
Subject: [php-src] Issue #24235: DateTime::createFromFormat() segfaults when "!" follows a parsed time zone and the passed zone is an abbreviation or offset
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-252964@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/24235 Author: zonuexe ### Description The following code: ```php <?php date_default_timezone_set('Europe/London'); var_dump(DateTime::createFromFormat('e !Y-m-d H:i', 'Europe/London 2024-10-27 01:30', new DateTimeZone('EST'))); ``` Resulted in this output: ``` Segmentation fault (exit status 139) ``` But I expected this output instead: ``` object(DateTime)#2 (3) { ["date"]=> string(26) "2024-10-27 01:30:00.000000" ["timezone_type"]=> int(2) ["timezone"]=> string(3) "EST" } ``` The input is valid and matches the format. It is not malformed input that the parser fails to reject. Invalid input is handled correctly, and the same input works in every other combination: | Call | Result | | --- | --- | | createFromFormat('e !Y-m-d H:i', 'Nowhere/Invalid 2024-10-27 01:30', new DateTimeZone('EST')) | false | | createFromFormat('e !Y-m-d H:i', 'Europe/London 2024-10-27 01:30') | works | | createFromFormat('e !Y-m-d H:i', 'Europe/London 2024-10-27 01:30', new DateTimeZone('UTC')) | works | | createFromFormat('!Y-m-d H:i', '2024-10-27 01:30', new DateTimeZone('EST')) | works | | createFromFormat('e !Y-m-d H:i', 'Europe/London 2024-10-27 01:30', new DateTimeZone('EST')) | **segfault** | The crash needs all three of these together: - a zone parsed from the string; - a later ! (or a trailing !, as in 'Y-m-d H:i e!'); - a passed or default zone that is an abbreviation (EST) or an offset (+01:00) rather than an identifier. DateTimeImmutable::createFromFormat() and date_create_from_format() crash the same way. The cause is in timelib's timelib_time_reset_fields(), which runs for !. It clears tz_info but keeps the zone type of the zone parsed before it. When the fallback zone is not an identifier, nothing refills tz_info. The result is an identifier-type zone with a NULL tz_info, which date_format() dereferences in timelib_fetch_timezone_offset(). ### PHP Version ``` PHP 8.5.11 (cli) (built: Sep 22 2026 13:32:06) (NTS) Copyright (c) The PHP Group Built by Homebrew Zend Engine v4.5.11, Copyright (c) Zend Technologies with Zend OPcache v8.5.11, Copyright (c), by Zend Technologies ``` Also reproduced on PHP 8.4.25 and on debug builds of PHP-8.4 and master. ### Operating System macOS (arm64); not platform specific

« previous php.bugs (#252964) next »