Skip to content

Commit 78b70d1

Browse files
committed
Warn on invalid string offset access in isset/empty
And one can admire the brilliant consistency between the coalesce operator and isset...
1 parent a307765 commit 78b70d1

13 files changed

+458
-128
lines changed

Zend/tests/bug81160.phpt

Lines changed: 0 additions & 66 deletions
This file was deleted.
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
--TEST--
2+
Invalid array offset types throws TypeError on isset/empty/coalese
3+
--FILE--
4+
<?php
5+
6+
$v = ['Hello', 'world'];
7+
$o = new stdClass();
8+
$a = [];
9+
$r = STDERR;
10+
11+
echo "Objects as offsets:\n";
12+
try {
13+
var_dump(isset($v[$o]));
14+
} catch (\Throwable $e) {
15+
echo $e->getMessage(), "\n";
16+
}
17+
try {
18+
var_dump(empty($v[$o]));
19+
} catch (\Throwable $e) {
20+
echo $e->getMessage(), "\n";
21+
}
22+
try {
23+
var_dump($v[$o] ?? 'default');
24+
} catch (\Throwable $e) {
25+
echo $e->getMessage(), "\n";
26+
}
27+
echo 'Array ($variable) as offsets:', "\n";
28+
try {
29+
var_dump(isset($v[$a]));
30+
} catch (\Throwable $e) {
31+
echo $e->getMessage(), "\n";
32+
}
33+
try {
34+
var_dump(empty($v[$a]));
35+
} catch (\Throwable $e) {
36+
echo $e->getMessage(), "\n";
37+
}
38+
try {
39+
var_dump($v[$a] ?? 'default');
40+
} catch (\Throwable $e) {
41+
echo $e->getMessage(), "\n";
42+
}
43+
echo "Array (constant empty array) as offsets:\n";
44+
try {
45+
var_dump(isset($v[[]]));
46+
} catch (\Throwable $e) {
47+
echo $e->getMessage(), "\n";
48+
}
49+
try {
50+
var_dump(empty($v[[]]));
51+
} catch (\Throwable $e) {
52+
echo $e->getMessage(), "\n";
53+
}
54+
try {
55+
var_dump($v[[]] ?? 'default');
56+
} catch (\Throwable $e) {
57+
echo $e->getMessage(), "\n";
58+
}
59+
echo "Resource as offsets:\n";
60+
try {
61+
var_dump(isset($v[$r]));
62+
} catch (\Throwable $e) {
63+
echo $e->getMessage(), "\n";
64+
}
65+
try {
66+
var_dump(empty($v[$r]));
67+
} catch (\Throwable $e) {
68+
echo $e->getMessage(), "\n";
69+
}
70+
try {
71+
var_dump($v[$r] ?? 'default');
72+
} catch (\Throwable $e) {
73+
echo $e->getMessage(), "\n";
74+
}
75+
76+
?>
77+
--EXPECTF--
78+
Objects as offsets:
79+
Illegal offset type in isset or empty
80+
Illegal offset type in isset or empty
81+
Illegal offset type
82+
Array ($variable) as offsets:
83+
Illegal offset type in isset or empty
84+
Illegal offset type in isset or empty
85+
Illegal offset type
86+
Array (constant empty array) as offsets:
87+
Illegal offset type in isset or empty
88+
Illegal offset type in isset or empty
89+
Illegal offset type
90+
Resource as offsets:
91+
92+
Warning: Resource ID#3 used as offset, casting to integer (3) in %s on line %d
93+
bool(false)
94+
95+
Warning: Resource ID#3 used as offset, casting to integer (3) in %s on line %d
96+
bool(true)
97+
98+
Warning: Resource ID#3 used as offset, casting to integer (3) in %s on line %d
99+
string(7) "default"
100+

Zend/tests/bug31098.phpt renamed to Zend/tests/offsets_isset_empty/bug31098.phpt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,19 @@ echo $simpleString["0"] === "B"?"ok\n":"bug\n";
6161
bool(false)
6262
bool(false)
6363
bool(false)
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
64+
65+
Warning: Cannot access offset of type string on string in %s on line %d
66+
bool(false)
67+
68+
Warning: Cannot access offset of type string on string in %s on line %d
69+
bool(false)
70+
71+
Warning: Cannot access offset of type string on string in %s on line %d
72+
bool(false)
73+
ok
74+
75+
Warning: Cannot access offset of type string on string in %s on line %d
6776
ok
68-
Cannot access offset of type string on string
6977
ok
7078
ok
7179
ok

Zend/tests/bug60362.phpt renamed to Zend/tests/offsets_isset_empty/bug60362.phpt

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,23 @@ if (empty($arr['exists'][1][0])) {
7777
}
7878
echo "DONE";
7979
?>
80-
--EXPECT--
81-
Cannot access offset of type string on string
80+
--EXPECTF--
81+
Warning: Cannot access offset of type string on string in %s on line %d
82+
sub-key 'non_existent' is not set.
8283
sub-key 1 is set: string(1) "o"
8384
-------------------
84-
Cannot access offset of type string on string
85+
86+
Warning: Cannot access offset of type string on string in %s on line %d
87+
sub-sub-key 'sub_sub' is not set.
8588
sub-sub-key 0 is set: string(1) "o"
8689
-------------------
87-
Cannot access offset of type string on string
90+
91+
Warning: Cannot access offset of type string on string in %s on line %d
92+
sub-key 'non_existent' is empty.
8893
sub-key 1 is not empty: string(1) "o"
8994
-------------------
90-
Cannot access offset of type string on string
95+
96+
Warning: Cannot access offset of type string on string in %s on line %d
97+
sub-sub-key 'sub_sub' is empty.
9198
sub-sub-key 0 is not empty: string(1) "o"
9299
DONE

