Skip to content

Commit fa2d556

Browse files
committed
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: Fix GH-10008: Narrowing occurred during type inference of ZEND_ADD_ARRAY_ELEMENT Fix type error on XSLTProcessor::transformToDoc return value with SimpleXML
2 parents 80266f8 + d7a7309 commit fa2d556

File tree

6 files changed

+115
-12
lines changed

6 files changed

+115
-12
lines changed

NEWS

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.3.0RC4
44

5+
- Core:
6+
. Fixed bug GH-10008 (Narrowing occurred during type inference of
7+
ZEND_ADD_ARRAY_ELEMENT). (nielsdos, arnaud-lb)
8+
59
- CType:
610
. Fixed bug GH-11997 (ctype_alnum 5 times slower in PHP 8.1 or greater).
711
(nielsdos)
@@ -13,6 +17,10 @@ PHP NEWS
1317
. Fixed bug GH-12297 (PHP Startup: Invalid library (maybe not a PHP library)
1418
'mysqlnd.so' in Unknown on line). (nielsdos)
1519

20+
- XSL:
21+
. Fix type error on XSLTProcessor::transformToDoc return value with
22+
SimpleXML. (nielsdos)
23+
1624
28 Sep 2023, PHP 8.3.0RC3
1725

1826
- Core:

Zend/Optimizer/zend_inference.c

+21-9
Original file line numberDiff line numberDiff line change
@@ -1942,6 +1942,21 @@ ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, int writ
19421942
return tmp;
19431943
}
19441944

1945+
static zend_always_inline uint32_t assign_long_dim_array_result_type(uint32_t arr_type)
1946+
{
1947+
/* Rules:
1948+
* HASH_ONLY -> MAY_BE_ARRAY_NUMERIC_HASH
1949+
* PACKED_ONLY -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG)
1950+
* HASH || PACKED -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG)
1951+
* 0 -> MAY_BE_ARRAY_NUMERIC_HASH
1952+
*/
1953+
if (MAY_BE_PACKED(arr_type)) {
1954+
return MAY_BE_ARRAY_KEY_LONG;
1955+
} else {
1956+
return MAY_BE_ARRAY_NUMERIC_HASH;
1957+
}
1958+
}
1959+
19451960
static uint32_t assign_dim_array_result_type(
19461961
uint32_t arr_type, uint32_t dim_type, uint32_t value_type, uint8_t dim_op_type) {
19471962
uint32_t tmp = 0;
@@ -1955,13 +1970,13 @@ static uint32_t assign_dim_array_result_type(
19551970
if (arr_type & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) {
19561971
tmp |= MAY_BE_ARRAY_PACKED;
19571972
}
1958-
tmp |= MAY_BE_HASH_ONLY(arr_type) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG;
1973+
tmp |= assign_long_dim_array_result_type(arr_type);
19591974
} else {
19601975
if (dim_type & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_RESOURCE|MAY_BE_DOUBLE)) {
19611976
if (arr_type & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) {
19621977
tmp |= MAY_BE_ARRAY_PACKED;
19631978
}
1964-
tmp |= MAY_BE_HASH_ONLY(arr_type) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG;
1979+
tmp |= assign_long_dim_array_result_type(arr_type);
19651980
}
19661981
if (dim_type & MAY_BE_STRING) {
19671982
tmp |= MAY_BE_ARRAY_KEY_STRING;
@@ -1970,7 +1985,7 @@ static uint32_t assign_dim_array_result_type(
19701985
if (arr_type & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) {
19711986
tmp |= MAY_BE_ARRAY_PACKED;
19721987
}
1973-
tmp |= MAY_BE_HASH_ONLY(arr_type) ? MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG;
1988+
tmp |= assign_long_dim_array_result_type(arr_type);
19741989
}
19751990
}
19761991
if (dim_type & (MAY_BE_UNDEF|MAY_BE_NULL)) {
@@ -3290,17 +3305,15 @@ static zend_always_inline zend_result _zend_update_type_info(
32903305
key_type |= MAY_BE_ARRAY_PACKED;
32913306
}
32923307
if (t1 & MAY_BE_ARRAY) {
3293-
key_type |= MAY_BE_HASH_ONLY(t1) ?
3294-
MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG;
3308+
key_type |= assign_long_dim_array_result_type(t1);
32953309
}
32963310
} else {
32973311
if (t2 & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_RESOURCE|MAY_BE_DOUBLE)) {
32983312
if (t1 & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) {
32993313
key_type |= MAY_BE_ARRAY_PACKED;
33003314
}
33013315
if (t1 & MAY_BE_ARRAY) {
3302-
key_type |= MAY_BE_HASH_ONLY(t1) ?
3303-
MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG;
3316+
key_type |= assign_long_dim_array_result_type(t1);
33043317
}
33053318
}
33063319
if (t2 & MAY_BE_STRING) {
@@ -3311,8 +3324,7 @@ static zend_always_inline zend_result _zend_update_type_info(
33113324
key_type |= MAY_BE_ARRAY_PACKED;
33123325
}
33133326
if (t1 & MAY_BE_ARRAY) {
3314-
key_type |= MAY_BE_HASH_ONLY(t1) ?
3315-
MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG;
3327+
key_type |= assign_long_dim_array_result_type(t1);
33163328
}
33173329
}
33183330
}

