From 27e250880b46031755a6985c340a6fb2186b9271 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 21 Dec 2020 10:21:08 +0100 Subject: [PATCH] Fix bug #80537 This is an unavoidable breaking change to both the type and parameter name. The assertion that was supposed to prevent this was overly lax and accepted any object type for string parameters. --- NEWS | 4 ++++ Zend/zend_execute.c | 16 ++++++++++++---- ext/dom/php_dom.stub.php | 2 +- ext/dom/php_dom_arginfo.h | 12 ++++++------ 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index c85245f4200..986195964d7 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,10 @@ PHP NEWS - Core: . Fixed bug #80523 (bogus parse error on >4GB source code). (Nikita) +- DOM: + . Fixed bug #80537 (Wrong parameter type in DOMElement::removeAttributeNode + stub). (Nikita) + - MySQLi: . Fixed bug #67983 (mysqlnd with MYSQLI_OPT_INT_AND_FLOAT_NATIVE fails to interpret bit columns). (Nikita) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index cb6e63c5154..16eafc39ba4 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -763,6 +763,17 @@ static zend_bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg } #if ZEND_DEBUG +static bool can_convert_to_string(zval *zv) { + /* We don't call cast_object here, because this check must be side-effect free. As this + * is only used for a sanity check of arginfo/zpp consistency, it's okay if we accept + * more than actually allowed here. */ + if (Z_TYPE_P(zv) == IS_OBJECT) { + return Z_OBJ_HT_P(zv)->cast_object != zend_std_cast_object_tostring + || Z_OBJCE_P(zv)->__tostring; + } + return Z_TYPE_P(zv) <= IS_STRING; +} + /* Used to sanity-check internal arginfo types without performing any actual type conversions. */ static zend_bool zend_verify_weak_scalar_type_hint_no_sideeffect(uint32_t type_mask, zval *arg) { @@ -776,10 +787,7 @@ static zend_bool zend_verify_weak_scalar_type_hint_no_sideeffect(uint32_t type_m if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval)) { return 1; } - /* We don't call cast_object here, because this check must be side-effect free. As this - * is only used for a sanity check of arginfo/zpp consistency, it's okay if we accept - * more than actually allowed here. */ - if ((type_mask & MAY_BE_STRING) && (Z_TYPE_P(arg) < IS_STRING || Z_TYPE_P(arg) == IS_OBJECT)) { + if ((type_mask & MAY_BE_STRING) && can_convert_to_string(arg)) { return 1; } if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, &bval)) { diff --git a/ext/dom/php_dom.stub.php b/ext/dom/php_dom.stub.php index bce79c9177d..a3b14504b3b 100644 --- a/ext/dom/php_dom.stub.php +++ b/ext/dom/php_dom.stub.php @@ -205,7 +205,7 @@ class DOMElement implements DOMParentNode, DOMChildNode public function removeAttributeNS(?string $namespace, string $localName) {} /** @return DOMAttr|false */ - public function removeAttributeNode(string $qualifiedName) {} + public function removeAttributeNode(DOMAttr $attr) {} /** @return DOMAttr|bool */ public function setAttribute(string $qualifiedName, string $value) {} diff --git a/ext/dom/php_dom_arginfo.h b/ext/dom/php_dom_arginfo.h index fb8aaf59f23..d38351ca69a 100644 --- a/ext/dom/php_dom_arginfo.h +++ b/ext/dom/php_dom_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 128108b08807ce0b125fc7b963bf3c5b77e6987a */ + * Stub hash: 3cf19e361d130ab881091f38e1c354d81f17d967 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_dom_import_simplexml, 0, 1, DOMElement, 1) ZEND_ARG_TYPE_INFO(0, node, IS_OBJECT, 0) @@ -197,7 +197,9 @@ ZEND_END_ARG_INFO() #define arginfo_class_DOMElement_removeAttributeNS arginfo_class_DOMElement_getAttributeNS -#define arginfo_class_DOMElement_removeAttributeNode arginfo_class_DOMElement_getAttribute +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMElement_removeAttributeNode, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, attr, DOMAttr, 0) +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMElement_setAttribute, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0) @@ -210,11 +212,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMElement_setAttributeNS, 0, 0, 3) ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMElement_setAttributeNode, 0, 0, 1) - ZEND_ARG_OBJ_INFO(0, attr, DOMAttr, 0) -ZEND_END_ARG_INFO() +#define arginfo_class_DOMElement_setAttributeNode arginfo_class_DOMElement_removeAttributeNode -#define arginfo_class_DOMElement_setAttributeNodeNS arginfo_class_DOMElement_setAttributeNode +#define arginfo_class_DOMElement_setAttributeNodeNS arginfo_class_DOMElement_removeAttributeNode ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DOMElement_setIdAttribute, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0)