From 88ff32a25ba0dbf8b0ce2f7afc3828dac940bd78 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 29 May 2024 17:49:07 +0200 Subject: [PATCH 1/2] Fix GH-14343: Memory leak in xml and dom (#14347) If there is no root, the namespace cannot be attached to it, so we have to attach it to the old list. This isn't a problem in "new DOM" because namespaces are managed in a separate structure there. --- NEWS | 3 +++ ext/dom/document.c | 7 ++++++- ext/dom/tests/gh14343.phpt | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 ext/dom/tests/gh14343.phpt diff --git a/NEWS b/NEWS index d7838aa7f4c..a0d7027019c 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,9 @@ PHP NEWS - Curl: . Fixed bug GH-14307 (Test curl_basic_024 fails with curl 8.8.0). (nielsdos) +- DOM: + . Fixed bug GH-14343 (Memory leak in xml and dom). (nielsdos) + - Opcache: . Fixed bug GH-14267 (opcache.jit=off does not allow enabling JIT at runtime). (ilutov) diff --git a/ext/dom/document.c b/ext/dom/document.c index 8312d6c5939..a2772479cfe 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -848,8 +848,13 @@ PHP_METHOD(DOMDocument, importNode) if (nsptr == NULL) { int errorcode; nsptr = dom_get_ns(root, (char *) nodep->ns->href, &errorcode, (char *) nodep->ns->prefix); + + /* If there is no root, the namespace cannot be attached to it, so we have to attach it to the old list. */ + if (nsptr != NULL && root == NULL) { + dom_set_old_ns(nodep->doc, nsptr); + } } - xmlSetNs(retnodep, nsptr); + retnodep->ns = nsptr; } } diff --git a/ext/dom/tests/gh14343.phpt b/ext/dom/tests/gh14343.phpt new file mode 100644 index 00000000000..7cece29f4cd --- /dev/null +++ b/ext/dom/tests/gh14343.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-14343 (Memory leak in xml and dom) +--EXTENSIONS-- +dom +--FILE-- +loadXML(''); +$attr= $fromdom->firstChild->attributes->item(0); +$att = $aDOM->importNode($attr); +echo $aDOM->saveXML($att); +?> +--EXPECT-- + ai:attr="namespaced" From ce7ed6e040f4c57604a19e6a7d2ed5e401f6f02d Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 29 May 2024 17:50:20 +0200 Subject: [PATCH 2/2] Fix bug #47925 again (#14348) The naming of the userland functions is terrible and confused me. gzdecode() is actually the function to decompress a gzip stream, and gzuncompress() is the one to decompress a deflate stream... See zlib.c to see the internal function -> type mapping. --- ext/soap/php_http.c | 10 ++++++---- ext/soap/tests/bugs/bug47925.phpt | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index f60f8b21caa..03db4ac4370 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -1256,14 +1256,16 @@ try_again: zval retval; zval params[1]; + /* Warning: the zlib function names are chosen in an unfortunate manner. + * Check zlib.c to see how a function corresponds with a particular format. */ if ((strcmp(content_encoding,"gzip") == 0 || strcmp(content_encoding,"x-gzip") == 0) && - zend_hash_str_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress")-1)) { - ZVAL_STRING(&func, "gzuncompress"); + zend_hash_str_exists(EG(function_table), "gzdecode", sizeof("gzdecode")-1)) { + ZVAL_STRING(&func, "gzdecode"); ZVAL_STR_COPY(¶ms[0], http_body); } else if (strcmp(content_encoding,"deflate") == 0 && - zend_hash_str_exists(EG(function_table), "gzinflate", sizeof("gzinflate")-1)) { - ZVAL_STRING(&func, "gzinflate"); + zend_hash_str_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress")-1)) { + ZVAL_STRING(&func, "gzuncompress"); ZVAL_STR_COPY(¶ms[0], http_body); } else { efree(content_encoding); diff --git a/ext/soap/tests/bugs/bug47925.phpt b/ext/soap/tests/bugs/bug47925.phpt index ce14c7f4676..ab7881d4abe 100644 --- a/ext/soap/tests/bugs/bug47925.phpt +++ b/ext/soap/tests/bugs/bug47925.phpt @@ -32,8 +32,8 @@ function test($compressed_response, $compression_name) { http_server_kill($pid); } -test(gzcompress($plain_response), "gzip"); -test(gzdeflate($plain_response), "deflate"); +test(gzencode($plain_response), "gzip"); +test(gzcompress($plain_response), "deflate"); ?> --EXPECT-- int(7)