Zend/tests/bug62680.phpt renamed to Zend/tests/offsets_isset_empty/bug62680.phpt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ try {
1414
echo $e->getMessage(), \PHP_EOL;
1515
}
1616
?>
17-
--EXPECT--
18-
Cannot access offset of type string on string
19-
Cannot access offset of type string on string
17+
--EXPECTF--
18+
Warning: Cannot access offset of type string on string in %s on line %d
19+
bool(false)
20+
21+
Warning: Cannot access offset of type string on string in %s on line %d
22+
bool(false)

Zend/tests/bug69889.phpt renamed to Zend/tests/offsets_isset_empty/bug69889.phpt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ try {
2222
}
2323

2424
?>
25-
--EXPECT--
25+
--EXPECTF--
2626
string(1) "t"
2727
string(7) "default"
2828
string(7) "default"
29-
Cannot access offset of type string on string
30-
Cannot access offset of type string on string
29+
30+
Warning: Cannot access offset of type string on string in %s on line %d
31+
string(7) "default"
32+
33+
Warning: Cannot access offset of type string on string in %s on line %d
34+
string(7) "default"
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
--TEST--
2+
Bug #81160: isset/empty doesn't throw a TypeError on invalid string offset which is inconsistent compared to arrays
3+
--FILE--
4+
<?php
5+
6+
$s = 'Hello';
7+
$o = new stdClass();
8+
$a = [];
9+
$r = STDERR;
10+
11+
echo "Objects as offsets:\n";
12+
try {
13+
var_dump(isset($s[$o]));
14+
} catch (\Throwable $e) {
15+
echo $e->getMessage(), "\n";
16+
}
17+
try {
18+
var_dump(empty($s[$o]));
19+
} catch (\Throwable $e) {
20+
echo $e->getMessage(), "\n";
21+
}
22+
try {
23+
var_dump($s[$o] ?? 'default');
24+
} catch (\Throwable $e) {
25+
echo $e->getMessage(), "\n";
26+
}
27+
echo 'Array ($variable) as offsets:', "\n";
28+
try {
29+
var_dump(isset($s[$a]));
30+
} catch (\Throwable $e) {
31+
echo $e->getMessage(), "\n";
32+
}
33+
try {
34+
var_dump(empty($s[$a]));
35+
} catch (\Throwable $e) {
36+
echo $e->getMessage(), "\n";
37+
}
38+
try {
39+
var_dump($s[$a] ?? 'default');
40+
} catch (\Throwable $e) {
41+
echo $e->getMessage(), "\n";
42+
}
43+
echo "Array (constant empty array) as offsets:\n";
44+
try {
45+
var_dump(isset($s[[]]));
46+
} catch (\Throwable $e) {
47+
echo $e->getMessage(), "\n";
48+
}
49+
try {
50+
var_dump(empty($s[[]]));
51+
} catch (\Throwable $e) {
52+
echo $e->getMessage(), "\n";
53+
}
54+
try {
55+
var_dump($s[[]] ?? 'default');
56+
} catch (\Throwable $e) {
57+
echo $e->getMessage(), "\n";
58+
}
59+
echo "Resource as offsets:\n";
60+
try {
61+
var_dump(isset($s[$r]));
62+
} catch (\Throwable $e) {
63+
echo $e->getMessage(), "\n";
64+
}
65+
try {
66+
var_dump(empty($s[$r]));
67+
} catch (\Throwable $e) {
68+
echo $e->getMessage(), "\n";
69+
}
70+
try {
71+
var_dump($s[$r] ?? 'default');
72+
} catch (\Throwable $e) {
73+
echo $e->getMessage(), "\n";
74+
}
75+
76+
?>
77+
--EXPECTF--
78+
Objects as offsets:
79+
80+
Warning: Cannot access offset of type stdClass on string in %s on line %d
81+
bool(false)
82+
83+
Warning: Cannot access offset of type stdClass on string in %s on line %d
84+
bool(true)
85+
Cannot access offset of type stdClass on string
86+
Array ($variable) as offsets:
87+
88+
Warning: Cannot access offset of type array on string in %s on line %d
89+
bool(false)
90+
91+
Warning: Cannot access offset of type array on string in %s on line %d
92+
bool(true)
93+
Cannot access offset of type array on string
94+
Array (constant empty array) as offsets:
95+
96+
Warning: Cannot access offset of type array on string in %s on line %d
97+
bool(false)
98+
99+
Warning: Cannot access offset of type array on string in %s on line %d
100+
bool(true)
101+
Cannot access offset of type array on string
102+
Resource as offsets:
103+
104+
Warning: Cannot access offset of type resource on string in %s on line %d
105+
bool(false)
106+
107+
Warning: Cannot access offset of type resource on string in %s on line %d
108+
bool(true)
109+
Cannot access offset of type resource on string
110+

0 commit comments

Comments
 (0)