Skip to content

Commit d542152

Browse files
committed
Fix oss-fuzz #60709 unseting op via globals
It turns out not just NULL is affected nor -- but also on booleans and this also affects properties
1 parent 154287b commit d542152

File tree

4 files changed

+333
-3
lines changed

4 files changed

+333
-3
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
oss-fuzz #60709: Test
3+
--FILE--
4+
<?php
5+
set_error_handler(function($_, $m) {
6+
echo "$m\n";
7+
unset($GLOBALS['x']);
8+
});
9+
10+
echo "POST DEC\n";
11+
var_dump($x--);
12+
unset($x);
13+
echo "POST INC\n";
14+
var_dump($x++);
15+
unset($x);
16+
echo "PRE DEC\n";
17+
var_dump(--$x);
18+
unset($x);
19+
echo "PRE INC\n";
20+
var_dump(++$x);
21+
?>
22+
--EXPECT--
23+
POST DEC
24+
Undefined variable $x
25+
Decrement on type null has no effect, this will change in the next major version of PHP
26+
NULL
27+
POST INC
28+
Undefined variable $x
29+
NULL
30+
PRE DEC
31+
Undefined variable $x
32+
Decrement on type null has no effect, this will change in the next major version of PHP
33+
NULL
34+
PRE INC
35+
Undefined variable $x
36+
int(1)
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
--TEST--
2+
Unset variable via $GLOBALS array in error_handler
3+
--FILE--
4+
<?php
5+
set_error_handler(function($_, $m) {
6+
echo "$m\n";
7+
unset($GLOBALS['x']);
8+
});
9+
echo "NULL (only --)\n";
10+
echo "POST DEC\n";
11+
$x = null;
12+
var_dump($x--);
13+
unset($x);
14+
echo "PRE DEC\n";
15+
$x = null;
16+
var_dump(--$x);
17+
unset($x);
18+
echo "Empty string\n";
19+
echo "POST INC\n";
20+
$x = "";
21+
var_dump($x++);
22+
unset($x);
23+
echo "POST DEC\n";
24+
$x = "";
25+
var_dump($x--);
26+
unset($x);
27+
echo "PRE INC\n";
28+
$x = "";
29+
var_dump(++$x);
30+
unset($x);
31+
echo "PRE DEC\n";
32+
$x = "";
33+
var_dump(--$x);
34+
unset($x);
35+
echo "Non fill ASCII (only ++)\n";
36+
echo "POST INC\n";
37+
$x = " ad ";
38+
var_dump($x++);
39+
unset($x);
40+
echo "PRE INC\n";
41+
$x = " ad ";
42+
var_dump(++$x);
43+
unset($x);
44+
echo "Bool\n";
45+
echo "POST INC\n";
46+
$x = false;
47+
var_dump($x++);
48+
unset($x);
49+
echo "POST DEC\n";
50+
$x = false;
51+
var_dump($x--);
52+
unset($x);
53+
echo "PRE INC\n";
54+
$x = false;
55+
var_dump(++$x);
56+
unset($x);
57+
echo "PRE DEC\n";
58+
$x = false;
59+
var_dump(--$x);
60+
unset($x);
61+
echo "POST INC\n";
62+
$x = true;
63+
var_dump($x++);
64+
unset($x);
65+
echo "POST DEC\n";
66+
$x = true;
67+
var_dump($x--);
68+
unset($x);
69+
echo "PRE INC\n";
70+
$x = true;
71+
var_dump(++$x);
72+
unset($x);
73+
echo "PRE DEC\n";
74+
$x = true;
75+
var_dump(--$x);
76+
unset($x);
77+
?>
78+
--EXPECT--
79+
NULL (only --)
80+
POST DEC
81+
Decrement on type null has no effect, this will change in the next major version of PHP
82+
NULL
83+
PRE DEC
84+
Decrement on type null has no effect, this will change in the next major version of PHP
85+
NULL
86+
Empty string
87+
POST INC
88+
Increment on non-alphanumeric string is deprecated
89+
string(0) ""
90+
POST DEC
91+
Decrement on empty string is deprecated as non-numeric
92+
string(0) ""
93+
PRE INC
94+
Increment on non-alphanumeric string is deprecated
95+
string(1) "1"
96+
PRE DEC
97+
Decrement on empty string is deprecated as non-numeric
98+
int(-1)
99+
Non fill ASCII (only ++)
100+
POST INC
101+
Increment on non-alphanumeric string is deprecated
102+
string(4) " ad "
103+
PRE INC
104+
Increment on non-alphanumeric string is deprecated
105+
string(4) " ad "
106+
Bool
107+
POST INC
108+
Increment on type bool has no effect, this will change in the next major version of PHP
109+
bool(false)
110+
POST DEC
111+
Decrement on type bool has no effect, this will change in the next major version of PHP
112+
bool(false)
113+
PRE INC
114+
Increment on type bool has no effect, this will change in the next major version of PHP
115+
bool(false)
116+
PRE DEC
117+
Decrement on type bool has no effect, this will change in the next major version of PHP
118+
bool(false)
119+
POST INC
120+
Increment on type bool has no effect, this will change in the next major version of PHP
121+
bool(true)
122+
POST DEC
123+
Decrement on type bool has no effect, this will change in the next major version of PHP
124+
bool(true)
125+
PRE INC
126+
Increment on type bool has no effect, this will change in the next major version of PHP
127+
bool(true)
128+
PRE DEC
129+
Decrement on type bool has no effect, this will change in the next major version of PHP
130+
bool(true)
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
--TEST--
2+
Unset property via error_handler
3+
--FILE--
4+
<?php
5+
class C {
6+
public $a;
7+
8+
public function errorHandler($errno, $errstr) {
9+
var_dump($errstr);
10+
unset($this->a);
11+
}
12+
}
13+
14+
$c = new C;
15+
set_error_handler([$c, 'errorHandler']);
16+
17+
/* default property value */
18+
var_dump(--$c->a);
19+
20+
echo "NULL (only --)\n";
21+
echo "POST DEC\n";
22+
$c->a = null;
23+
var_dump($c->a--);
24+
unset($c->a);
25+
echo "PRE DEC\n";
26+
$c->a = null;
27+
var_dump(--$c->a);
28+
unset($c->a);
29+
echo "Empty string\n";
30+
echo "POST INC\n";
31+
$c->a = "";
32+
var_dump($c->a++);
33+
unset($c->a);
34+
echo "POST DEC\n";
35+
$c->a = "";
36+
var_dump($c->a--);
37+
unset($c->a);
38+
echo "PRE INC\n";
39+
$c->a = "";
40+
var_dump(++$c->a);
41+
unset($c->a);
42+
echo "PRE DEC\n";
43+
$c->a = "";
44+
var_dump(--$c->a);
45+
unset($c->a);
46+
echo "Non fill ASCII (only ++)\n";
47+
echo "POST INC\n";
48+
$c->a = " ad ";
49+
var_dump($c->a++);
50+
unset($c->a);
51+
echo "PRE INC\n";
52+
$c->a = " ad ";
53+
var_dump(++$c->a);
54+
unset($c->a);
55+
echo "Bool\n";
56+
echo "POST INC\n";
57+
$c->a = false;
58+
var_dump($c->a++);
59+
unset($c->a);
60+
echo "POST DEC\n";
61+
$c->a = false;
62+
var_dump($c->a--);
63+
unset($c->a);
64+
echo "PRE INC\n";
65+
$c->a = false;
66+
var_dump(++$c->a);
67+
unset($c->a);
68+
echo "PRE DEC\n";
69+
$c->a = false;
70+
var_dump(--$c->a);
71+
unset($c->a);
72+
echo "POST INC\n";
73+
$c->a = true;
74+
var_dump($c->a++);
75+
unset($c->a);
76+
echo "POST DEC\n";
77+
$c->a = true;
78+
var_dump($c->a--);
79+
unset($c->a);
80+
echo "PRE INC\n";
81+
$c->a = true;
82+
var_dump(++$c->a);
83+
unset($c->a);
84+
echo "PRE DEC\n";
85+
$c->a = true;
86+
var_dump(--$c->a);
87+
unset($c->a);
88+
?>
89+
--EXPECT--
90+
string(87) "Decrement on type null has no effect, this will change in the next major version of PHP"
91+
NULL
92+
NULL (only --)
93+
POST DEC
94+
string(87) "Decrement on type null has no effect, this will change in the next major version of PHP"
95+
NULL
96+
PRE DEC
97+
string(87) "Decrement on type null has no effect, this will change in the next major version of PHP"
98+
NULL
99+
Empty string
100+
POST INC
101+
string(50) "Increment on non-alphanumeric string is deprecated"
102+
string(0) ""
103+
POST DEC
104+
string(54) "Decrement on empty string is deprecated as non-numeric"
105+
string(0) ""
106+
PRE INC
107+
string(50) "Increment on non-alphanumeric string is deprecated"
108+
string(1) "1"
109+
PRE DEC
110+
string(54) "Decrement on empty string is deprecated as non-numeric"
111+
int(-1)
112+
Non fill ASCII (only ++)
113+
POST INC
114+
string(50) "Increment on non-alphanumeric string is deprecated"
115+
string(4) " ad "
116+
PRE INC
117+
string(50) "Increment on non-alphanumeric string is deprecated"
118+
string(4) " ad "
119+
Bool
120+
POST INC
121+
string(87) "Increment on type bool has no effect, this will change in the next major version of PHP"
122+
bool(false)
123+
POST DEC
124+
string(87) "Decrement on type bool has no effect, this will change in the next major version of PHP"
125+
bool(false)
126+
PRE INC
127+
string(87) "Increment on type bool has no effect, this will change in the next major version of PHP"
128+
bool(false)
129+
PRE DEC
130+
string(87) "Decrement on type bool has no effect, this will change in the next major version of PHP"
131+
bool(false)
132+
POST INC
133+
string(87) "Increment on type bool has no effect, this will change in the next major version of PHP"
134+
bool(true)
135+
POST DEC
136+
string(87) "Decrement on type bool has no effect, this will change in the next major version of PHP"
137+
bool(true)
138+
PRE INC
139+
string(87) "Increment on type bool has no effect, this will change in the next major version of PHP"
140+
bool(true)
141+
PRE DEC
142+
string(87) "Decrement on type bool has no effect, this will change in the next major version of PHP"
143+
bool(true)

