diff --git a/ext/dom/node.c b/ext/dom/node.c
index a6f88b5c0f1bb..53e6457ca71d0 100644
--- a/ext/dom/node.c
+++ b/ext/dom/node.c
@@ -20,6 +20,7 @@
#endif
#include "php.h"
+
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
#include "php_dom.h"
@@ -976,6 +977,9 @@ PHP_METHOD(DOMNode, insertBefore)
new_child = _php_dom_insert_fragment(parentp, parentp->last, NULL, child, intern, childobj);
}
if (new_child == NULL) {
+ if (!child->ns && parentp->parent) {
+ xmlSetNs(child, parentp->ns);
+ }
new_child = xmlAddChild(parentp, child);
}
}
@@ -1220,6 +1224,9 @@ PHP_METHOD(DOMNode, appendChild)
}
if (new_child == NULL) {
+ if (!child->ns && nodep->parent) {
+ xmlSetNs(child, nodep->ns);
+ }
new_child = xmlAddChild(nodep, child);
if (new_child == NULL) {
// TODO Convert to Error?
@@ -1668,7 +1675,7 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{
buf = xmlAllocOutputBuffer(NULL);
}
- if (buf != NULL) {
+ if (buf != NULL) {
ret = xmlC14NDocSaveTo(docp, nodeset, exclusive, inclusive_ns_prefixes,
with_comments, buf);
}
@@ -1683,9 +1690,9 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{
xmlXPathFreeContext(ctxp);
}
- if (buf == NULL || ret < 0) {
- RETVAL_FALSE;
- } else {
+ if (buf == NULL || ret < 0) {
+ RETVAL_FALSE;
+ } else {
if (mode == 0) {
#ifdef LIBXML2_NEW_BUFFER
ret = xmlOutputBufferGetSize(buf);
@@ -1702,7 +1709,7 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{
RETVAL_EMPTY_STRING();
}
}
- }
+ }
if (buf) {
int bytes;
diff --git a/ext/dom/tests/bug81468.phpt b/ext/dom/tests/bug81468.phpt
new file mode 100644
index 0000000000000..5900ca0ff6afd
--- /dev/null
+++ b/ext/dom/tests/bug81468.phpt
@@ -0,0 +1,175 @@
+--TEST--
+Bug #81468 (Inconsistent default namespace inheritance)
+--SKIPIF--
+
+--FILE--
+appendChild($dom->createElementNS('some:namespace', 'foo'))
+ ->appendChild($dom->createElement('bar'));
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar')) . " should be 1\n\n";
+
+$dom = new \DOMDocument();
+$dom->loadXml($xml);
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar')) . " should be 1\n\n";
+
+
+$dom = new \DOMDocument();
+$dom
+ ->appendChild($dom->createElementNS('some:namespace', 'foo'))
+ ->appendChild($dom->createElementNS('some:namespace_test', 'bar'));
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+$xpath->registerNamespace('m', 'some:namespace_test');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/m:bar')) . " should be 1\n\n";
+
+$dom = new \DOMDocument();
+$dom->loadXml($xml);
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+$xpath->registerNamespace('m', 'some:namespace_test');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/m:bar')) . " should be 1\n\n";
+
+$dom = new \DOMDocument();
+$dom
+ ->appendChild($dom->createElement('bar'))
+ ->appendChild($dom->createElementNS('some:namespace', 'foo'));
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+echo count($xpath->query('/bar/n:foo')) . " should be 1\n";
+echo count($xpath->query('/bar/foo')) . " should be 0\n\n";
+
+
+
+$dom = new \DOMDocument();
+$dom
+ ->appendChild($dom->createElementNS('some:namespace', 'foo'))
+ ->appendChild($dom->createElement('bar'))
+ ->appendChild($dom->createElement('baz'));
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar')) . " should be 1\n";
+echo count($xpath->query('/n:foo/n:bar/baz')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar/n:baz')) . " should be 1\n\n";
+
+$dom = new \DOMDocument();
+$dom->loadXml($xml);
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar')) . " should be 1\n";
+echo count($xpath->query('/n:foo/n:bar/baz')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar/n:baz')) . " should be 1\n\n";
+
+
+$dom = new \DOMDocument();
+$dom
+ ->appendChild($dom->createElementNS('some:namespace', 'foo'))
+ ->appendChild($dom->createElementNS('some:namespace_test', 'bar'))
+ ->appendChild($dom->createElement('baz'));
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+$xpath->registerNamespace('m', 'some:namespace_test');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/m:bar')) . " should be 1\n";
+echo count($xpath->query('/n:foo/m:bar/baz')) . " should be 0\n";
+echo count($xpath->query('/n:foo/m:bar/m:baz')) . " should be 1\n\n";
+
+$dom = new \DOMDocument();
+$dom->loadXml($xml);
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+$xpath->registerNamespace('m', 'some:namespace_test');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/m:bar')) . " should be 1\n";
+echo count($xpath->query('/n:foo/m:bar/baz')) . " should be 0\n";
+echo count($xpath->query('/n:foo/m:bar/m:baz')) . " should be 1\n\n";
+
+?>
+--EXPECT--
+
+
+0 should be 0
+1 should be 1
+
+
+
+0 should be 0
+1 should be 1
+
+
+
+0 should be 0
+0 should be 0
+1 should be 1
+
+
+
+0 should be 0
+0 should be 0
+1 should be 1
+
+
+
+1 should be 1
+0 should be 0
+
+
+
+0 should be 0
+1 should be 1
+0 should be 0
+1 should be 1
+
+
+
+0 should be 0
+1 should be 1
+0 should be 0
+1 should be 1
+
+
+
+0 should be 0
+1 should be 1
+0 should be 0
+1 should be 1
+
+
+
+0 should be 0
+1 should be 1
+0 should be 0
+1 should be 1
diff --git a/ext/dom/tests/bug81468_2.phpt b/ext/dom/tests/bug81468_2.phpt
new file mode 100644
index 0000000000000..9a3a89267792e
--- /dev/null
+++ b/ext/dom/tests/bug81468_2.phpt
@@ -0,0 +1,175 @@
+--TEST--
+Bug #81468 (Inconsistent default namespace inheritance)
+--SKIPIF--
+
+--FILE--
+insertBefore($dom->createElementNS('some:namespace', 'foo'))
+ ->insertBefore($dom->createElement('bar'));
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar')) . " should be 1\n\n";
+
+$dom = new \DOMDocument();
+$dom->loadXml($xml);
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar')) . " should be 1\n\n";
+
+
+$dom = new \DOMDocument();
+$dom
+ ->insertBefore($dom->createElementNS('some:namespace', 'foo'))
+ ->insertBefore($dom->createElementNS('some:namespace_test', 'bar'));
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+$xpath->registerNamespace('m', 'some:namespace_test');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/m:bar')) . " should be 1\n\n";
+
+$dom = new \DOMDocument();
+$dom->loadXml($xml);
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+$xpath->registerNamespace('m', 'some:namespace_test');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/m:bar')) . " should be 1\n\n";
+
+$dom = new \DOMDocument();
+$dom
+ ->insertBefore($dom->createElement('bar'))
+ ->insertBefore($dom->createElementNS('some:namespace', 'foo'));
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+echo count($xpath->query('/bar/n:foo')) . " should be 1\n";
+echo count($xpath->query('/bar/foo')) . " should be 0\n\n";
+
+
+
+$dom = new \DOMDocument();
+$dom
+ ->insertBefore($dom->createElementNS('some:namespace', 'foo'))
+ ->insertBefore($dom->createElement('bar'))
+ ->insertBefore($dom->createElement('baz'));
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar')) . " should be 1\n";
+echo count($xpath->query('/n:foo/n:bar/baz')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar/n:baz')) . " should be 1\n\n";
+
+$dom = new \DOMDocument();
+$dom->loadXml($xml);
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar')) . " should be 1\n";
+echo count($xpath->query('/n:foo/n:bar/baz')) . " should be 0\n";
+echo count($xpath->query('/n:foo/n:bar/n:baz')) . " should be 1\n\n";
+
+
+$dom = new \DOMDocument();
+$dom
+ ->insertBefore($dom->createElementNS('some:namespace', 'foo'))
+ ->insertBefore($dom->createElementNS('some:namespace_test', 'bar'))
+ ->insertBefore($dom->createElement('baz'));
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+$xpath->registerNamespace('m', 'some:namespace_test');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/m:bar')) . " should be 1\n";
+echo count($xpath->query('/n:foo/m:bar/baz')) . " should be 0\n";
+echo count($xpath->query('/n:foo/m:bar/m:baz')) . " should be 1\n\n";
+
+$dom = new \DOMDocument();
+$dom->loadXml($xml);
+echo ($xml = $dom->saveXML());
+
+$xpath = new \DOMXPath($dom);
+$xpath->registerNamespace('n', 'some:namespace');
+$xpath->registerNamespace('m', 'some:namespace_test');
+echo count($xpath->query('/n:foo/bar')) . " should be 0\n";
+echo count($xpath->query('/n:foo/m:bar')) . " should be 1\n";
+echo count($xpath->query('/n:foo/m:bar/baz')) . " should be 0\n";
+echo count($xpath->query('/n:foo/m:bar/m:baz')) . " should be 1\n\n";
+
+?>
+--EXPECT--
+
+
+0 should be 0
+1 should be 1
+
+
+
+0 should be 0
+1 should be 1
+
+
+
+0 should be 0
+0 should be 0
+1 should be 1
+
+
+
+0 should be 0
+0 should be 0
+1 should be 1
+
+
+
+1 should be 1
+0 should be 0
+
+
+
+0 should be 0
+1 should be 1
+0 should be 0
+1 should be 1
+
+
+
+0 should be 0
+1 should be 1
+0 should be 0
+1 should be 1
+
+
+
+0 should be 0
+1 should be 1
+0 should be 0
+1 should be 1
+
+
+
+0 should be 0
+1 should be 1
+0 should be 0
+1 should be 1