From 0c18ffe17fc1a84655253b73209aa5e24e7c3dea Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Sat, 11 Mar 2023 10:21:21 +0800 Subject: [PATCH] Fix bug #80332 --- NEWS | 2 + ext/dom/php_dom.c | 19 +++++++- ext/dom/tests/bug67949.phpt | 12 ++++-- ext/dom/tests/bug80332.phpt | 86 +++++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 ext/dom/tests/bug80332.phpt diff --git a/NEWS b/NEWS index 1856ad53e310..8d0059267973 100644 --- a/NEWS +++ b/NEWS @@ -355,6 +355,8 @@ PHP NEWS - DOM: . Fixed bug #79451 (DOMDocument->replaceChild on doctype causes double free). (Nathan Freeman) + . Fixed bug #80332 (Completely broken array access functionality with + DOMNamedNodeMap). (Nathan Freeman) - FPM: . Fixed bug GH-8885 (FPM access.log with stderr begins to write logs to diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 01a206c0985b..7d1a5a23c739 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -21,6 +21,7 @@ #endif #include "php.h" + #if defined(HAVE_LIBXML) && defined(HAVE_DOM) #include "ext/standard/php_rand.h" #include "php_dom.h" @@ -1519,7 +1520,14 @@ static zval *dom_nodelist_read_dimension(zend_object *object, zval *offset, int return NULL; } - ZVAL_LONG(&offset_copy, zval_get_long(offset)); + zend_long lval; + if (Z_TYPE_P(offset) == IS_LONG) { + ZVAL_LONG(&offset_copy, Z_LVAL_P(offset)); + } else if (Z_TYPE_P(offset) == IS_STRING && is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), &lval, NULL, false) == IS_LONG) { + ZVAL_LONG(&offset_copy, lval); + } else { + return NULL; + } zend_call_method_with_1_params(object, object->ce, NULL, "item", rv, &offset_copy); @@ -1528,7 +1536,14 @@ static zval *dom_nodelist_read_dimension(zend_object *object, zval *offset, int static int dom_nodelist_has_dimension(zend_object *object, zval *member, int check_empty) { - zend_long offset = zval_get_long(member); + zend_long lval; + zend_long offset = -1; + if (Z_TYPE_P(member) == IS_LONG) { + offset = Z_LVAL_P(member); + } else if (Z_TYPE_P(member) == IS_STRING && is_numeric_string(Z_STRVAL_P(member), Z_STRLEN_P(member), &lval, NULL, false) == IS_LONG) { + offset = lval; + } + zval rv; if (offset < 0) { diff --git a/ext/dom/tests/bug67949.phpt b/ext/dom/tests/bug67949.phpt index 394c9888bd35..5079496b15d9 100644 --- a/ext/dom/tests/bug67949.phpt +++ b/ext/dom/tests/bug67949.phpt @@ -78,12 +78,16 @@ array(1) { string(4) "test" } string(4) "test" -bool(true) -string(4) "data" + +Warning: Attempt to read property "textContent" on null in %s on line %d +bool(false) +NULL string(4) "test" string(4) "test" -bool(true) -string(4) "data" + +Warning: Attempt to read property "textContent" on null in %s on line %d +bool(false) +NULL string(4) "test" testing read_dimension with null offset Cannot access node list without offset diff --git a/ext/dom/tests/bug80332.phpt b/ext/dom/tests/bug80332.phpt new file mode 100644 index 000000000000..5e631a8b0fef --- /dev/null +++ b/ext/dom/tests/bug80332.phpt @@ -0,0 +1,86 @@ +--TEST-- +Bug #80332 (Completely broken array access functionality with DOMNamedNodeMap) +--EXTENSIONS-- +dom +--FILE-- +loadHTML(''); + +$x = new DOMXPath($doc); +$span = $x->query('//span')[0]; + +var_dump($span->attributes[0]->nodeName); +var_dump($span->attributes[0]->nodeValue); + +var_dump($span->attributes['1']->nodeName); +var_dump($span->attributes['1']->nodeValue); + +var_dump($span->attributes[0.6]->nodeName); +var_dump($span->attributes[0.6]->nodeValue); + +var_dump($span->attributes['0.6']->nodeName); +var_dump($span->attributes['0.6']->nodeValue); + +var_dump($span->attributes[12345678]->nodeName); +var_dump($span->attributes[12345678]->nodeValue); + +var_dump($span->attributes['12345678']->nodeName); +var_dump($span->attributes['12345678']->nodeValue); + +var_dump($span->attributes[9999999999999999999999999999999999]->nodeName); +var_dump($span->attributes[9999999999999999999999999999999999]->nodeValue); + +var_dump($span->attributes['9999999999999999999999999999999999']->nodeName); +var_dump($span->attributes['9999999999999999999999999999999999']->nodeValue); + +var_dump($span->attributes['hi']->nodeName); +var_dump($span->attributes['hi']->nodeValue); +?> +--EXPECTF-- +string(5) "attr1" +string(6) "value1" +string(5) "attr2" +string(6) "value2" + +Warning: Attempt to read property "nodeName" on null in %s on line %d +NULL + +Warning: Attempt to read property "nodeValue" on null in %s on line %d +NULL + +Warning: Attempt to read property "nodeName" on null in %s on line %d +NULL + +Warning: Attempt to read property "nodeValue" on null in %s on line %d +NULL + +Warning: Attempt to read property "nodeName" on null in %s on line %d +NULL + +Warning: Attempt to read property "nodeValue" on null in %s on line %d +NULL + +Warning: Attempt to read property "nodeName" on null in %s on line %d +NULL + +Warning: Attempt to read property "nodeValue" on null in %s on line %d +NULL + +Warning: Attempt to read property "nodeName" on null in %s on line %d +NULL + +Warning: Attempt to read property "nodeValue" on null in %s on line %d +NULL + +Warning: Attempt to read property "nodeName" on null in %s on line %d +NULL + +Warning: Attempt to read property "nodeValue" on null in %s on line %d +NULL + +Warning: Attempt to read property "nodeName" on null in %s on line %d +NULL + +Warning: Attempt to read property "nodeValue" on null in %s on line %d +NULL