mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.3'
* PHP-8.3: Fix GH-12616: DOM: Removing XMLNS namespace node results in invalid default: prefix Fix GH-12702: libxml2 2.12.0 issue building from src
This commit is contained in:
@@ -862,6 +862,83 @@ PHP_METHOD(DOMElement, setAttributeNS)
|
||||
}
|
||||
/* }}} end dom_element_set_attribute_ns */
|
||||
|
||||
static void dom_remove_eliminated_ns_single_element(xmlNodePtr node, xmlNsPtr eliminatedNs)
|
||||
{
|
||||
ZEND_ASSERT(node->type == XML_ELEMENT_NODE);
|
||||
if (node->ns == eliminatedNs) {
|
||||
node->ns = NULL;
|
||||
}
|
||||
|
||||
for (xmlAttrPtr attr = node->properties; attr != NULL; attr = attr->next) {
|
||||
if (attr->ns == eliminatedNs) {
|
||||
attr->ns = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dom_remove_eliminated_ns(xmlNodePtr node, xmlNsPtr eliminatedNs)
|
||||
{
|
||||
dom_remove_eliminated_ns_single_element(node, eliminatedNs);
|
||||
|
||||
xmlNodePtr base = node;
|
||||
node = node->children;
|
||||
while (node != NULL) {
|
||||
ZEND_ASSERT(node != base);
|
||||
|
||||
if (node->type == XML_ELEMENT_NODE) {
|
||||
dom_remove_eliminated_ns_single_element(node, eliminatedNs);
|
||||
|
||||
if (node->children) {
|
||||
node = node->children;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (node->next) {
|
||||
node = node->next;
|
||||
} else {
|
||||
/* Go upwards, until we find a parent node with a next sibling, or until we hit the base. */
|
||||
do {
|
||||
node = node->parent;
|
||||
if (node == base) {
|
||||
return;
|
||||
}
|
||||
} while (node->next == NULL);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dom_eliminate_ns(xmlNodePtr nodep, xmlNsPtr nsptr)
|
||||
{
|
||||
if (nsptr->href != NULL) {
|
||||
xmlFree((char *) nsptr->href);
|
||||
nsptr->href = NULL;
|
||||
}
|
||||
if (nsptr->prefix != NULL) {
|
||||
xmlFree((char *) nsptr->prefix);
|
||||
nsptr->prefix = NULL;
|
||||
}
|
||||
|
||||
/* Remove it from the list and move it to the old ns list */
|
||||
xmlNsPtr current_ns = nodep->nsDef;
|
||||
if (current_ns == nsptr) {
|
||||
nodep->nsDef = nsptr->next;
|
||||
} else {
|
||||
do {
|
||||
if (current_ns->next == nsptr) {
|
||||
current_ns->next = nsptr->next;
|
||||
break;
|
||||
}
|
||||
current_ns = current_ns->next;
|
||||
} while (current_ns != NULL);
|
||||
}
|
||||
nsptr->next = NULL;
|
||||
php_libxml_set_old_ns(nodep->doc, nsptr);
|
||||
|
||||
dom_remove_eliminated_ns(nodep, nsptr);
|
||||
}
|
||||
|
||||
/* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElRemAtNS
|
||||
Since: DOM Level 2
|
||||
*/
|
||||
@@ -887,14 +964,7 @@ PHP_METHOD(DOMElement, removeAttributeNS)
|
||||
nsptr = dom_get_nsdecl(nodep, (xmlChar *)name);
|
||||
if (nsptr != NULL) {
|
||||
if (xmlStrEqual((xmlChar *)uri, nsptr->href)) {
|
||||
if (nsptr->href != NULL) {
|
||||
xmlFree((char *) nsptr->href);
|
||||
nsptr->href = NULL;
|
||||
}
|
||||
if (nsptr->prefix != NULL) {
|
||||
xmlFree((char *) nsptr->prefix);
|
||||
nsptr->prefix = NULL;
|
||||
}
|
||||
dom_eliminate_ns(nodep, nsptr);
|
||||
} else {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
36
ext/dom/tests/gh12616_1.phpt
Normal file
36
ext/dom/tests/gh12616_1.phpt
Normal file
@@ -0,0 +1,36 @@
|
||||
--TEST--
|
||||
GH-12616 (DOM: Removing XMLNS namespace node results in invalid default: prefix)
|
||||
--EXTENSIONS--
|
||||
dom
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$doc = new DOMDocument();
|
||||
$doc->loadXML(
|
||||
<<<XML
|
||||
<container xmlns="http://symfony.com/schema/dic/services">
|
||||
CHILDREN
|
||||
</container>
|
||||
XML
|
||||
);
|
||||
|
||||
$doc->documentElement->removeAttributeNS('http://symfony.com/schema/dic/services', '');
|
||||
echo $doc->saveXML();
|
||||
|
||||
$new = new DOMDocument();
|
||||
$new->append(
|
||||
$new->importNode($doc->documentElement, true)
|
||||
);
|
||||
|
||||
echo $new->saveXML();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
<?xml version="1.0"?>
|
||||
<container>
|
||||
CHILDREN
|
||||
</container>
|
||||
<?xml version="1.0"?>
|
||||
<container>
|
||||
CHILDREN
|
||||
</container>
|
||||
39
ext/dom/tests/gh12616_2.phpt
Normal file
39
ext/dom/tests/gh12616_2.phpt
Normal file
@@ -0,0 +1,39 @@
|
||||
--TEST--
|
||||
GH-12616 (DOM: Removing XMLNS namespace node results in invalid default: prefix)
|
||||
--EXTENSIONS--
|
||||
dom
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$doc = new DOMDocument();
|
||||
$doc->loadXML(
|
||||
<<<XML
|
||||
<container xmlns:test="urn:test" xmlns:symfony="http://symfony.com/schema/dic/services">
|
||||
<symfony:services>
|
||||
<test:service id="hello" />
|
||||
</symfony:services>
|
||||
</container>
|
||||
XML
|
||||
);
|
||||
|
||||
$doc->documentElement->removeAttributeNS('http://symfony.com/schema/dic/services', 'symfony');
|
||||
$xpath = new DOMXPath($doc);
|
||||
$xpath->registerNamespace('test', 'urn:test');
|
||||
|
||||
echo $doc->saveXML();
|
||||
|
||||
$result = $xpath->query('//container/services/test:service[@id="hello"]');
|
||||
var_dump($result);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
<?xml version="1.0"?>
|
||||
<container xmlns:test="urn:test">
|
||||
<services>
|
||||
<test:service id="hello"/>
|
||||
</services>
|
||||
</container>
|
||||
object(DOMNodeList)#4 (1) {
|
||||
["length"]=>
|
||||
int(1)
|
||||
}
|
||||
172
ext/dom/tests/gh12616_3.phpt
Normal file
172
ext/dom/tests/gh12616_3.phpt
Normal file
@@ -0,0 +1,172 @@
|
||||
--TEST--
|
||||
GH-12616 (DOM: Removing XMLNS namespace node results in invalid default: prefix)
|
||||
--EXTENSIONS--
|
||||
dom
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$doc = new DOMDocument();
|
||||
$doc->loadXML(
|
||||
<<<XML
|
||||
<container>
|
||||
<child1 xmlns:x="http://symfony.com/schema/dic/services">
|
||||
<x:foo x:bar=""/>
|
||||
<x:foo x:bar=""/>
|
||||
</child1>
|
||||
<child2 xmlns:x="http://symfony.com/schema/dic/services">
|
||||
<x:foo x:bar=""/>
|
||||
<x:foo x:bar=""/>
|
||||
</child2>
|
||||
</container>
|
||||
XML
|
||||
);
|
||||
|
||||
$doc->documentElement->firstElementChild->removeAttributeNS('http://symfony.com/schema/dic/services', 'x');
|
||||
echo $doc->saveXML();
|
||||
|
||||
$xpath = new DOMXPath($doc);
|
||||
|
||||
echo "--- Namespaces of child1 ---\n";
|
||||
|
||||
foreach ($xpath->query("/container/child1/namespace::*") as $ns) {
|
||||
var_dump($ns);
|
||||
}
|
||||
|
||||
echo "--- Namespaces of child1/foo (both nodes) ---\n";
|
||||
|
||||
foreach ($xpath->query("/container/child1/foo/namespace::*") as $ns) {
|
||||
var_dump($ns);
|
||||
}
|
||||
|
||||
echo "--- Namespaces of child2 ---\n";
|
||||
|
||||
foreach ($xpath->query("/container/child2/namespace::*") as $ns) {
|
||||
var_dump($ns);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
<?xml version="1.0"?>
|
||||
<container>
|
||||
<child1>
|
||||
<foo bar=""/>
|
||||
<foo bar=""/>
|
||||
</child1>
|
||||
<child2 xmlns:x="http://symfony.com/schema/dic/services">
|
||||
<x:foo x:bar=""/>
|
||||
<x:foo x:bar=""/>
|
||||
</child2>
|
||||
</container>
|
||||
--- Namespaces of child1 ---
|
||||
object(DOMNameSpaceNode)#4 (10) {
|
||||
["nodeName"]=>
|
||||
string(9) "xmlns:xml"
|
||||
["nodeValue"]=>
|
||||
string(36) "http://www.w3.org/XML/1998/namespace"
|
||||
["nodeType"]=>
|
||||
int(18)
|
||||
["prefix"]=>
|
||||
string(3) "xml"
|
||||
["localName"]=>
|
||||
string(3) "xml"
|
||||
["namespaceURI"]=>
|
||||
string(36) "http://www.w3.org/XML/1998/namespace"
|
||||
["isConnected"]=>
|
||||
bool(true)
|
||||
["ownerDocument"]=>
|
||||
string(22) "(object value omitted)"
|
||||
["parentNode"]=>
|
||||
string(22) "(object value omitted)"
|
||||
["parentElement"]=>
|
||||
string(22) "(object value omitted)"
|
||||
}
|
||||
--- Namespaces of child1/foo (both nodes) ---
|
||||
object(DOMNameSpaceNode)#5 (10) {
|
||||
["nodeName"]=>
|
||||
string(9) "xmlns:xml"
|
||||
["nodeValue"]=>
|
||||
string(36) "http://www.w3.org/XML/1998/namespace"
|
||||
["nodeType"]=>
|
||||
int(18)
|
||||
["prefix"]=>
|
||||
string(3) "xml"
|
||||
["localName"]=>
|
||||
string(3) "xml"
|
||||
["namespaceURI"]=>
|
||||
string(36) "http://www.w3.org/XML/1998/namespace"
|
||||
["isConnected"]=>
|
||||
bool(true)
|
||||
["ownerDocument"]=>
|
||||
string(22) "(object value omitted)"
|
||||
["parentNode"]=>
|
||||
string(22) "(object value omitted)"
|
||||
["parentElement"]=>
|
||||
string(22) "(object value omitted)"
|
||||
}
|
||||
object(DOMNameSpaceNode)#8 (10) {
|
||||
["nodeName"]=>
|
||||
string(9) "xmlns:xml"
|
||||
["nodeValue"]=>
|
||||
string(36) "http://www.w3.org/XML/1998/namespace"
|
||||
["nodeType"]=>
|
||||
int(18)
|
||||
["prefix"]=>
|
||||
string(3) "xml"
|
||||
["localName"]=>
|
||||
string(3) "xml"
|
||||
["namespaceURI"]=>
|
||||
string(36) "http://www.w3.org/XML/1998/namespace"
|
||||
["isConnected"]=>
|
||||
bool(true)
|
||||
["ownerDocument"]=>
|
||||
string(22) "(object value omitted)"
|
||||
["parentNode"]=>
|
||||
string(22) "(object value omitted)"
|
||||
["parentElement"]=>
|
||||
string(22) "(object value omitted)"
|
||||
}
|
||||
--- Namespaces of child2 ---
|
||||
object(DOMNameSpaceNode)#9 (10) {
|
||||
["nodeName"]=>
|
||||
string(9) "xmlns:xml"
|
||||
["nodeValue"]=>
|
||||
string(36) "http://www.w3.org/XML/1998/namespace"
|
||||
["nodeType"]=>
|
||||
int(18)
|
||||
["prefix"]=>
|
||||
string(3) "xml"
|
||||
["localName"]=>
|
||||
string(3) "xml"
|
||||
["namespaceURI"]=>
|
||||
string(36) "http://www.w3.org/XML/1998/namespace"
|
||||
["isConnected"]=>
|
||||
bool(true)
|
||||
["ownerDocument"]=>
|
||||
string(22) "(object value omitted)"
|
||||
["parentNode"]=>
|
||||
string(22) "(object value omitted)"
|
||||
["parentElement"]=>
|
||||
string(22) "(object value omitted)"
|
||||
}
|
||||
object(DOMNameSpaceNode)#5 (10) {
|
||||
["nodeName"]=>
|
||||
string(7) "xmlns:x"
|
||||
["nodeValue"]=>
|
||||
string(38) "http://symfony.com/schema/dic/services"
|
||||
["nodeType"]=>
|
||||
int(18)
|
||||
["prefix"]=>
|
||||
string(1) "x"
|
||||
["localName"]=>
|
||||
string(1) "x"
|
||||
["namespaceURI"]=>
|
||||
string(38) "http://symfony.com/schema/dic/services"
|
||||
["isConnected"]=>
|
||||
bool(true)
|
||||
["ownerDocument"]=>
|
||||
string(22) "(object value omitted)"
|
||||
["parentNode"]=>
|
||||
string(22) "(object value omitted)"
|
||||
["parentElement"]=>
|
||||
string(22) "(object value omitted)"
|
||||
}
|
||||
@@ -35,6 +35,7 @@ extern zend_module_entry libxml_module_entry;
|
||||
|
||||
#include "zend_smart_str.h"
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/parser.h>
|
||||
|
||||
#define LIBXML_SAVE_NOEMPTYTAG 1<<2
|
||||
|
||||
|
||||
Reference in New Issue
Block a user