Skip to content

Commit d7a7309

Browse files
committed
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1: 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 90707f3 + e72fc12 commit d7a7309

File tree

6 files changed

+113
-12
lines changed

6 files changed

+113
-12
lines changed

NEWS

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ PHP NEWS
88
. Fixed bug GH-12215 (Module entry being overwritten causes type errors in
99
ext/dom). (nielsdos)
1010
. Fixed bug GH-12273 (__builtin_cpu_init check). (Freaky)
11+
. Fixed bug GH-10008 (Narrowing occurred during type inference of
12+
ZEND_ADD_ARRAY_ELEMENT). (nielsdos, arnaud-lb)
1113

1214
- CType:
1315
. Fixed bug GH-11997 (ctype_alnum 5 times slower in PHP 8.1 or greater).
@@ -59,6 +61,10 @@ PHP NEWS
5961
. Fix return type of stub of xml_parse_into_struct(). (nielsdos)
6062
. Fix memory leak when calling xml_parse_into_struct() twice. (nielsdos)
6163

64+
- XSL:
65+
. Fix type error on XSLTProcessor::transformToDoc return value with
66+
SimpleXML. (nielsdos)
67+
6268
28 Sep 2023, PHP 8.2.11
6369

6470
- 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, zend_uchar op_type, int w
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, zend_uchar 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)) {
@@ -3286,17 +3301,15 @@ static zend_always_inline zend_result _zend_update_type_info(
32863301
key_type |= MAY_BE_ARRAY_PACKED;
32873302
}
32883303
if (t1 & MAY_BE_ARRAY) {
3289-
key_type |= MAY_BE_HASH_ONLY(t1) ?
3290-
MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG;
3304+
key_type |= assign_long_dim_array_result_type(t1);
32913305
}
32923306
} else {
32933307
if (t2 & (MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_RESOURCE|MAY_BE_DOUBLE)) {
32943308
if (t1 & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) {
32953309
key_type |= MAY_BE_ARRAY_PACKED;
32963310
}
32973311
if (t1 & MAY_BE_ARRAY) {
3298-
key_type |= MAY_BE_HASH_ONLY(t1) ?
3299-
MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG;
3312+
key_type |= assign_long_dim_array_result_type(t1);
33003313
}
33013314
}
33023315
if (t2 & MAY_BE_STRING) {
@@ -3307,8 +3320,7 @@ static zend_always_inline zend_result _zend_update_type_info(
33073320
key_type |= MAY_BE_ARRAY_PACKED;
33083321
}
33093322
if (t1 & MAY_BE_ARRAY) {
3310-
key_type |= MAY_BE_HASH_ONLY(t1) ?
3311-
MAY_BE_ARRAY_NUMERIC_HASH : MAY_BE_ARRAY_KEY_LONG;
3323+
key_type |= assign_long_dim_array_result_type(t1);
33123324
}
33133325
}
33143326
}

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)