1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Merge branch 'PHP-8.2'

* PHP-8.2:
  Fix empty argument cases for DOMParentNode methods
  Fix DOMCharacterData::replaceWith() with itself
  Fix incorrect attribute existence check in DOMElement::setAttributeNodeNS()
  Fix DOMEntity field getter bugs
This commit is contained in:
Niels Dossche
2023-07-24 19:04:55 +02:00
9 changed files with 274 additions and 36 deletions

View File

@@ -341,11 +341,11 @@ PHP_METHOD(DOMCharacterData, remove)
PHP_METHOD(DOMCharacterData, after)
{
uint32_t argc;
uint32_t argc = 0;
zval *args;
dom_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
RETURN_THROWS();
}
@@ -356,11 +356,11 @@ PHP_METHOD(DOMCharacterData, after)
PHP_METHOD(DOMCharacterData, before)
{
uint32_t argc;
uint32_t argc = 0;
zval *args;
dom_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
RETURN_THROWS();
}
@@ -371,18 +371,17 @@ PHP_METHOD(DOMCharacterData, before)
PHP_METHOD(DOMCharacterData, replaceWith)
{
uint32_t argc;
uint32_t argc = 0;
zval *args;
dom_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
RETURN_THROWS();
}
DOM_GET_THIS_INTERN(intern);
dom_parent_node_after(intern, args, argc);
dom_child_node_remove(intern);
dom_child_replace_with(intern, args, argc);
}
#endif

View File

@@ -2110,11 +2110,11 @@ Since: DOM Living Standard (DOM4)
*/
PHP_METHOD(DOMDocument, append)
{
uint32_t argc;
uint32_t argc = 0;
zval *args;
dom_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
RETURN_THROWS();
}
@@ -2129,11 +2129,11 @@ Since: DOM Living Standard (DOM4)
*/
PHP_METHOD(DOMDocument, prepend)
{
uint32_t argc;
uint32_t argc = 0;
zval *args;
dom_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
RETURN_THROWS();
}

View File

@@ -97,11 +97,11 @@ Since: DOM Living Standard (DOM4)
*/
PHP_METHOD(DOMDocumentFragment, append)
{
uint32_t argc;
uint32_t argc = 0;
zval *args;
dom_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
RETURN_THROWS();
}
@@ -116,11 +116,11 @@ Since: DOM Living Standard (DOM4)
*/
PHP_METHOD(DOMDocumentFragment, prepend)
{
uint32_t argc;
uint32_t argc = 0;
zval *args;
dom_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
RETURN_THROWS();
}

View File

@@ -944,7 +944,7 @@ PHP_METHOD(DOMElement, setAttributeNodeNS)
nsp = attrp->ns;
if (nsp != NULL) {
existattrp = xmlHasNsProp(nodep, nsp->href, attrp->name);
existattrp = xmlHasNsProp(nodep, attrp->name, nsp->href);
} else {
existattrp = xmlHasProp(nodep, attrp->name);
}
@@ -1194,11 +1194,11 @@ PHP_METHOD(DOMElement, remove)
PHP_METHOD(DOMElement, after)
{
uint32_t argc;
uint32_t argc = 0;
zval *args;
dom_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
RETURN_THROWS();
}
@@ -1209,11 +1209,11 @@ PHP_METHOD(DOMElement, after)
PHP_METHOD(DOMElement, before)
{
uint32_t argc;
uint32_t argc = 0;
zval *args;
dom_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
RETURN_THROWS();
}
@@ -1227,11 +1227,11 @@ Since: DOM Living Standard (DOM4)
*/
PHP_METHOD(DOMElement, append)
{
uint32_t argc;
uint32_t argc = 0;
zval *args;
dom_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
RETURN_THROWS();
}
@@ -1246,11 +1246,11 @@ Since: DOM Living Standard (DOM4)
*/
PHP_METHOD(DOMElement, prepend)
{
uint32_t argc;
uint32_t argc = 0;
zval *args;
dom_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
RETURN_THROWS();
}
@@ -1265,11 +1265,11 @@ Since: DOM Living Standard (DOM4)
*/
PHP_METHOD(DOMElement, replaceWith)
{
uint32_t argc;
uint32_t argc = 0;
zval *args;
dom_object *intern;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
RETURN_THROWS();
}

View File

