From 0ee79b2b17437f8401d280b3eea7858cf851d641 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Tue, 30 Apr 2024 20:50:30 +0200
Subject: [PATCH 1/2] Add test with wrong output
---
ext/dom/tests/DOMNode_C14N_references.phpt | 45 ++++++++++++++++++++++
1 file changed, 45 insertions(+)
create mode 100644 ext/dom/tests/DOMNode_C14N_references.phpt
diff --git a/ext/dom/tests/DOMNode_C14N_references.phpt b/ext/dom/tests/DOMNode_C14N_references.phpt
new file mode 100644
index 000000000000..2bda9c708264
--- /dev/null
+++ b/ext/dom/tests/DOMNode_C14N_references.phpt
@@ -0,0 +1,45 @@
+--TEST--
+Test: Canonicalization - C14N() with references
+--EXTENSIONS--
+dom
+--FILE--
+
+
+
+
+
+
+
+
+EOXML;
+
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+$doc = $dom->documentElement->firstChild;
+
+$xpath = [
+ 'query' => '(//a:contain | //a:bar | .//namespace::*)',
+ 'namespaces' => ['a' => 'http://www.example.com/ns/foo'],
+];
+$prefixes = ['test'];
+
+foreach ($xpath['namespaces'] as $k => &$v);
+unset($v);
+foreach ($xpath as $k => &$v);
+unset($v);
+foreach ($prefixes as $k => &$v);
+unset($v);
+
+echo $doc->C14N(true, false, $xpath, $prefixes);
+?>
+--EXPECTF--
+Fatal error: Uncaught TypeError: DOMNode::C14N(): Argument #3 ($xpath) "query" option must be a string, string given in %s:%d
+Stack trace:
+#0 %s(%d): DOMNode->C14N(true, false, Array, Array)
+#1 {main}
+ thrown in %s on line %d
From 52effd0fe9ad2f9d44561b0d30df27fda60ca1c9 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Tue, 30 Apr 2024 20:53:04 +0200
Subject: [PATCH 2/2] Fix references not handled correctly in C14N
---
ext/dom/node.c | 5 +++--
ext/dom/tests/DOMNode_C14N_references.phpt | 8 ++------
2 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/ext/dom/node.c b/ext/dom/node.c
index 973505c5b01a..82f40860cfd3 100644
--- a/ext/dom/node.c
+++ b/ext/dom/node.c
@@ -1614,7 +1614,7 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{
zval *tmp;
char *xquery;
- tmp = zend_hash_str_find(ht, "query", sizeof("query")-1);
+ tmp = zend_hash_str_find_deref(ht, "query", sizeof("query")-1);
if (!tmp) {
/* if mode == 0 then $xpath arg is 3, if mode == 1 then $xpath is 4 */
zend_argument_value_error(3 + mode, "must have a \"query\" key");
@@ -1630,12 +1630,13 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{
ctxp = xmlXPathNewContext(docp);
ctxp->node = nodep;
- tmp = zend_hash_str_find(ht, "namespaces", sizeof("namespaces")-1);
+ tmp = zend_hash_str_find_deref(ht, "namespaces", sizeof("namespaces")-1);
if (tmp && Z_TYPE_P(tmp) == IS_ARRAY && !HT_IS_PACKED(Z_ARRVAL_P(tmp))) {
zval *tmpns;
zend_string *prefix;
ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(tmp), prefix, tmpns) {
+ ZVAL_DEREF(tmpns);
if (Z_TYPE_P(tmpns) == IS_STRING) {
if (prefix) {
xmlXPathRegisterNs(ctxp, (xmlChar *) ZSTR_VAL(prefix), (xmlChar *) Z_STRVAL_P(tmpns));
diff --git a/ext/dom/tests/DOMNode_C14N_references.phpt b/ext/dom/tests/DOMNode_C14N_references.phpt
index 2bda9c708264..514e22be6365 100644
--- a/ext/dom/tests/DOMNode_C14N_references.phpt
+++ b/ext/dom/tests/DOMNode_C14N_references.phpt
@@ -37,9 +37,5 @@ unset($v);
echo $doc->C14N(true, false, $xpath, $prefixes);
?>
---EXPECTF--
-Fatal error: Uncaught TypeError: DOMNode::C14N(): Argument #3 ($xpath) "query" option must be a string, string given in %s:%d
-Stack trace:
-#0 %s(%d): DOMNode->C14N(true, false, Array, Array)
-#1 {main}
- thrown in %s on line %d
+--EXPECT--
+