Skip to content

Commit 26d75b6

Browse files
committed
Fix Bug #81160: isset/empty doesn't throw a TypeError on invalid string offset
1 parent 083b64e commit 26d75b6

12 files changed

+372
-219
lines changed

Zend/Optimizer/zend_inference.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -4793,7 +4793,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
47934793
return 0;
47944794
}
47954795
case ZEND_FETCH_IS:
4796-
return (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT));
4796+
return (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_STRING));
47974797
case ZEND_ISSET_ISEMPTY_DIM_OBJ:
47984798
return (t1 & MAY_BE_OBJECT) || (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT));
47994799
case ZEND_FETCH_DIM_IS:

Zend/tests/bug31098.phpt

+22-7
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,26 @@ var_dump(isset($a->b));
99
$a = '0';
1010
var_dump(isset($a->b));
1111
$a = '';
12-
var_dump(isset($a['b']));
12+
13+
try {
14+
var_dump(isset($a['b']));
15+
} catch (\TypeError $e) {
16+
echo $e->getMessage(), "\n";
17+
}
1318
$a = 'a';
14-
var_dump(isset($a['b']));
19+
20+
try {
21+
var_dump(isset($a['b']));
22+
} catch (\TypeError $e) {
23+
echo $e->getMessage(), "\n";
24+
}
1525
$a = '0';
16-
var_dump(isset($a['b']));
26+
27+
try {
28+
var_dump(isset($a['b']));
29+
} catch (\TypeError $e) {
30+
echo $e->getMessage(), "\n";
31+
}
1732

1833
$simpleString = "Bogus String Text";
1934
echo isset($simpleString->wrong)?"bug\n":"ok\n";
@@ -46,11 +61,11 @@ echo $simpleString["0"] === "B"?"ok\n":"bug\n";
4661
bool(false)
4762
bool(false)
4863
bool(false)
49-
bool(false)
50-
bool(false)
51-
bool(false)
52-
ok
64+
Cannot access offset of type string on string
65+
Cannot access offset of type string on string
66+
Cannot access offset of type string on string
5367
ok
68+
Cannot access offset of type string on string
5469
ok
5570
ok
5671
ok

Zend/tests/bug60362.phpt

+41-24
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@ Bug #60362: non-existent sub-sub keys should not have values
44
<?php
55
$arr = array('exists' => 'foz');
66