Zend/zend_operators.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2657,9 +2657,18 @@ ZEND_API zend_result ZEND_FASTCALL increment_function(zval *op1) /* {{{ */
26572657
}
26582658
break;
26592659
case IS_FALSE:
2660-
case IS_TRUE:
2660+
case IS_TRUE: {
2661+
/* Error handler can undef/change type of op1, save it and reset it in case those cases */
2662+
zval copy;
2663+
ZVAL_COPY_VALUE(&copy, op1);
26612664
zend_error(E_WARNING, "Increment on type bool has no effect, this will change in the next major version of PHP");
2665+
zval_ptr_dtor(op1);
2666+
ZVAL_COPY_VALUE(op1, &copy);
2667+
if (EG(exception)) {
2668+
return FAILURE;
2669+
}
26622670
break;
2671+
}
26632672
case IS_REFERENCE:
26642673
op1 = Z_REFVAL_P(op1);
26652674
goto try_again;
@@ -2735,19 +2744,31 @@ ZEND_API zend_result ZEND_FASTCALL decrement_function(zval *op1) /* {{{ */
27352744
}
27362745
}
27372746
break;
2738-
case IS_NULL:
2747+
case IS_NULL: {
2748+
/* Error handler can undef/change type of op1, save it and reset it in case those cases */
2749+
zval copy;
2750+
ZVAL_COPY_VALUE(&copy, op1);
27392751
zend_error(E_WARNING, "Decrement on type null has no effect, this will change in the next major version of PHP");
2752+
zval_ptr_dtor(op1);
2753+
ZVAL_COPY_VALUE(op1, &copy);
27402754
if (EG(exception)) {
27412755
return FAILURE;
27422756
}
27432757
break;
2758+
}
27442759
case IS_FALSE:
2745-
case IS_TRUE:
2760+
case IS_TRUE: {
2761+
/* Error handler can undef/change type of op1, save it and reset it in case those cases */
2762+
zval copy;
2763+
ZVAL_COPY_VALUE(&copy, op1);
27462764
zend_error(E_WARNING, "Decrement on type bool has no effect, this will change in the next major version of PHP");
2765+
zval_ptr_dtor(op1);
2766+
ZVAL_COPY_VALUE(op1, &copy);
27472767
if (EG(exception)) {
27482768
return FAILURE;
27492769
}
27502770
break;
2771+
}
27512772
case IS_REFERENCE:
27522773
op1 = Z_REFVAL_P(op1);
27532774
goto try_again;

0 commit comments

Comments
 (0)