From 3f8efc2f054ea230d8948e74dcb9b13e41273e90 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Wed, 5 Aug 2026 09:16:12 -0400 Subject: [PATCH] Reject embedded NUL in SimpleXMLElement path/URL constructor When dataIsURL is true, __construct parsed the path as a plain string and passed it to xmlReadFile, so an embedded NUL truncated the path. simplexml_load_file already rejects NULs via the path parameter type. Match that check before xmlReadFile. Closes GH-23069 --- NEWS | 4 +++ ext/simplexml/simplexml.c | 5 ++++ .../tests/bug_sxe_ctor_nul_path.phpt | 26 +++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 ext/simplexml/tests/bug_sxe_ctor_nul_path.phpt diff --git a/NEWS b/NEWS index 474db936ef15..06f35fa08ee4 100644 --- a/NEWS +++ b/NEWS @@ -42,6 +42,10 @@ PHP NEWS . Fixed bug GH-23043 (broken session id code can cause zend_mm_heap corrupted). (ndossche) +- SimpleXML: + . Fixed SimpleXMLElement::__construct() accepting embedded null bytes in + URL/path mode. (iliaal) + - Sockets: . Fixed various memory related issues in ext/sockets. (David Carlier) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 8cf8e657e58f..4ae396b3fe1d 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -2334,6 +2334,11 @@ PHP_METHOD(SimpleXMLElement, __construct) RETURN_THROWS(); } + if (is_url && CHECK_NULL_PATH(data, data_len)) { + zend_argument_value_error(1, "must not contain any null bytes"); + RETURN_THROWS(); + } + PHP_LIBXML_SANITIZE_GLOBALS(read_file_or_memory); docp = is_url ? xmlReadFile(data, NULL, (int)options) : xmlReadMemory(data, (int)data_len, NULL, NULL, (int)options); PHP_LIBXML_RESTORE_GLOBALS(read_file_or_memory); diff --git a/ext/simplexml/tests/bug_sxe_ctor_nul_path.phpt b/ext/simplexml/tests/bug_sxe_ctor_nul_path.phpt new file mode 100644 index 000000000000..aea5396eac30 --- /dev/null +++ b/ext/simplexml/tests/bug_sxe_ctor_nul_path.phpt @@ -0,0 +1,26 @@ +--TEST-- +SimpleXMLElement constructor rejects embedded NUL in URL/path mode +--EXTENSIONS-- +simplexml +--FILE-- +'); +$path = $tmp . "\0evil"; +try { + new SimpleXMLElement($path, 0, true); + echo "ctor: loaded\n"; +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} +try { + simplexml_load_file($path); + echo "load_file: loaded\n"; +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} +unlink($tmp); +?> +--EXPECT-- +ValueError: SimpleXMLElement::__construct(): Argument #1 ($data) must not contain any null bytes +ValueError: simplexml_load_file(): Argument #1 ($filename) must not contain any null bytes