Skip to content

Commit 0806916

Browse files
committed
Deprecate ctype_*() on non-string arguments
Non-string arguments will be interpreted as strings in the future. Warn about the upcoming behavior change. Part of https://wiki.php.net/rfc/deprecations_php_8_1.
1 parent a09754b commit 0806916

29 files changed

+502
-40
lines changed

UPGRADING

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,16 @@ PHP 8.1 UPGRADE NOTES
334334
. Returning by reference from a void function is deprecated.
335335
RFC: https://wiki.php.net/rfc/deprecations_php_8_1
336336

337+
- Ctype:
338+
. Passing a non-string value to ctype_*() functions is deprecated. A future
339+
version of PHP will make ctype_*() accept a string argument, which means
340+
that either only strings will be accepted (strict_types=1) or inputs may be
341+
converted to string (strict_types=0). In particular, using ctype_*($cp) to
342+
check whether an ASCII codepoint given as integer satisfies a given ctype
343+
predicate will no longer be supported. Instead ctype_*(chr($cp)) should be
344+
used.
345+
RFC: https://wiki.php.net/rfc/deprecations_php_8_1
346+
337347
- Date:
338348
. The date_sunrise() and date_sunset() functions have been deprecated in
339349
favor of date_sun_info().

ext/ctype/ctype.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,21 @@ static void ctype_impl(
6969
Z_PARAM_ZVAL(c)
7070
ZEND_PARSE_PARAMETERS_END();
7171

72+
if (Z_TYPE_P(c) == IS_STRING) {
73+
char *p = Z_STRVAL_P(c), *e = Z_STRVAL_P(c) + Z_STRLEN_P(c);
74+
if (e == p) {
75+
RETURN_FALSE;
76+
}
77+
while (p < e) {
78+
if (!iswhat((int)*(unsigned char *)(p++))) {
79+
RETURN_FALSE;
80+
}
81+
}
82+
RETURN_TRUE;
83+
}
84+
85+
php_error_docref(NULL, E_DEPRECATED,
86+
"Argument of type %s will be interpreted as string in the future", zend_zval_type_name(c));
7287
if (Z_TYPE_P(c) == IS_LONG) {
7388
if (Z_LVAL_P(c) <= 255 && Z_LVAL_P(c) >= 0) {
7489
RETURN_BOOL(iswhat((int)Z_LVAL_P(c)));
@@ -79,17 +94,6 @@ static void ctype_impl(
7994
} else {
8095
RETURN_BOOL(allow_minus);
8196
}
82-
} else if (Z_TYPE_P(c) == IS_STRING) {
83-
char *p = Z_STRVAL_P(c), *e = Z_STRVAL_P(c) + Z_STRLEN_P(c);
84-
if (e == p) {
85-
RETURN_FALSE;
86-
}
87-
while (p < e) {
88-
if(!iswhat((int)*(unsigned char *)(p++))) {
89-
RETURN_FALSE;
90-
}
91-
}
92-
RETURN_TRUE;
9397
} else {
9498
RETURN_FALSE;
9599
}

ext/ctype/tests/001.phpt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@
22
ctype on integers
33
--EXTENSIONS--
44
ctype
5+
--INI--
6+
error_reporting=E_ALL&~E_DEPRECATED
57
--FILE--
68
<?php
7-
setlocale(LC_ALL,"C");
9+
setlocale(LC_ALL,"C");
810

9-
function ctype_test_001($function) {
11+
function ctype_test_001($function) {
1012
$n=0;
1113
for($a=0;$a<256;$a++) {
1214
if($function($a)) $n++;
1315
}
14-
echo "$function $n\n";
15-
}
16+
echo "$function $n\n";
17+
}
18+
1619
ctype_test_001("ctype_lower");
1720
ctype_test_001("ctype_upper");
1821
ctype_test_001("ctype_alpha");

ext/ctype/tests/002.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function ctype_test_002($function) {
1313
// test portable POSIX characters 0..127
1414
for ($a=0;$a<128;$a++) {
1515
$c = chr($a);
16-
if($function($a)) $n1++;
16+
if($function($c)) $n1++;
1717
if($function("$c$c$c")) $n2++;
1818
if($function("1-$c$c$c-x")) $n3++;
1919
}

ext/ctype/tests/bug25745.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Bug #25745 (ctype functions fail with non-ascii characters)
33
--EXTENSIONS--
44
ctype
5+
--INI--
6+
error_reporting=E_ALL&~E_DEPRECATED
57
--FILE--
68
<?php
79
$funcs = array(

ext/ctype/tests/bug34645.phpt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ $id = 394829384;
88
var_dump(ctype_digit($id));
99
var_dump($id);
1010
?>
11-
--EXPECT--
11+
--EXPECTF--
12+
Deprecated: ctype_digit(): Argument of type int will be interpreted as string in the future in %s on line %d
1213
bool(true)
1314
int(394829384)

ext/ctype/tests/ctype_alnum_variation1.phpt

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,52 +93,82 @@ fclose($fp);
9393

9494
setlocale(LC_CTYPE, $orig);
9595
?>
96-
--EXPECT--
96+
--EXPECTF--
9797
*** Testing ctype_alnum() : usage variations ***
9898

9999
-- Iteration 1 --
100+
101+
Deprecated: ctype_alnum(): Argument of type int will be interpreted as string in the future in %s on line %d
100102
bool(false)
101103

102104
-- Iteration 2 --
105+
106+
Deprecated: ctype_alnum(): Argument of type int will be interpreted as string in the future in %s on line %d
103107
bool(false)
104108

105109
-- Iteration 3 --
110+
111+
Deprecated: ctype_alnum(): Argument of type int will be interpreted as string in the future in %s on line %d
106112
bool(true)
107113

108114
-- Iteration 4 --
115+
116+
Deprecated: ctype_alnum(): Argument of type int will be interpreted as string in the future in %s on line %d
109117
bool(false)
110118

111119
-- Iteration 5 --
120+
121+
Deprecated: ctype_alnum(): Argument of type float will be interpreted as string in the future in %s on line %d
112122
bool(false)
113123

114124
-- Iteration 6 --
125+
126+
Deprecated: ctype_alnum(): Argument of type float will be interpreted as string in the future in %s on line %d
115127
bool(false)
116128

117129
-- Iteration 7 --
130+
131+
Deprecated: ctype_alnum(): Argument of type float will be interpreted as string in the future in %s on line %d
118132
bool(false)
119133

120134
-- Iteration 8 --
135+
136+
Deprecated: ctype_alnum(): Argument of type float will be interpreted as string in the future in %s on line %d
121137
bool(false)
122138

123139
-- Iteration 9 --
140+
141+
Deprecated: ctype_alnum(): Argument of type float will be interpreted as string in the future in %s on line %d
124142
bool(false)
125143

126144
-- Iteration 10 --
145+
146+
Deprecated: ctype_alnum(): Argument of type null will be interpreted as string in the future in %s on line %d
127147
bool(false)
128148

129149
-- Iteration 11 --
150+
151+
Deprecated: ctype_alnum(): Argument of type null will be interpreted as string in the future in %s on line %d
130152
bool(false)
131153

132154
-- Iteration 12 --
155+
156+
Deprecated: ctype_alnum(): Argument of type bool will be interpreted as string in the future in %s on line %d
133157
bool(false)
134158

135159
-- Iteration 13 --
160+
161+
Deprecated: ctype_alnum(): Argument of type bool will be interpreted as string in the future in %s on line %d
136162
bool(false)
137163

138164
-- Iteration 14 --
165+
166+
Deprecated: ctype_alnum(): Argument of type bool will be interpreted as string in the future in %s on line %d
139167
bool(false)
140168

141169
-- Iteration 15 --
170+
171+
Deprecated: ctype_alnum(): Argument of type bool will be interpreted as string in the future in %s on line %d
142172
bool(false)
143173

144174
-- Iteration 16 --
@@ -148,6 +178,8 @@ bool(false)
148178
bool(false)
149179

150180
-- Iteration 18 --
181+
182+
Deprecated: ctype_alnum(): Argument of type array will be interpreted as string in the future in %s on line %d
151183
bool(false)
152184

153185
-- Iteration 19 --
@@ -160,13 +192,21 @@ bool(true)
160192
bool(true)
161193

162194
-- Iteration 22 --
195+
196+
Deprecated: ctype_alnum(): Argument of type classA will be interpreted as string in the future in %s on line %d
163197
bool(false)
164198

165199
-- Iteration 23 --
200+
201+
Deprecated: ctype_alnum(): Argument of type null will be interpreted as string in the future in %s on line %d
166202
bool(false)
167203

168204
-- Iteration 24 --
205+
206+
Deprecated: ctype_alnum(): Argument of type null will be interpreted as string in the future in %s on line %d
169207
bool(false)
170208

171209
-- Iteration 25 --
210+
211+
Deprecated: ctype_alnum(): Argument of type resource will be interpreted as string in the future in %s on line %d
172212
bool(false)

ext/ctype/tests/ctype_alnum_variation2.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ echo "*** Testing ctype_alnum() : usage variations ***\n";
1414
$orig = setlocale(LC_CTYPE, "C");
1515

1616
for ($i = 0; $i < 256; $i++) {
17-
if (ctype_alnum($i)) {
17+
if (ctype_alnum(chr($i))) {
1818
echo "character code $i is alpha numeric\n";
1919
}
2020
}

ext/ctype/tests/ctype_alpha_variation1.phpt

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,52 +93,82 @@ fclose($fp);
9393

9494
setlocale(LC_CTYPE, $orig);
9595
?>
96-
--EXPECT--
96+
--EXPECTF--
9797
*** Testing ctype_alpha() : usage variations ***
9898

9999
-- Iteration 1 --
100+
101+
Deprecated: ctype_alpha(): Argument of type int will be interpreted as string in the future in %s on line %d
100102
bool(false)
101103

102104
-- Iteration 2 --
105+
106+
Deprecated: ctype_alpha(): Argument of type int will be interpreted as string in the future in %s on line %d
103107
bool(false)
104108

105109
-- Iteration 3 --
110+
111+
Deprecated: ctype_alpha(): Argument of type int will be interpreted as string in the future in %s on line %d
106112
bool(false)
107113

108114
-- Iteration 4 --
115+
116+
Deprecated: ctype_alpha(): Argument of type int will be interpreted as string in the future in %s on line %d
109117
bool(false)
110118

111119
-- Iteration 5 --
120+
121+
Deprecated: ctype_alpha(): Argument of type float will be interpreted as string in the future in %s on line %d
112122
bool(false)
113123

114124
-- Iteration 6 --
125+
126+
Deprecated: ctype_alpha(): Argument of type float will be interpreted as string in the future in %s on line %d
115127
bool(false)
116128

117129
-- Iteration 7 --
130+
131+
Deprecated: ctype_alpha(): Argument of type float will be interpreted as string in the future in %s on line %d
118132
bool(false)
119133

120134
-- Iteration 8 --
135+
136+
Deprecated: ctype_alpha(): Argument of type float will be interpreted as string in the future in %s on line %d
121137
bool(false)
122138

123139
-- Iteration 9 --
140+
141+
Deprecated: ctype_alpha(): Argument of type float will be interpreted as string in the future in %s on line %d
124142
bool(false)
125143

126144
-- Iteration 10 --
145+
146+
Deprecated: ctype_alpha(): Argument of type null will be interpreted as string in the future in %s on line %d
127147
bool(false)
128148

129149
-- Iteration 11 --
150+
151+
Deprecated: ctype_alpha(): Argument of type null will be interpreted as string in the future in %s on line %d
130152
bool(false)
131153

132154
-- Iteration 12 --
155+
156+
Deprecated: ctype_alpha(): Argument of type bool will be interpreted as string in the future in %s on line %d
133157
bool(false)
134158

135159
-- Iteration 13 --
160+
161+
Deprecated: ctype_alpha(): Argument of type bool will be interpreted as string in the future in %s on line %d
136162
bool(false)
137163

138164
-- Iteration 14 --
165+
166+
Deprecated: ctype_alpha(): Argument of type bool will be interpreted as string in the future in %s on line %d
139167
bool(false)
140168

141169
-- Iteration 15 --
170+
171+
Deprecated: ctype_alpha(): Argument of type bool will be interpreted as string in the future in %s on line %d
142172
bool(false)
143173

144174
-- Iteration 16 --
@@ -148,6 +178,8 @@ bool(false)
148178
bool(false)
149179

150180
-- Iteration 18 --
181+
182+
Deprecated: ctype_alpha(): Argument of type array will be interpreted as string in the future in %s on line %d
151183
bool(false)
152184

153185
-- Iteration 19 --
@@ -160,13 +192,21 @@ bool(true)
160192
bool(true)
161193

162194
-- Iteration 22 --
195+
196+
Deprecated: ctype_alpha(): Argument of type classA will be interpreted as string in the future in %s on line %d
163197
bool(false)
164198

165199
-- Iteration 23 --
200+
201+
Deprecated: ctype_alpha(): Argument of type null will be interpreted as string in the future in %s on line %d
166202
bool(false)
167203

168204
-- Iteration 24 --
205+
206+
Deprecated: ctype_alpha(): Argument of type null will be interpreted as string in the future in %s on line %d
169207
bool(false)
170208

171209
-- Iteration 25 --
210+
211+
Deprecated: ctype_alpha(): Argument of type resource will be interpreted as string in the future in %s on line %d
172212
bool(false)

ext/ctype/tests/ctype_alpha_variation2.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ echo "*** Testing ctype_alpha() : usage variations ***\n";
1414
$orig = setlocale(LC_CTYPE, "C");
1515

1616
for ($i = 0; $i < 256; $i++) {
17-
if (ctype_alpha($i)) {
17+
if (ctype_alpha(chr($i))) {
1818
echo "character code $i is alphabetic\n";
1919
}
2020
}

0 commit comments

Comments
 (0)