Skip to content

Commit 283ed45

Browse files
committed
Error handler can change type of op
Fix the empty string case, don't think this is the solution for non ASCII strings as I'm not sure *what* the behaviour should be
1 parent 0df3171 commit 283ed45

File tree

4 files changed

+109
-7
lines changed

4 files changed

+109
-7
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
Error handler can change type of operand of --
3+
--FILE--
4+
<?php
5+
6+
set_error_handler(function () {
7+
global $x;
8+
$x = 1;
9+
});
10+
11+
$x = '';
12+
$x--;
13+
var_dump($x);
14+
15+
?>
16+
DONE
17+
--EXPECT--
18+
int(-1)
19+
DONE
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
--TEST--
2+
Error handler can change type of operand of ++
3+
--FILE--
4+
<?php
5+
6+
set_error_handler(function () {
7+
global $x;
8+
$x = 1;
9+
});
10+
11+
$x = '';
12+
$x++;
13+
var_dump($x);
14+
15+
set_error_handler(function ($errno, $errstr) {
16+
var_dump($errstr);
17+
global $x;
18+
$x = new stdClass;
19+
});
20+
21+
$x = 'foo!';
22+
$x++;
23+
var_dump($x);
24+
25+
/* Interned string */
26+
$x = '!';
27+
$x++;
28+
var_dump($x);
29+
30+
?>
31+
DONE
32+
--EXPECT--
33+
string(1) "1"
34+
string(50) "Increment on non-alphanumeric string is deprecated"
35+
object(stdClass)#3 (0) {
36+
}
37+
string(50) "Increment on non-alphanumeric string is deprecated"
38+
object(stdClass)#3 (0) {
39+
}
40+
DONE
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Error handler can change type of operand of ++ to object with do_operator
3+
--EXTENSIONS--
4+
gmp
5+
--FILE--
6+
<?php
7+
8+
set_error_handler(function ($errno, $errstr) {
9+
var_dump($errstr);
10+
global $x;
11+
$x = gmp_init(10);
12+
});
13+
14+
$x = 'foo!';
15+
$x++;
16+
var_dump($x);
17+
18+
/* Interned string */
19+
$x = '!';
20+
$x++;
21+
var_dump($x);
22+
23+
?>
24+
DONE
25+
--EXPECT--
26+
string(50) "Increment on non-alphanumeric string is deprecated"
27+
object(GMP)#2 (1) {
28+
["num"]=>
29+
string(2) "10"
30+
}
31+
string(50) "Increment on non-alphanumeric string is deprecated"
32+
object(GMP)#2 (1) {
33+
["num"]=>
34+
string(2) "10"
35+
}
36+
DONE

Zend/zend_operators.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2506,7 +2506,7 @@ ZEND_API bool zend_string_only_has_ascii_alphanumeric(const zend_string *str)
25062506
return true;
25072507
}
25082508

2509-
static void ZEND_FASTCALL increment_string(zval *str) /* {{{ */
2509+
static bool ZEND_FASTCALL increment_string(zval *str) /* {{{ */
25102510
{
25112511
int carry=0;
25122512
size_t pos=Z_STRLEN_P(str)-1;
@@ -2515,20 +2515,25 @@ static void ZEND_FASTCALL increment_string(zval *str) /* {{{ */
25152515
int last=0; /* Shut up the compiler warning */
25162516
int ch;
25172517

2518-
if (Z_STRLEN_P(str) == 0) {
2518+
if (UNEXPECTED(Z_STRLEN_P(str) == 0)) {
25192519
zend_error(E_DEPRECATED, "Increment on non-alphanumeric string is deprecated");
25202520
if (EG(exception)) {
2521-
return;
2521+
return false;
25222522
}
2523-
zval_ptr_dtor_str(str);
2523+
/* A userland error handler can change the type from string to something else */
2524+
zval_ptr_dtor(str);
25242525
ZVAL_CHAR(str, '1');
2525-
return;
2526+
return true;
25262527
}
25272528

25282529
if (UNEXPECTED(!zend_string_only_has_ascii_alphanumeric(Z_STR_P(str)))) {
25292530
zend_error(E_DEPRECATED, "Increment on non-alphanumeric string is deprecated");
25302531
if (EG(exception)) {
2531-
return;
2532+
return false;
2533+
}
2534+
/* A userland error handler can change the type from string to something else */
2535+
if (Z_TYPE_P(str) != IS_STRING) {
2536+
return false;
25322537
}
25332538
}
25342539

@@ -2601,6 +2606,7 @@ static void ZEND_FASTCALL increment_string(zval *str) /* {{{ */
26012606
zend_string_free(Z_STR_P(str));
26022607
ZVAL_NEW_STR(str, t);
26032608
}
2609+
return true;
26042610
}
26052611
/* }}} */
26062612

@@ -2699,7 +2705,8 @@ ZEND_API zend_result ZEND_FASTCALL decrement_function(zval *op1) /* {{{ */
26992705
if (EG(exception)) {
27002706
return FAILURE;
27012707
}
2702-
zval_ptr_dtor_str(op1);
2708+
/* A userland error handler can change the type from string to something else */
2709+
zval_ptr_dtor(op1);
27032710
ZVAL_LONG(op1, -1);
27042711
break;
27052712
}

0 commit comments

Comments
 (0)