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