-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
601 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
From 774f90ee277e32b6881328838c0b19724d01a995 Mon Sep 17 00:00:00 2001 | ||
From: Jan Tojnar <[email protected]> | ||
Date: Sat, 24 Aug 2024 13:17:44 +0200 | ||
Subject: [PATCH] Fix memory leak when setting an invalid DOMDocument encoding | ||
|
||
Because the failure path did not release the string, there was a memory | ||
leak. | ||
As the only valid types for this function are IS_NULL and IS_STRING, we | ||
and IS_NULL is always rejected in practice, solve the issue by not using | ||
a function that increments the refcount in the first place. | ||
|
||
Closes GH-12002. | ||
|
||
Cherry-picked from aff365871aec54c9a556d7667f131b8638d20194 (only ext/dom/document.c) | ||
Cherry-picked from 20ac42e1b065e23376e7ea548995636369809a7d (sans NEWS) | ||
--- | ||
ext/dom/document.c | 29 +++++++++++++++++------------ | ||
ext/dom/tests/gh12002.phpt | 38 ++++++++++++++++++++++++++++++++++++++ | ||
2 files changed, 55 insertions(+), 12 deletions(-) | ||
create mode 100644 ext/dom/tests/gh12002.phpt | ||
|
||
diff --git a/ext/dom/document.c b/ext/dom/document.c | ||
index 7735e5d5dc..45b502d427 100644 | ||
--- a/ext/dom/document.c | ||
+++ b/ext/dom/document.c | ||
@@ -139,7 +139,6 @@ int dom_document_encoding_read(dom_object *obj, zval *retval) | ||
zend_result dom_document_encoding_write(dom_object *obj, zval *newval) | ||
{ | ||
xmlDoc *docp = (xmlDocPtr) dom_object_get_node(obj); | ||
- zend_string *str; | ||
xmlCharEncodingHandlerPtr handler; | ||
|
||
if (docp == NULL) { | ||
@@ -147,26 +146,32 @@ zend_result dom_document_encoding_write(dom_object *obj, zval *newval) | ||
return FAILURE; | ||
} | ||
|
||
- str = zval_try_get_string(newval); | ||
- if (UNEXPECTED(!str)) { | ||
- return FAILURE; | ||
+ /* Typed property, can only be IS_STRING or IS_NULL. */ | ||
+ ZEND_ASSERT(Z_TYPE_P(newval) == IS_STRING || Z_TYPE_P(newval) == IS_NULL); | ||
+ | ||
+ if (Z_TYPE_P(newval) == IS_NULL) { | ||
+ goto invalid_encoding; | ||
} | ||
|
||
+ zend_string *str = Z_STR_P(newval); | ||
+ | ||
handler = xmlFindCharEncodingHandler(ZSTR_VAL(str)); | ||
|
||
- if (handler != NULL) { | ||
+ if (handler != NULL) { | ||
xmlCharEncCloseFunc(handler); | ||
if (docp->encoding != NULL) { | ||
xmlFree((xmlChar *)docp->encoding); | ||
} | ||
docp->encoding = xmlStrdup((const xmlChar *) ZSTR_VAL(str)); | ||
- } else { | ||
- zend_value_error("Invalid document encoding"); | ||
- return FAILURE; | ||
- } | ||
+ } else { | ||
+ goto invalid_encoding; | ||
+ } | ||
|
||
- zend_string_release_ex(str, 0); | ||
return SUCCESS; | ||
+ | ||
+invalid_encoding: | ||
+ zend_value_error("Invalid document encoding"); | ||
+ return FAILURE; | ||
} | ||
|
||
/* }}} */ | ||
@@ -1166,8 +1171,8 @@ char *_dom_get_valid_file_path(char *source, char *resolved_path, int resolved_p | ||
|
||
static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, size_t source_len, size_t options) /* {{{ */ | ||
{ | ||
- xmlDocPtr ret; | ||
- xmlParserCtxtPtr ctxt = NULL; | ||
+ xmlDocPtr ret; | ||
+ xmlParserCtxtPtr ctxt = NULL; | ||
dom_doc_propsptr doc_props; | ||
dom_object *intern; | ||
php_libxml_ref_obj *document = NULL; | ||
diff --git a/ext/dom/tests/gh12002.phpt b/ext/dom/tests/gh12002.phpt | ||
new file mode 100644 | ||
index 0000000000..7d1ae94464 | ||
--- /dev/null | ||
+++ b/ext/dom/tests/gh12002.phpt | ||
@@ -0,0 +1,38 @@ | ||
+--TEST-- | ||
+GH-12002 (DOMDocument::encoding memory leak with invalid encoding) | ||
+--EXTENSIONS-- | ||
+dom | ||
+--FILE-- | ||
+<?php | ||
+ | ||
+function make_nonconst(string $x) { | ||
+ // Defeat SCCP, even with inlining | ||
+ return str_repeat($x, random_int(1, 1)); | ||
+} | ||
+ | ||
+$dom = new DOMDocument(); | ||
+$dom->encoding = make_nonconst('utf-8'); | ||
+var_dump($dom->encoding); | ||
+try { | ||
+ $dom->encoding = make_nonconst('foobar'); | ||
+} catch (ValueError $e) { | ||
+ echo $e->getMessage(), "\n"; | ||
+} | ||
+var_dump($dom->encoding); | ||
+$dom->encoding = make_nonconst('utf-16le'); | ||
+var_dump($dom->encoding); | ||
+try { | ||
+ $dom->encoding = NULL; | ||
+} catch (ValueError $e) { | ||
+ echo $e->getMessage(), "\n"; | ||
+} | ||
+var_dump($dom->encoding); | ||
+ | ||
+?> | ||
+--EXPECT-- | ||
+string(5) "utf-8" | ||
+Invalid document encoding | ||
+string(5) "utf-8" | ||
+string(8) "utf-16le" | ||
+Invalid document encoding | ||
+string(8) "utf-16le" | ||
-- | ||
2.45.2 | ||
|
22 changes: 22 additions & 0 deletions
22
pkgs/patches/php80-libxml213-compatibility-simplexml.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
From 94160e6ef7561c8915992d9b3ba7a8bb821b498d Mon Sep 17 00:00:00 2001 | ||
From: Niels Dossche <[email protected]> | ||
Date: Thu, 4 Jul 2024 06:29:50 -0700 | ||
Subject: [PATCH] Backport libxml2 2.13.2 fixes (#14816) | ||
|
||
Backproted from https://github.com/php/php-src/pull/14789 | ||
|
||
Picked simplexml part from https://github.com/php/php-src/commit/4fe821311cafb18ca8bdf20b9d796c48a13ba552 | ||
|
||
diff --git a/ext/simplexml/tests/bug79971_1.phpt b/ext/simplexml/tests/bug79971_1.phpt | ||
index 197776d82d..2ee24e89f1 100644 | ||
--- a/ext/simplexml/tests/bug79971_1.phpt | ||
+++ b/ext/simplexml/tests/bug79971_1.phpt | ||
@@ -20,7 +20,7 @@ var_dump($sxe->asXML("$uri.out%00foo")); | ||
--EXPECTF-- | ||
Warning: simplexml_load_file(): URI must not contain percent-encoded NUL bytes in %s on line %d | ||
|
||
-Warning: simplexml_load_file(): I/O warning : failed to load external entity "%s/bug79971_1.xml%00foo" in %s on line %d | ||
+Warning: simplexml_load_file(): I/O warning : failed to load %s | ||
bool(false) | ||
|
||
Warning: SimpleXMLElement::asXML(): URI must not contain percent-encoded NUL bytes in %s on line %d |
Oops, something went wrong.