mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1: Fix GH-11433: Unable to set CURLOPT_ACCEPT_ENCODING to NULL Fix "invalid state error" with cloned namespace declarations Fix lifetime issue with getAttributeNodeNS()
This commit is contained in:
commit
c160693515
7 changed files with 185 additions and 30 deletions
6
NEWS
6
NEWS
|
@ -9,6 +9,10 @@ PHP NEWS
|
||||||
- Core:
|
- Core:
|
||||||
. Fixed build for the riscv64 architecture/GCC 12. (Daniil Gentili)
|
. Fixed build for the riscv64 architecture/GCC 12. (Daniil Gentili)
|
||||||
|
|
||||||
|
- Curl:
|
||||||
|
. Fixed bug GH-11433 (Unable to set CURLOPT_ACCEPT_ENCODING to NULL).
|
||||||
|
(nielsdos)
|
||||||
|
|
||||||
- DOM:
|
- DOM:
|
||||||
. Fixed bugs GH-11288 and GH-11289 and GH-11290 and GH-9142 (DOMExceptions
|
. Fixed bugs GH-11288 and GH-11289 and GH-11290 and GH-9142 (DOMExceptions
|
||||||
and segfaults with replaceWith). (nielsdos)
|
and segfaults with replaceWith). (nielsdos)
|
||||||
|
@ -30,6 +34,8 @@ PHP NEWS
|
||||||
. Fixed bug #70359 (print_r() on DOMAttr causes Segfault in
|
. Fixed bug #70359 (print_r() on DOMAttr causes Segfault in
|
||||||
php_libxml_node_free_list()). (nielsdos)
|
php_libxml_node_free_list()). (nielsdos)
|
||||||
. Fixed bug #78577 (Crash in DOMNameSpace debug info handlers). (nielsdos)
|
. Fixed bug #78577 (Crash in DOMNameSpace debug info handlers). (nielsdos)
|
||||||
|
. Fix lifetime issue with getAttributeNodeNS(). (nielsdos)
|
||||||
|
. Fix "invalid state error" with cloned namespace declarations. (nielsdos)
|
||||||
|
|
||||||
- Opcache:
|
- Opcache:
|
||||||
. Fix allocation loop in zend_shared_alloc_startup(). (nielsdos)
|
. Fix allocation loop in zend_shared_alloc_startup(). (nielsdos)
|
||||||
|
|
|
@ -1835,7 +1835,6 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
|
||||||
case CURLOPT_TLSAUTH_TYPE:
|
case CURLOPT_TLSAUTH_TYPE:
|
||||||
case CURLOPT_TLSAUTH_PASSWORD:
|
case CURLOPT_TLSAUTH_PASSWORD:
|
||||||
case CURLOPT_TLSAUTH_USERNAME:
|
case CURLOPT_TLSAUTH_USERNAME:
|
||||||
case CURLOPT_ACCEPT_ENCODING:
|
|
||||||
case CURLOPT_TRANSFER_ENCODING:
|
case CURLOPT_TRANSFER_ENCODING:
|
||||||
case CURLOPT_DNS_SERVERS:
|
case CURLOPT_DNS_SERVERS:
|
||||||
case CURLOPT_MAIL_AUTH:
|
case CURLOPT_MAIL_AUTH:
|
||||||
|
@ -1910,6 +1909,7 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
|
||||||
case CURLOPT_RANGE:
|
case CURLOPT_RANGE:
|
||||||
case CURLOPT_FTP_ACCOUNT:
|
case CURLOPT_FTP_ACCOUNT:
|
||||||
case CURLOPT_RTSP_SESSION_ID:
|
case CURLOPT_RTSP_SESSION_ID:
|
||||||
|
case CURLOPT_ACCEPT_ENCODING:
|
||||||
#if LIBCURL_VERSION_NUM >= 0x072100 /* Available since 7.33.0 */
|
#if LIBCURL_VERSION_NUM >= 0x072100 /* Available since 7.33.0 */
|
||||||
case CURLOPT_DNS_INTERFACE:
|
case CURLOPT_DNS_INTERFACE:
|
||||||
case CURLOPT_DNS_LOCAL_IP4:
|
case CURLOPT_DNS_LOCAL_IP4:
|
||||||
|
|
38
ext/curl/tests/curl_setopt_CURLOPT_ACCEPT_ENCODING.phpt
Normal file
38
ext/curl/tests/curl_setopt_CURLOPT_ACCEPT_ENCODING.phpt
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
--TEST--
|
||||||
|
Test curl_setopt() with CURLOPT_ACCEPT_ENCODING
|
||||||
|
--EXTENSIONS--
|
||||||
|
curl
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
include 'server.inc';
|
||||||
|
$host = curl_cli_server_start();
|
||||||
|
|
||||||
|
$ch = curl_init();
|
||||||
|
|
||||||
|
$url = "{$host}/get.inc?test=";
|
||||||
|
curl_setopt($ch, CURLOPT_URL, $url);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
curl_setopt($ch, CURLOPT_ACCEPT_ENCODING, "gzip");
|
||||||
|
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
|
||||||
|
|
||||||
|
// First execution, with gzip accept
|
||||||
|
curl_exec($ch);
|
||||||
|
echo curl_getinfo($ch, CURLINFO_HEADER_OUT);
|
||||||
|
|
||||||
|
// Second execution, with the encoding accept disabled
|
||||||
|
curl_setopt($ch, CURLOPT_ACCEPT_ENCODING, NULL);
|
||||||
|
curl_exec($ch);
|
||||||
|
echo curl_getinfo($ch, CURLINFO_HEADER_OUT);
|
||||||
|
|
||||||
|
curl_close($ch);
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
GET /get.inc?test= HTTP/1.1
|
||||||
|
Host: %s
|
||||||
|
Accept: */*
|
||||||
|
Accept-Encoding: gzip
|
||||||
|
|
||||||
|
GET /get.inc?test= HTTP/1.1
|
||||||
|
Host: %s
|
||||||
|
Accept: */*
|
|
@ -787,7 +787,7 @@ Since: DOM Level 2
|
||||||
PHP_METHOD(DOMElement, getAttributeNodeNS)
|
PHP_METHOD(DOMElement, getAttributeNodeNS)
|
||||||
{
|
{
|
||||||
zval *id;
|
zval *id;
|
||||||
xmlNodePtr elemp, fakeAttrp;
|
xmlNodePtr elemp;
|
||||||
xmlAttrPtr attrp;
|
xmlAttrPtr attrp;
|
||||||
dom_object *intern;
|
dom_object *intern;
|
||||||
size_t uri_len, name_len;
|
size_t uri_len, name_len;
|
||||||
|
@ -808,21 +808,9 @@ PHP_METHOD(DOMElement, getAttributeNodeNS)
|
||||||
xmlNsPtr nsptr;
|
xmlNsPtr nsptr;
|
||||||
nsptr = dom_get_nsdecl(elemp, (xmlChar *)name);
|
nsptr = dom_get_nsdecl(elemp, (xmlChar *)name);
|
||||||
if (nsptr != NULL) {
|
if (nsptr != NULL) {
|
||||||
xmlNsPtr curns;
|
/* Keep parent alive, because we're a fake child. */
|
||||||
curns = xmlNewNs(NULL, nsptr->href, NULL);
|
GC_ADDREF(&intern->std);
|
||||||
if (nsptr->prefix) {
|
(void) php_dom_create_fake_namespace_decl(elemp, nsptr, return_value, intern);
|
||||||
curns->prefix = xmlStrdup((xmlChar *) nsptr->prefix);
|
|
||||||
}
|
|
||||||
if (nsptr->prefix) {
|
|
||||||
fakeAttrp = xmlNewDocNode(elemp->doc, NULL, (xmlChar *) nsptr->prefix, nsptr->href);
|
|
||||||
} else {
|
|
||||||
fakeAttrp = xmlNewDocNode(elemp->doc, NULL, (xmlChar *)"xmlns", nsptr->href);
|
|
||||||
}
|
|
||||||
fakeAttrp->type = XML_NAMESPACE_DECL;
|
|
||||||
fakeAttrp->parent = elemp;
|
|
||||||
fakeAttrp->ns = curns;
|
|
||||||
|
|
||||||
DOM_RET_OBJ(fakeAttrp, &ret, intern);
|
|
||||||
} else {
|
} else {
|
||||||
RETURN_NULL();
|
RETURN_NULL();
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,7 @@ static HashTable dom_xpath_prop_handlers;
|
||||||
|
|
||||||
static zend_object *dom_objects_namespace_node_new(zend_class_entry *class_type);
|
static zend_object *dom_objects_namespace_node_new(zend_class_entry *class_type);
|
||||||
static void dom_object_namespace_node_free_storage(zend_object *object);
|
static void dom_object_namespace_node_free_storage(zend_object *object);
|
||||||
|
static xmlNodePtr php_dom_create_fake_namespace_decl_node_ptr(xmlNodePtr nodep, xmlNsPtr original);
|
||||||
|
|
||||||
typedef int (*dom_read_t)(dom_object *obj, zval *retval);
|
typedef int (*dom_read_t)(dom_object *obj, zval *retval);
|
||||||
typedef int (*dom_write_t)(dom_object *obj, zval *newval);
|
typedef int (*dom_write_t)(dom_object *obj, zval *newval);
|
||||||
|
@ -477,6 +478,19 @@ PHP_FUNCTION(dom_import_simplexml)
|
||||||
|
|
||||||
static dom_object* dom_objects_set_class(zend_class_entry *class_type);
|
static dom_object* dom_objects_set_class(zend_class_entry *class_type);
|
||||||
|
|
||||||
|
static void dom_update_refcount_after_clone(dom_object *original, xmlNodePtr original_node, dom_object *clone, xmlNodePtr cloned_node)
|
||||||
|
{
|
||||||
|
/* If we cloned a document then we must create new doc proxy */
|
||||||
|
if (cloned_node->doc == original_node->doc) {
|
||||||
|
clone->document = original->document;
|
||||||
|
}
|
||||||
|
php_libxml_increment_doc_ref((php_libxml_node_object *)clone, cloned_node->doc);
|
||||||
|
php_libxml_increment_node_ptr((php_libxml_node_object *)clone, cloned_node, (void *)clone);
|
||||||
|
if (original->document != clone->document) {
|
||||||
|
dom_copy_doc_props(original->document, clone->document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */
|
static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */
|
||||||
{
|
{
|
||||||
dom_object *intern = php_dom_obj_from_obj(zobject);
|
dom_object *intern = php_dom_obj_from_obj(zobject);
|
||||||
|
@ -489,15 +503,7 @@ static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */
|
||||||
if (node != NULL) {
|
if (node != NULL) {
|
||||||
xmlNodePtr cloned_node = xmlDocCopyNode(node, node->doc, 1);
|
xmlNodePtr cloned_node = xmlDocCopyNode(node, node->doc, 1);
|
||||||
if (cloned_node != NULL) {
|
if (cloned_node != NULL) {
|
||||||
/* If we cloned a document then we must create new doc proxy */
|
dom_update_refcount_after_clone(intern, node, clone, cloned_node);
|
||||||
if (cloned_node->doc == node->doc) {
|
|
||||||
clone->document = intern->document;
|
|
||||||
}
|
|
||||||
php_libxml_increment_doc_ref((php_libxml_node_object *)clone, cloned_node->doc);
|
|
||||||
php_libxml_increment_node_ptr((php_libxml_node_object *)clone, cloned_node, (void *)clone);
|
|
||||||
if (intern->document != clone->document) {
|
|
||||||
dom_copy_doc_props(intern->document, clone->document);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -509,6 +515,26 @@ static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
static zend_object *dom_object_namespace_node_clone_obj(zend_object *zobject)
|
||||||
|
{
|
||||||
|
dom_object_namespace_node *intern = php_dom_namespace_node_obj_from_obj(zobject);
|
||||||
|
zend_object *clone = dom_objects_namespace_node_new(intern->dom.std.ce);
|
||||||
|
dom_object_namespace_node *clone_intern = php_dom_namespace_node_obj_from_obj(clone);
|
||||||
|
|
||||||
|
xmlNodePtr original_node = dom_object_get_node(&intern->dom);
|
||||||
|
ZEND_ASSERT(original_node->type == XML_NAMESPACE_DECL);
|
||||||
|
xmlNodePtr cloned_node = php_dom_create_fake_namespace_decl_node_ptr(original_node->parent, original_node->ns);
|
||||||
|
|
||||||
|
if (intern->parent_intern) {
|
||||||
|
clone_intern->parent_intern = intern->parent_intern;
|
||||||
|
GC_ADDREF(&clone_intern->parent_intern->std);
|
||||||
|
}
|
||||||
|
dom_update_refcount_after_clone(&intern->dom, original_node, &clone_intern->dom, cloned_node);
|
||||||
|
|
||||||
|
zend_objects_clone_members(clone, &intern->dom.std);
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
static void dom_copy_prop_handler(zval *zv) /* {{{ */
|
static void dom_copy_prop_handler(zval *zv) /* {{{ */
|
||||||
{
|
{
|
||||||
dom_prop_handler *hnd = Z_PTR_P(zv);
|
dom_prop_handler *hnd = Z_PTR_P(zv);
|
||||||
|
@ -577,6 +603,7 @@ PHP_MINIT_FUNCTION(dom)
|
||||||
memcpy(&dom_object_namespace_node_handlers, &dom_object_handlers, sizeof(zend_object_handlers));
|
memcpy(&dom_object_namespace_node_handlers, &dom_object_handlers, sizeof(zend_object_handlers));
|
||||||
dom_object_namespace_node_handlers.offset = XtOffsetOf(dom_object_namespace_node, dom.std);
|
dom_object_namespace_node_handlers.offset = XtOffsetOf(dom_object_namespace_node, dom.std);
|
||||||
dom_object_namespace_node_handlers.free_obj = dom_object_namespace_node_free_storage;
|
dom_object_namespace_node_handlers.free_obj = dom_object_namespace_node_free_storage;
|
||||||
|
dom_object_namespace_node_handlers.clone_obj = dom_object_namespace_node_clone_obj;
|
||||||
|
|
||||||
zend_hash_init(&classes, 0, NULL, NULL, 1);
|
zend_hash_init(&classes, 0, NULL, NULL, 1);
|
||||||
|
|
||||||
|
@ -1530,8 +1557,7 @@ xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName) {
|
||||||
}
|
}
|
||||||
/* }}} end dom_get_nsdecl */
|
/* }}} end dom_get_nsdecl */
|
||||||
|
|
||||||
/* Note: Assumes the additional lifetime was already added in the caller. */
|
static xmlNodePtr php_dom_create_fake_namespace_decl_node_ptr(xmlNodePtr nodep, xmlNsPtr original)
|
||||||
xmlNodePtr php_dom_create_fake_namespace_decl(xmlNodePtr nodep, xmlNsPtr original, zval *return_value, dom_object *parent_intern)
|
|
||||||
{
|
{
|
||||||
xmlNodePtr attrp;
|
xmlNodePtr attrp;
|
||||||
xmlNsPtr curns = xmlNewNs(NULL, original->href, NULL);
|
xmlNsPtr curns = xmlNewNs(NULL, original->href, NULL);
|
||||||
|
@ -1544,11 +1570,16 @@ xmlNodePtr php_dom_create_fake_namespace_decl(xmlNodePtr nodep, xmlNsPtr origina
|
||||||
attrp->type = XML_NAMESPACE_DECL;
|
attrp->type = XML_NAMESPACE_DECL;
|
||||||
attrp->parent = nodep;
|
attrp->parent = nodep;
|
||||||
attrp->ns = curns;
|
attrp->ns = curns;
|
||||||
|
return attrp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: Assumes the additional lifetime was already added in the caller. */
|
||||||
|
xmlNodePtr php_dom_create_fake_namespace_decl(xmlNodePtr nodep, xmlNsPtr original, zval *return_value, dom_object *parent_intern)
|
||||||
|
{
|
||||||
|
xmlNodePtr attrp = php_dom_create_fake_namespace_decl_node_ptr(nodep, original);
|
||||||
php_dom_create_object(attrp, return_value, parent_intern);
|
php_dom_create_object(attrp, return_value, parent_intern);
|
||||||
/* This object must exist, because we just created an object for it via php_dom_create_object(). */
|
/* This object must exist, because we just created an object for it via php_dom_create_object(). */
|
||||||
dom_object *obj = ((php_libxml_node_ptr *)attrp->_private)->_private;
|
php_dom_namespace_node_obj_from_obj(Z_OBJ_P(return_value))->parent_intern = parent_intern;
|
||||||
php_dom_namespace_node_obj_from_obj(&obj->std)->parent_intern = parent_intern;
|
|
||||||
return attrp;
|
return attrp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
--TEST--
|
||||||
|
Lifetime issue with parentNode on getAttributeNodeNS()
|
||||||
|
--EXTENSIONS--
|
||||||
|
dom
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$xmlString = '<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<root xmlns="http://ns" xmlns:ns2="http://ns2">
|
||||||
|
<ns2:child />
|
||||||
|
</root>';
|
||||||
|
|
||||||
|
$xml=new DOMDocument();
|
||||||
|
$xml->loadXML($xmlString);
|
||||||
|
$ns2 = $xml->documentElement->getAttributeNodeNS("http://www.w3.org/2000/xmlns/", "ns2");
|
||||||
|
$ns2->parentNode->remove();
|
||||||
|
var_dump($ns2->parentNode->localName);
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
string(4) "root"
|
72
ext/dom/tests/clone_nodes.phpt
Normal file
72
ext/dom/tests/clone_nodes.phpt
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
--TEST--
|
||||||
|
Clone nodes
|
||||||
|
--EXTENSIONS--
|
||||||
|
dom
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
echo "-- Clone DOMNameSpaceNode --\n";
|
||||||
|
|
||||||
|
$doc = new DOMDocument;
|
||||||
|
$doc->loadXML('<foo xmlns="http://php.net/test" xmlns:foo="urn:foo" />');
|
||||||
|
|
||||||
|
$attr = $doc->documentElement->getAttributeNode('xmlns');
|
||||||
|
var_dump($attr);
|
||||||
|
|
||||||
|
$attrClone = clone $attr;
|
||||||
|
var_dump($attrClone->nodeValue);
|
||||||
|
var_dump($attrClone->parentNode->nodeName);
|
||||||
|
|
||||||
|
unset($doc);
|
||||||
|
unset($attr);
|
||||||
|
|
||||||
|
var_dump($attrClone->nodeValue);
|
||||||
|
var_dump($attrClone->parentNode->nodeName);
|
||||||
|
|
||||||
|
echo "-- Clone DOMNode --\n";
|
||||||
|
|
||||||
|
$doc = new DOMDocument;
|
||||||
|
$doc->loadXML('<foo><bar/></foo>');
|
||||||
|
|
||||||
|
$bar = $doc->documentElement->firstChild;
|
||||||
|
$barClone = clone $bar;
|
||||||
|
$bar->remove();
|
||||||
|
unset($bar);
|
||||||
|
|
||||||
|
var_dump($barClone->nodeName);
|
||||||
|
|
||||||
|
$doc->firstElementChild->remove();
|
||||||
|
unset($doc);
|
||||||
|
|
||||||
|
var_dump($barClone->nodeName);
|
||||||
|
var_dump($barClone->parentNode);
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
-- Clone DOMNameSpaceNode --
|
||||||
|
object(DOMNameSpaceNode)#3 (8) {
|
||||||
|
["nodeName"]=>
|
||||||
|
string(5) "xmlns"
|
||||||
|
["nodeValue"]=>
|
||||||
|
string(19) "http://php.net/test"
|
||||||
|
["nodeType"]=>
|
||||||
|
int(18)
|
||||||
|
["prefix"]=>
|
||||||
|
string(0) ""
|
||||||
|
["localName"]=>
|
||||||
|
string(5) "xmlns"
|
||||||
|
["namespaceURI"]=>
|
||||||
|
string(19) "http://php.net/test"
|
||||||
|
["ownerDocument"]=>
|
||||||
|
string(22) "(object value omitted)"
|
||||||
|
["parentNode"]=>
|
||||||
|
string(22) "(object value omitted)"
|
||||||
|
}
|
||||||
|
string(19) "http://php.net/test"
|
||||||
|
string(3) "foo"
|
||||||
|
string(19) "http://php.net/test"
|
||||||
|
string(3) "foo"
|
||||||
|
-- Clone DOMNode --
|
||||||
|
string(3) "bar"
|
||||||
|
string(3) "bar"
|
||||||
|
NULL
|
Loading…
Add table
Add a link
Reference in a new issue