Skip to content

Commit 807a05e

Browse files
committed
Merge branch 'PHP-8.2'
* PHP-8.2: Fix memory leak when setting an invalid DOMDocument encoding
2 parents 0d65f72 + 767697c commit 807a05e

File tree

2 files changed

+50
-7
lines changed

2 files changed

+50
-7
lines changed

ext/dom/document.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,19 +140,22 @@ int dom_document_encoding_read(dom_object *obj, zval *retval)
140140
zend_result dom_document_encoding_write(dom_object *obj, zval *newval)
141141
{
142142
xmlDoc *docp = (xmlDocPtr) dom_object_get_node(obj);
143-
zend_string *str;
144143
xmlCharEncodingHandlerPtr handler;
145144

146145
if (docp == NULL) {
147146
php_dom_throw_error(INVALID_STATE_ERR, 1);
148147
return FAILURE;
149148
}
150149

151-
str = zval_try_get_string(newval);
152-
if (UNEXPECTED(!str)) {
153-
return FAILURE;
150+
/* Typed property, can only be IS_STRING or IS_NULL. */
151+
ZEND_ASSERT(Z_TYPE_P(newval) == IS_STRING || Z_TYPE_P(newval) == IS_NULL);
152+
153+
if (Z_TYPE_P(newval) == IS_NULL) {
154+
goto invalid_encoding;
154155
}
155156

157+
zend_string *str = Z_STR_P(newval);
158+
156159
handler = xmlFindCharEncodingHandler(ZSTR_VAL(str));
157160

158161
if (handler != NULL) {
@@ -162,12 +165,14 @@ zend_result dom_document_encoding_write(dom_object *obj, zval *newval)
162165
}
163166
docp->encoding = xmlStrdup((const xmlChar *) ZSTR_VAL(str));
164167
} else {
165-
zend_value_error("Invalid document encoding");
166-
return FAILURE;
168+
goto invalid_encoding;
167169
}
168170

169-
zend_string_release_ex(str, 0);
170171
return SUCCESS;
172+
173+
invalid_encoding:
174+
zend_value_error("Invalid document encoding");
175+
return FAILURE;
171176
}
172177

173178
/* }}} */

ext/dom/tests/gh12002.phpt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
GH-12002 (DOMDocument::encoding memory leak with invalid encoding)
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
function make_nonconst(string $x) {
9+
// Defeat SCCP, even with inlining
10+
return str_repeat($x, random_int(1, 1));
11+
}
12+
13+
$dom = new DOMDocument();
14+
$dom->encoding = make_nonconst('utf-8');
15+
var_dump($dom->encoding);
16+
try {
17+
$dom->encoding = make_nonconst('foobar');
18+
} catch (ValueError $e) {
19+
echo $e->getMessage(), "\n";
20+
}
21+
var_dump($dom->encoding);
22+
$dom->encoding = make_nonconst('utf-16le');
23+
var_dump($dom->encoding);
24+
try {
25+
$dom->encoding = NULL;
26+
} catch (ValueError $e) {
27+
echo $e->getMessage(), "\n";
28+
}
29+
var_dump($dom->encoding);
30+
31+
?>
32+
--EXPECT--
33+
string(5) "utf-8"
34+
Invalid document encoding
35+
string(5) "utf-8"
36+
string(8) "utf-16le"
37+
Invalid document encoding
38+
string(8) "utf-16le"

0 commit comments

Comments
 (0)