ext/opcache/tests/opt/gh10008.phpt

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
GH-10008 (Narrowing occurred during type inference of ZEND_ADD_ARRAY_ELEMENT)
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.optimization_level=0x20
7+
--EXTENSIONS--
8+
opcache
9+
--FILE--
10+
<?php
11+
12+
function test()
13+
{
14+
$bool = true;
15+
for ($i = 0; $i < 10; $i++) {
16+
if ($bool !== true) {
17+
$string_key = "a";
18+
// The following line triggers narrowing during type inference of ZEND_ADD_ARRAY_ELEMENT.
19+
$array = ["b" => $bool, $string_key => 123];
20+
}
21+
22+
$bool = false;
23+
}
24+
}
25+
26+
echo "Done\n";
27+
28+
?>
29+
--EXPECT--
30+
Done

ext/xsl/php_xsl.stub.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public function importStylesheet(object $stylesheet): bool {}
8181
* @param DOMDocument|SimpleXMLElement $document
8282
* @tentative-return-type
8383
*/
84-
public function transformToDoc(object $document, ?string $returnClass = null): DOMDocument|false {}
84+
public function transformToDoc(object $document, ?string $returnClass = null): object|false {}
8585

8686
/**
8787
* @param DOMDocument|SimpleXMLElement $document

ext/xsl/php_xsl_arginfo.h

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
--TEST--
2+
XSLTProcessor::transformToDoc return value type error with SimpleXML
3+
--EXTENSIONS--
4+
xsl
5+
simplexml
6+
--FILE--
7+
<?php
8+
9+
class AdvancedXMLElement extends SimpleXMLElement {
10+
public function foo() {
11+
return "foo: " . (string) $this;
12+
}
13+
}
14+
15+
$sxe = simplexml_load_file(__DIR__ . '/53965/collection.xml', AdvancedXMLElement::class);
16+
17+
$processor = new XSLTProcessor;
18+
$dom = new DOMDocument;
19+
$dom->load(__DIR__ . '/53965/collection.xsl');
20+
$processor->importStylesheet($dom);
21+
$result = $processor->transformToDoc($sxe, AdvancedXMLElement::class);
22+
23+
var_dump($result);
24+
var_dump($result->h1->foo());
25+
26+
?>
27+
--EXPECT--
28+
object(AdvancedXMLElement)#4 (3) {
29+
["h1"]=>
30+
array(2) {
31+
[0]=>
32+
string(19) "Fight for your mind"
33+
[1]=>
34+
string(17) "Electric Ladyland"
35+
}
36+
["h2"]=>
37+
array(2) {
38+
[0]=>
39+
string(20) "by Ben Harper - 1995"
40+
[1]=>
41+
string(22) "by Jimi Hendrix - 1997"
42+
}
43+
["hr"]=>
44+
array(2) {
45+
[0]=>
46+
object(AdvancedXMLElement)#5 (0) {
47+
}
48+
[1]=>
49+
object(AdvancedXMLElement)#6 (0) {
50+
}
51+
}
52+
}
53+
string(24) "foo: Fight for your mind"

0 commit comments

Comments
 (0)