7-
if (isset($arr['exists']['non_existent'])) {
8-
echo "sub-key 'non_existent' is set: ";
9-
var_dump($arr['exists']['non_existent']);
10-
} else {
11-
echo "sub-key 'non_existent' is not set.\n";
7+
try {
8+
if (isset($arr['exists']['non_existent'])) {
9+
echo "sub-key 'non_existent' is set: ";
10+
var_dump($arr['exists']['non_existent']);
11+
} else {
12+
echo "sub-key 'non_existent' is not set.\n";
13+
}
14+
} catch (\TypeError $e) {
15+
echo $e->getMessage(), \PHP_EOL;
1216
}
17+
1318
if (isset($arr['exists'][1])) {
1419
echo "sub-key 1 is set: ";
1520
var_dump($arr['exists'][1]);
@@ -18,11 +23,15 @@ if (isset($arr['exists'][1])) {
1823
}
1924

2025
echo "-------------------\n";
21-
if (isset($arr['exists']['non_existent']['sub_sub'])) {
22-
echo "sub-key 'sub_sub' is set: ";
23-
var_dump($arr['exists']['non_existent']['sub_sub']);
24-
} else {
25-
echo "sub-sub-key 'sub_sub' is not set.\n";
26+
try {
27+
if (isset($arr['exists']['non_existent']['sub_sub'])) {
28+
echo "sub-key 'sub_sub' is set: ";
29+
var_dump($arr['exists']['non_existent']['sub_sub']);
30+
} else {
31+
echo "sub-sub-key 'sub_sub' is not set.\n";
32+
}
33+
} catch (\TypeError $e) {
34+
echo $e->getMessage(), \PHP_EOL;
2635
}
2736
if (isset($arr['exists'][1][0])) {
2837
echo "sub-sub-key 0 is set: ";
@@ -32,11 +41,15 @@ if (isset($arr['exists'][1][0])) {
3241
}
3342

3443
echo "-------------------\n";
35-
if (empty($arr['exists']['non_existent'])) {
36-
echo "sub-key 'non_existent' is empty.\n";
37-
} else {
38-
echo "sub-key 'non_existent' is not empty: ";
39-
var_dump($arr['exists']['non_existent']);
44+
try {
45+
if (empty($arr['exists']['non_existent'])) {
46+
echo "sub-key 'non_existent' is empty.\n";
47+
} else {
48+
echo "sub-key 'non_existent' is not empty: ";
49+
var_dump($arr['exists']['non_existent']);
50+
}
51+
} catch (\TypeError $e) {
52+
echo $e->getMessage(), \PHP_EOL;
4053
}
4154
if (empty($arr['exists'][1])) {
4255
echo "sub-key 1 is empty.\n";
@@ -46,11 +59,15 @@ if (empty($arr['exists'][1])) {
4659
}
4760

4861
echo "-------------------\n";
49-
if (empty($arr['exists']['non_existent']['sub_sub'])) {
50-
echo "sub-sub-key 'sub_sub' is empty.\n";
51-
} else {
52-
echo "sub-sub-key 'sub_sub' is not empty: ";
53-
var_dump($arr['exists']['non_existent']['sub_sub']);
62+
try {
63+
if (empty($arr['exists']['non_existent']['sub_sub'])) {
64+
echo "sub-sub-key 'sub_sub' is empty.\n";
65+
} else {
66+
echo "sub-sub-key 'sub_sub' is not empty: ";
67+
var_dump($arr['exists']['non_existent']['sub_sub']);
68+
}
69+
} catch (\TypeError $e) {
70+
echo $e->getMessage(), \PHP_EOL;
5471
}
5572
if (empty($arr['exists'][1][0])) {
5673
echo "sub-sub-key 0 is empty.\n";
@@ -61,15 +78,15 @@ if (empty($arr['exists'][1][0])) {
6178
echo "DONE";
6279
?>
6380
--EXPECT--
64-
sub-key 'non_existent' is not set.
81+
Cannot access offset of type string on string
6582
sub-key 1 is set: string(1) "o"
6683
-------------------
67-
sub-sub-key 'sub_sub' is not set.
84+
Cannot access offset of type string on string
6885
sub-sub-key 0 is set: string(1) "o"
6986
-------------------
70-
sub-key 'non_existent' is empty.
87+
Cannot access offset of type string on string
7188
sub-key 1 is not empty: string(1) "o"
7289
-------------------
73-
sub-sub-key 'sub_sub' is empty.
90+
Cannot access offset of type string on string
7491
sub-sub-key 0 is not empty: string(1) "o"
7592
DONE

Zend/tests/bug62680.phpt

+12-4
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,17 @@ Bug #62680 (Function isset() throws fatal error on set array if non-existent key
33
--FILE--
44
<?php
55
$array = array("");
6-
var_dump(isset($array[0]["a"]["b"]));
7-
var_dump(isset($array[0]["a"]["b"]["c"]));
6+
try {
7+
var_dump(isset($array[0]["a"]["b"]));
8+
} catch (\TypeError $e) {
9+
echo $e->getMessage(), \PHP_EOL;
10+
}
11+
try {
12+
var_dump(isset($array[0]["a"]["b"]["c"]));
13+
} catch (\TypeError $e) {
14+
echo $e->getMessage(), \PHP_EOL;
15+
}
816
?>
917
--EXPECT--
10-
bool(false)
11-
bool(false)
18+
Cannot access offset of type string on string
19+
Cannot access offset of type string on string

Zend/tests/bug69889.phpt

+13-4
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,22 @@ var_dump($foo[0] ?? "default");
99
var_dump($foo[5] ?? "default");
1010
var_dump(isset($foo[5]) ? $foo[5] : "default");
1111

12-
var_dump($foo["str"] ?? "default");
13-
var_dump(isset($foo["str"]) ? $foo["str"] : "default");
12+
try {
13+
var_dump($foo["str"] ?? "default");
14+
} catch (\TypeError $e) {
15+
echo $e->getMessage(), \PHP_EOL;
16+
}
17+
18+
try {
19+
var_dump(isset($foo["str"]) ? $foo["str"] : "default");
20+
} catch (\TypeError $e) {
21+
echo $e->getMessage(), \PHP_EOL;
22+
}
1423

1524
?>
1625
--EXPECT--
1726
string(1) "t"
1827
string(7) "default"
1928
string(7) "default"
20-
string(7) "default"
21-
string(7) "default"
29+
Cannot access offset of type string on string
30+
Cannot access offset of type string on string

Zend/tests/bug81160.phpt

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
--TEST--
2+
Bug #81160: isset/empty doesn't throw a TypeError on invalid string offset
3+
--FILE--
4+
<?php
5+
6+
$s = 'Hello';
7+
$o = new stdClass();
8+
$a = [];
9+
10+
try {
11+
var_dump(isset($s[$o]));
12+
} catch (\Throwable $e) {
13+
echo $e->getMessage(), "\n";
14+
}
15+
try {
16+
var_dump(empty($s[$o]));
17+
} catch (\Throwable $e) {
18+
echo $e->getMessage(), "\n";
19+
}
20+
try {
21+
var_dump($s[$o] ?? 'default');
22+
} catch (\Throwable $e) {
23+
echo $e->getMessage(), "\n";
24+
}
25+
try {
26+
var_dump(isset($s[$a]));
27+
} catch (\Throwable $e) {
28+
echo $e->getMessage(), "\n";
29+
}
30+
try {
31+
var_dump(empty($s[$a]));
32+
} catch (\Throwable $e) {
33+
echo $e->getMessage(), "\n";
34+
}
35+
try {
36+
var_dump($s[$a] ?? 'default');
37+
} catch (\Throwable $e) {
38+
echo $e->getMessage(), "\n";
39+
}
40+
try {
41+
var_dump(isset($s[[]]));
42+
} catch (\Throwable $e) {
43+
echo $e->getMessage(), "\n";
44+
}
45+
try {
46+
var_dump(empty($s[[]]));
47+
} catch (\Throwable $e) {
48+
echo $e->getMessage(), "\n";
49+
}
50+
try {
51+
var_dump($s[[]] ?? 'default');
52+
} catch (\Throwable $e) {
53+
echo $e->getMessage(), "\n";
54+
}
55+
56+
?>
57+
--EXPECT--
58+
Cannot access offset of type stdClass on string
59+
Cannot access offset of type stdClass on string
60+
Cannot access offset of type stdClass on string
61+
Cannot access offset of type array on string
62+
Cannot access offset of type array on string
63+
Cannot access offset of type array on string
64+
Cannot access offset of type array on string
65+
Cannot access offset of type array on string
66+
Cannot access offset of type array on string

0 commit comments

Comments
 (0)