Skip to content

Commit cab46b2

Browse files
authored
ext/standard: Deprecate passing integers outside the interval [0, 255] to chr() (php#19441)
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_integers_outside_the_interval_0_255_to_chr
1 parent 6009b8a commit cab46b2

15 files changed

+139
-160
lines changed

Zend/zend_compile.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4147,17 +4147,19 @@ static zend_result zend_compile_func_defined(znode *result, zend_ast_list *args)
41474147
}
41484148
/* }}} */
41494149

4150-
static zend_result zend_compile_func_chr(znode *result, zend_ast_list *args) /* {{{ */
4150+
static zend_result zend_compile_func_chr(znode *result, const zend_ast_list *args) /* {{{ */
41514151
{
4152-
4153-
if (args->children == 1 &&
4154-
args->child[0]->kind == ZEND_AST_ZVAL &&
4155-
Z_TYPE_P(zend_ast_get_zval(args->child[0])) == IS_LONG) {
4156-
4157-
zend_long c = Z_LVAL_P(zend_ast_get_zval(args->child[0])) & 0xff;
4158-
4152+
zval *zint;
4153+
if (
4154+
args->children == 1
4155+
&& args->child[0]->kind == ZEND_AST_ZVAL
4156+
&& (zint = zend_ast_get_zval(args->child[0]))
4157+
&& Z_TYPE_P(zint) == IS_LONG
4158+
&& Z_LVAL_P(zint) >= 0
4159+
&& Z_LVAL_P(zint) <= 255
4160+
) {
41594161
result->op_type = IS_CONST;
4160-
ZVAL_CHAR(&result->u.constant, c);
4162+
ZVAL_CHAR(&result->u.constant, Z_LVAL_P(zint));
41614163
return SUCCESS;
41624164
} else {
41634165
return FAILURE;

ext/gd/tests/gh16232.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ $bad_webp = __DIR__ . "/gh16232.webp";
99
copy($good_webp, $bad_webp);
1010
var_dump(imagecreatefromwbmp($bad_webp));
1111
$data = file_get_contents($bad_webp);
12-
$data[3] = chr(-1);
12+
$data[3] = chr(255);
1313
file_put_contents($bad_webp, $data);
1414
var_dump(imagecreatefromwbmp($bad_webp));
15-
$data[3] = chr(1000);
15+
$data[3] = chr(232);
1616
file_put_contents($bad_webp, $data);
1717
var_dump(imagecreatefromwbmp($bad_webp));
1818
unlink($bad_webp);

ext/standard/string.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2665,6 +2665,12 @@ PHP_FUNCTION(chr)
26652665
Z_PARAM_LONG(c)
26662666
ZEND_PARSE_PARAMETERS_END();
26672667

2668+
if (UNEXPECTED(c < 0 || c > 255)) {
2669+
php_error_docref(NULL, E_DEPRECATED,
2670+
"Providing a value not in-between 0 and 255 is deprecated,"
2671+
" this is because a byte value must be in the [0, 255] interval."
2672+
" The value used will be constrained using %% 256");
2673+
}
26682674
c &= 0xff;
26692675
RETURN_CHAR(c);
26702676
}

ext/standard/tests/array/array_filter_variation9.phpt

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Test array_filter() function : usage variations - built-in functions as 'callbac
88

99
echo "*** Testing array_filter() : usage variations - built-in functions as 'callback' argument ***\n";
1010

11-
$input = array(0, 1, -1, 10, 100, 1000);
11+
$input = array(0, 1, 10, 100);
1212

1313
// using built-in function 'is_int' as 'callback'
1414
var_dump( array_filter($input, 'is_int') );
@@ -34,33 +34,25 @@ echo "Done"
3434
?>
3535
--EXPECT--
3636
*** Testing array_filter() : usage variations - built-in functions as 'callback' argument ***
37-
array(6) {
37+
array(4) {
3838
[0]=>
3939
int(0)
4040
[1]=>
4141
int(1)
4242
[2]=>
43-
int(-1)
44-
[3]=>
4543
int(10)
46-
[4]=>
44+
[3]=>
4745
int(100)
48-
[5]=>
49-
int(1000)
5046
}
51-
array(6) {
47+
array(4) {
5248
[0]=>
5349
int(0)
5450
[1]=>
5551
int(1)
5652
[2]=>
57-
int(-1)
58-
[3]=>
5953
int(10)
60-
[4]=>
54+
[3]=>
6155
int(100)
62-
[5]=>
63-
int(1000)
6456
}
6557
array_filter(): Argument #2 ($callback) must be a valid callback or null, function "echo" not found or invalid function name
6658
array_filter(): Argument #2 ($callback) must be a valid callback or null, function "isset" not found or invalid function name
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
chr() with out of range values
3+
--FILE--
4+
<?php
5+
6+
var_dump("\xFF" == chr(-1));
7+
var_dump("\0" == chr(256));
8+
9+
?>
10+
--EXPECTF--
11+
Deprecated: chr(): Providing a value not in-between 0 and 255 is deprecated, this is because a byte value must be in the [0, 255] interval. The value used will be constrained using % 256 in %s on line 3
12+
bool(true)
13+
14+
Deprecated: chr(): Providing a value not in-between 0 and 255 is deprecated, this is because a byte value must be in the [0, 255] interval. The value used will be constrained using % 256 in %s on line 4
15+
bool(true)

ext/standard/tests/strings/chr_variation1.phpt

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,17 @@ Test chr() function : usage variations - test values for $ascii argument
55

66
echo "*** Testing chr() function: with unexpected inputs for 'ascii' argument ***\n";
77

8-
//defining a class
9-
class sample {
10-
public function __toString() {
11-
return "sample object";
12-
}
13-
}
14-
15-
//getting the resource
16-
$file_handle = fopen(__FILE__, "r");
17-
188
// array with different values for $input
19-
$inputs = array (
20-
21-
// integer values
22-
/*1*/ 0,
23-
1,
24-
255,
25-
256,
26-
27-
// float values
28-
/*5*/ 10.5,
29-
-20.5,
30-
1.1234e6,
31-
32-
// boolean values
33-
/*11*/ true,
34-
false,
35-
TRUE,
36-
FALSE,
37-
);
9+
$inputs = [
10+
0,
11+
1,
12+
255,
13+
// float values
14+
10.5,
15+
// bool values
16+
true,
17+
false,
18+
];
3819

3920
// loop through with each element of the $inputs array to test chr() function
4021
$count = 1;
@@ -44,8 +25,6 @@ foreach($inputs as $input) {
4425
$count ++;
4526
}
4627

47-
fclose($file_handle); //closing the file handle
48-
4928
?>
5029
--EXPECTF--
5130
*** Testing chr() function: with unexpected inputs for 'ascii' argument ***
@@ -56,22 +35,10 @@ string(2) "01"
5635
-- Iteration 3 --
5736
string(2) "ff"
5837
-- Iteration 4 --
59-
string(2) "00"
60-
-- Iteration 5 --
6138

6239
Deprecated: Implicit conversion from float 10.5 to int loses precision in %s on line %d
6340
string(2) "0a"
64-
-- Iteration 6 --
65-
66-
Deprecated: Implicit conversion from float -20.5 to int loses precision in %s on line %d
67-
string(2) "ec"
68-
-- Iteration 7 --
69-
string(2) "48"
70-
-- Iteration 8 --
71-
string(2) "01"
72-
-- Iteration 9 --
73-
string(2) "00"
74-
-- Iteration 10 --
41+
-- Iteration 5 --
7542
string(2) "01"
76-
-- Iteration 11 --
43+
-- Iteration 6 --
7744
string(2) "00"

0 commit comments

Comments
 (0)