@@ -27,13 +27,13 @@
/*
* class DOMEntity extends DOMNode
*
* URL: https://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-527DCFF2
* URL: https://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-527DCFF2
* Since:
*/
/* {{{ publicId string
readonly=yes
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-D7303025
URL: https://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D7303025
Since:
*/
int dom_entity_public_id_read(dom_object *obj, zval *retval)
@@ -45,7 +45,7 @@ int dom_entity_public_id_read(dom_object *obj, zval *retval)
return FAILURE;
}
if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY || !nodep->ExternalID) {
ZVAL_NULL(retval);
} else {
ZVAL_STRING(retval, (char *) (nodep->ExternalID));
@@ -58,7 +58,7 @@ int dom_entity_public_id_read(dom_object *obj, zval *retval)
/* {{{ systemId string
readonly=yes
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-D7C29F3E
URL: https://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D7C29F3E
Since:
*/
int dom_entity_system_id_read(dom_object *obj, zval *retval)
@@ -83,13 +83,12 @@ int dom_entity_system_id_read(dom_object *obj, zval *retval)
/* {{{ notationName string
readonly=yes
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-6ABAEB38
URL: https://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6ABAEB38
Since:
*/
int dom_entity_notation_name_read(dom_object *obj, zval *retval)
{
xmlEntity *nodep = (xmlEntity *) dom_object_get_node(obj);
char *content;
if (nodep == NULL) {
php_dom_throw_error(INVALID_STATE_ERR, 1);
@@ -99,9 +98,12 @@ int dom_entity_notation_name_read(dom_object *obj, zval *retval)
if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
ZVAL_NULL(retval);
} else {
content = (char *) xmlNodeGetContent((xmlNodePtr) nodep);
ZVAL_STRING(retval, content);
xmlFree(content);
/* According to spec, NULL is only allowed for unparsed entities, if it's not set we should use the empty string. */
if (!nodep->content) {
ZVAL_EMPTY_STRING(retval);
} else {
ZVAL_STRING(retval, (const char *) nodep->content);
}
}
return SUCCESS;

View File

@@ -0,0 +1,15 @@
--TEST--
DOMCharacterData::replaceWith() with itself
--EXTENSIONS--
dom
--FILE--
<?php
$dom = new DOMDocument;
$dom->loadXML('<?xml version="1.0"?><container><![CDATA[Hello]]></container>');
$cdata = $dom->documentElement->firstChild;
$cdata->replaceWith($cdata);
echo $dom->saveXML();
?>
--EXPECT--
<?xml version="1.0"?>
<container><![CDATA[Hello]]></container>

View File

@@ -0,0 +1,100 @@
--TEST--
DOMEntity fields
--EXTENSIONS--
dom
--FILE--
<?php
$xmlString = <<<XML
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY sampleInternalEntity "This is a sample entity value.">
<!ENTITY sampleExternalSystemWithNotationName SYSTEM "external.stuff" NDATA stuff>
<!ENTITY sampleExternalSystemWithoutNotationName SYSTEM "external.stuff" NDATA >
<!ENTITY sampleExternalPublicWithNotationName1 PUBLIC "public id" "external.stuff" NDATA stuff>
<!ENTITY sampleExternalPublicWithNotationName2 PUBLIC "" "external.stuff" NDATA stuff>
<!ENTITY sampleExternalPublicWithoutNotationName1 PUBLIC "public id" "external.stuff" NDATA >
<!ENTITY sampleExternalPublicWithoutNotationName2 PUBLIC "" "external.stuff" NDATA >
]>
<root/>
XML;
$dom = new DOMDocument();
$dom->loadXML($xmlString);
// Sort them, the iteration order isn't defined
$entities = iterator_to_array($dom->doctype->entities);
ksort($entities);
foreach ($entities as $entity) {
echo "Entity name: {$entity->nodeName}\n";
echo "publicId: ";
var_dump($entity->publicId);
echo "systemId: ";
var_dump($entity->systemId);
echo "notationName: ";
var_dump($entity->notationName);
echo "actualEncoding: ";
var_dump($entity->actualEncoding);
echo "encoding: ";
var_dump($entity->encoding);
echo "version: ";
var_dump($entity->version);
echo "\n";
}
?>
--EXPECT--
Entity name: sampleExternalPublicWithNotationName1
publicId: string(9) "public id"
systemId: string(14) "external.stuff"
notationName: string(5) "stuff"
actualEncoding: NULL
encoding: NULL
version: NULL
Entity name: sampleExternalPublicWithNotationName2
publicId: string(0) ""
systemId: string(14) "external.stuff"
notationName: string(5) "stuff"
actualEncoding: NULL
encoding: NULL
version: NULL
Entity name: sampleExternalPublicWithoutNotationName1
publicId: string(9) "public id"
systemId: string(14) "external.stuff"
notationName: string(0) ""
actualEncoding: NULL
encoding: NULL
version: NULL
Entity name: sampleExternalPublicWithoutNotationName2
publicId: string(0) ""
systemId: string(14) "external.stuff"
notationName: string(0) ""
actualEncoding: NULL
encoding: NULL
version: NULL
Entity name: sampleExternalSystemWithNotationName
publicId: NULL
systemId: string(14) "external.stuff"
notationName: string(5) "stuff"
actualEncoding: NULL
encoding: NULL
version: NULL
Entity name: sampleExternalSystemWithoutNotationName
publicId: NULL
systemId: string(14) "external.stuff"
notationName: string(0) ""
actualEncoding: NULL
encoding: NULL
version: NULL
Entity name: sampleInternalEntity
publicId: NULL
systemId: NULL
notationName: NULL
actualEncoding: NULL
encoding: NULL
version: NULL

View File

@@ -0,0 +1,84 @@
--TEST--
DOMParentNode functions with empty argument
--EXTENSIONS--
dom
--FILE--
<?php
$dom = new DOMDocument();
$dom->loadXML('<?xml version="1.0"?><root><node/></root>');
$emptyFragment = $dom->createDocumentFragment();
echo "--- DOMElement test ---\n";
$dom->documentElement->after(...$emptyFragment->childNodes);
$dom->documentElement->before(...$emptyFragment->childNodes);
$dom->documentElement->append(...$emptyFragment->childNodes);
$dom->documentElement->prepend(...$emptyFragment->childNodes);
$dom->documentElement->after();
$dom->documentElement->before();
$dom->documentElement->append();
$dom->documentElement->prepend();
echo $dom->saveXML();
$dom->documentElement->firstChild->replaceWith(...$emptyFragment->childNodes);
echo $dom->saveXML();
$dom->documentElement->replaceWith(...$emptyFragment->childNodes);
echo $dom->saveXML();
echo "--- DOMDocumentFragment test ---\n";
$fragment = $dom->createDocumentFragment();
$fragment->append($dom->createElement('foo'));
$fragment->append(...$emptyFragment->childNodes);
$fragment->prepend(...$emptyFragment->childNodes);
$fragment->append();
$fragment->prepend();
echo $dom->saveXML($fragment), "\n";
echo "--- DOMDocument test ---\n";
$dom->append(...$emptyFragment->childNodes);
$dom->prepend(...$emptyFragment->childNodes);
$dom->append();
$dom->prepend();
echo $dom->saveXML(), "\n";
echo "--- DOMCharacterData test ---\n";
$cdata = $dom->createCDATASection('foo');
$dom->appendChild($cdata);
$cdata->after(...$emptyFragment->childNodes);
$cdata->before(...$emptyFragment->childNodes);
$cdata->after();
$cdata->before();
echo $dom->saveXML(), "\n";
$cdata->replaceWith(...$emptyFragment->childNodes);
echo $dom->saveXML(), "\n";
$cdata = $dom->createCDATASection('foo');
$dom->appendChild($cdata);
$cdata->replaceWith(...$emptyFragment->childNodes);
echo $dom->saveXML(), "\n";
?>
--EXPECT--
--- DOMElement test ---
<?xml version="1.0"?>
<root><node/></root>
<?xml version="1.0"?>
<root/>
<?xml version="1.0"?>
--- DOMDocumentFragment test ---
<foo/>
--- DOMDocument test ---
<?xml version="1.0"?>
--- DOMCharacterData test ---
<?xml version="1.0"?>
<![CDATA[foo]]>
<?xml version="1.0"?>
<?xml version="1.0"?>

View File

@@ -0,0 +1,38 @@
--TEST--
setAttributeNodeNS with same URI but different prefix
--EXTENSIONS--
dom
--FILE--
<?php
// Spec doesn't require to remove redundant namespace declarations.
// This means that when appending a new attribute the old namespace declaration is reused, hence the prefix stays "foo".
// Firefox cleans up the old namespace declaration, so there the prefix does change.
// Chrome doesn't clean it up, so there the prefix doesn't change.
// Our behaviour is the same as Chrome's due to implementation difficulties.
$doc = new DOMDocument();
$doc->appendChild($doc->createElement('container'));
$attribute = $doc->createAttributeNS('http://php.net/ns1', 'foo:hello');
$attribute->nodeValue = '1';
var_dump($doc->documentElement->setAttributeNodeNS($attribute)?->nodeValue);
echo $doc->saveXML(), "\n";
$attribute = $doc->createAttributeNS('http://php.net/ns1', 'bar:hello');
$attribute->nodeValue = '2';
var_dump($doc->documentElement->setAttributeNodeNS($attribute)?->nodeValue);
echo $doc->saveXML(), "\n";
$attribute = $doc->createAttributeNS('http://php.net/ns1', 'hello');
$attribute->nodeValue = '3';
var_dump($doc->documentElement->setAttributeNodeNS($attribute)?->nodeValue);
echo $doc->saveXML(), "\n";
?>
--EXPECT--
NULL
<?xml version="1.0"?>
<container xmlns:foo="http://php.net/ns1" foo:hello="1"/>
string(1) "1"
<?xml version="1.0"?>
<container xmlns:foo="http://php.net/ns1" foo:hello="2"/>
string(1) "2"
<?xml version="1.0"?>
<container xmlns:foo="http://php.net/ns1" foo:hello="3"/>