diff --git a/NEWS b/NEWS index 26fad472919..395f5f687ef 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.3.0RC4 +- Core: + . Fixed bug GH-10008 (Narrowing occurred during type inference of + ZEND_ADD_ARRAY_ELEMENT). (nielsdos, arnaud-lb) + - CType: . Fixed bug GH-11997 (ctype_alnum 5 times slower in PHP 8.1 or greater). (nielsdos) @@ -13,6 +17,10 @@ PHP NEWS . Fixed bug GH-12297 (PHP Startup: Invalid library (maybe not a PHP library) 'mysqlnd.so' in Unknown on line). (nielsdos) +- XSL: + . Fix type error on XSLTProcessor::transformToDoc return value with + SimpleXML. (nielsdos) + 28 Sep 2023, PHP 8.3.0RC3 - Core: diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index dd71215980f..3c192577529 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -1942,6 +1942,21 @@ ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, int writ return tmp; } +static zend_always_inline uint32_t assign_long_dim_array_result_type(uint32_t arr_type) +{ + /* Rules: + * HASH_ONLY -> MAY_BE_ARRAY_NUMERIC_HASH + * PACKED_ONLY -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG) + * HASH || PACKED -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG) + * 0 -> MAY_BE_ARRAY_NUMERIC_HASH + */ + if (MAY_BE_PACKED(arr_type)) { + return MAY_BE_ARRAY_KEY_LONG; + } else { + return MAY_BE_ARRAY_NUMERIC_HASH; + } +} + static uint32_t assign_dim_array_result_type( uint32_t arr_type, uint32_t dim_type, uint32_t value_type, uint8_t dim_op_type) { uint32_t tmp = 0; @@ -1955,13 +1970,13 @@ static uint32_t assign_dim_array_result_type( if (arr_type & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) { tmp |= MAY_BE_ARRAY_PACKED; } - tmp |= MAY_BE_HASH_ONLY(arr_type) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG; + tmp |= assign_long_dim_array_result_type(arr_type); } else { if (dim_type & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_RESOURCE|MAY_BE_DOUBLE)) { if (arr_type & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) { tmp |= MAY_BE_ARRAY_PACKED; } - tmp |= MAY_BE_HASH_ONLY(arr_type) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG; + tmp |= assign_long_dim_array_result_type(arr_type); } if (dim_type & MAY_BE_STRING) { tmp |= MAY_BE_ARRAY_KEY_STRING; @@ -1970,7 +1985,7 @@ static uint32_t assign_dim_array_result_type( if (arr_type & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) { tmp |= MAY_BE_ARRAY_PACKED; } - tmp |= MAY_BE_HASH_ONLY(arr_type) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG; + tmp |= assign_long_dim_array_result_type(arr_type); } } if (dim_type & (MAY_BE_UNDEF|MAY_BE_NULL)) { @@ -3290,8 +3305,7 @@ static zend_always_inline zend_result _zend_update_type_info( key_type |= MAY_BE_ARRAY_PACKED; } if (t1 & MAY_BE_ARRAY) { - key_type |= MAY_BE_HASH_ONLY(t1) ? - MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG; + key_type |= assign_long_dim_array_result_type(t1); } } else { if (t2 & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_RESOURCE|MAY_BE_DOUBLE)) { @@ -3299,8 +3313,7 @@ static zend_always_inline zend_result _zend_update_type_info( key_type |= MAY_BE_ARRAY_PACKED; } if (t1 & MAY_BE_ARRAY) { - key_type |= MAY_BE_HASH_ONLY(t1) ? - MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG; + key_type |= assign_long_dim_array_result_type(t1); } } if (t2 & MAY_BE_STRING) { @@ -3311,8 +3324,7 @@ static zend_always_inline zend_result _zend_update_type_info( key_type |= MAY_BE_ARRAY_PACKED; } if (t1 & MAY_BE_ARRAY) { - key_type |= MAY_BE_HASH_ONLY(t1) ? - MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG; + key_type |= assign_long_dim_array_result_type(t1); } } } diff --git a/ext/opcache/tests/opt/gh10008.phpt b/ext/opcache/tests/opt/gh10008.phpt new file mode 100644 index 00000000000..e92b7137bdb --- /dev/null +++ b/ext/opcache/tests/opt/gh10008.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-10008 (Narrowing occurred during type inference of ZEND_ADD_ARRAY_ELEMENT) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=0x20 +--EXTENSIONS-- +opcache +--FILE-- + $bool, $string_key => 123]; + } + + $bool = false; + } +} + +echo "Done\n"; + +?> +--EXPECT-- +Done diff --git a/ext/xsl/php_xsl.stub.php b/ext/xsl/php_xsl.stub.php index 52300c019ec..4bba5beae8c 100644 --- a/ext/xsl/php_xsl.stub.php +++ b/ext/xsl/php_xsl.stub.php @@ -81,7 +81,7 @@ class XSLTProcessor * @param DOMDocument|SimpleXMLElement $document * @tentative-return-type */ - public function transformToDoc(object $document, ?string $returnClass = null): DOMDocument|false {} + public function transformToDoc(object $document, ?string $returnClass = null): object|false {} /** * @param DOMDocument|SimpleXMLElement $document diff --git a/ext/xsl/php_xsl_arginfo.h b/ext/xsl/php_xsl_arginfo.h index aabf6629cc1..aaa8531496a 100644 --- a/ext/xsl/php_xsl_arginfo.h +++ b/ext/xsl/php_xsl_arginfo.h @@ -1,11 +1,11 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7d747e7b5989c18169e67d9a9d70256583fffd8e */ + * Stub hash: 606e6ceba2381588b28e25e140fbcfec8a4dbe84 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_XSLTProcessor_importStylesheet, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, stylesheet, IS_OBJECT, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_XSLTProcessor_transformToDoc, 0, 1, DOMDocument, MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_XSLTProcessor_transformToDoc, 0, 1, MAY_BE_OBJECT|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, document, IS_OBJECT, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, returnClass, IS_STRING, 1, "null") ZEND_END_ARG_INFO() diff --git a/ext/xsl/tests/transformToDoc_sxe_type_error.phpt b/ext/xsl/tests/transformToDoc_sxe_type_error.phpt new file mode 100644 index 00000000000..536f66bc0ea --- /dev/null +++ b/ext/xsl/tests/transformToDoc_sxe_type_error.phpt @@ -0,0 +1,53 @@ +--TEST-- +XSLTProcessor::transformToDoc return value type error with SimpleXML +--EXTENSIONS-- +xsl +simplexml +--FILE-- +load(__DIR__ . '/53965/collection.xsl'); +$processor->importStylesheet($dom); +$result = $processor->transformToDoc($sxe, AdvancedXMLElement::class); + +var_dump($result); +var_dump($result->h1->foo()); + +?> +--EXPECT-- +object(AdvancedXMLElement)#4 (3) { + ["h1"]=> + array(2) { + [0]=> + string(19) "Fight for your mind" + [1]=> + string(17) "Electric Ladyland" + } + ["h2"]=> + array(2) { + [0]=> + string(20) "by Ben Harper - 1995" + [1]=> + string(22) "by Jimi Hendrix - 1997" + } + ["hr"]=> + array(2) { + [0]=> + object(AdvancedXMLElement)#5 (0) { + } + [1]=> + object(AdvancedXMLElement)#6 (0) { + } + } +} +string(24) "foo: Fight for your mind"