Skip to content

Commit da41102

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

13 files changed

+132
-145
lines changed

Zend/zend_compile.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4142,17 +4142,19 @@ static zend_result zend_compile_func_defined(znode *result, zend_ast_list *args)
41424142
}
41434143
/* }}} */
41444144

4145-
static zend_result zend_compile_func_chr(znode *result, zend_ast_list *args) /* {{{ */
4145+
static zend_result zend_compile_func_chr(znode *result, const zend_ast_list *args) /* {{{ */
41464146
{
4147-
4148-
if (args->children == 1 &&
4149-
args->child[0]->kind == ZEND_AST_ZVAL &&
4150-
Z_TYPE_P(zend_ast_get_zval(args->child[0])) == IS_LONG) {
4151-
4152-
zend_long c = Z_LVAL_P(zend_ast_get_zval(args->child[0])) & 0xff;
4153-
4147+
zval *zint;
4148+
if (
4149+
args->children == 1
4150+
&& args->child[0]->kind == ZEND_AST_ZVAL
4151+
&& (zint = zend_ast_get_zval(args->child[0]))
4152+
&& Z_TYPE_P(zint) == IS_LONG
4153+
&& Z_LVAL_P(zint) >= 0
4154+
&& Z_LVAL_P(zint) <= 255
4155+
) {
41544156
result->op_type = IS_CONST;
4155-
ZVAL_CHAR(&result->u.constant, c);
4157+
ZVAL_CHAR(&result->u.constant, Z_LVAL_P(zint));
41564158
return SUCCESS;
41574159
} else {
41584160
return FAILURE;

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
}
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)