Skip to content

Commit 7a3f906

Browse files
committed
Change warning type for well formed numeric float strings used as string offset
1 parent e9ac343 commit 7a3f906

File tree

6 files changed

+107
-13
lines changed

6 files changed

+107
-13
lines changed

Zend/tests/numeric_strings/string_offset.phpt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,21 @@ echo "Done\n";
3939
?>
4040
--EXPECTF--
4141
string(1) "l"
42-
Illegal offset type
42+
43+
Warning: String offset cast occurred in %s on line %d
4344
string(1) "l"
44-
Illegal offset type
4545
string(1) "l"
46-
Illegal offset type
46+
47+
Warning: String offset cast occurred in %s on line %d
48+
string(1) "l"
49+
string(1) "l"
50+
51+
Warning: String offset cast occurred in %s on line %d
52+
string(1) "l"
53+
string(1) "l"
54+
55+
Warning: String offset cast occurred in %s on line %d
4756
string(1) "l"
48-
Illegal offset type
4957

5058
Warning: Illegal string offset "7str" in %s on line %d
5159
string(1) "l"

Zend/tests/offset_string.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ Warning: String offset cast occurred in %s on line %d
5757
string(1) "S"
5858
Illegal offset type
5959
string(1) "c"
60-
Illegal offset type
60+
61+
Warning: String offset cast occurred in %s on line %d
62+
string(1) "o"
6163

6264
Warning: Illegal string offset "15 and then some" in %s on line %d
6365
string(1) "r"

Zend/zend_execute.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,14 +1342,21 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type
13421342
case IS_STRING:
13431343
{
13441344
/* allow errors in string offset for BC reasons */
1345-
if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true)) {
1345+
zend_uchar numeric_string_type = is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true);
1346+
if (IS_LONG == numeric_string_type) {
13461347
/* emit Illegal string warning on leading numerical string */
13471348
if (0 == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)
13481349
&& type != BP_VAR_UNSET) {
13491350
zend_error(E_WARNING, "Illegal string offset \"%s\"", Z_STRVAL_P(dim));
13501351
}
13511352
return offset;
13521353
}
1354+
if (IS_DOUBLE == numeric_string_type) {
1355+
if (IS_DOUBLE == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)) {
1356+
zend_error(E_WARNING, "String offset cast occurred");
1357+
break;
1358+
}
1359+
}
13531360
zend_illegal_offset();
13541361
break;
13551362
}
@@ -2334,13 +2341,20 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z
23342341
case IS_STRING:
23352342
{
23362343
/* allow errors in string offset for BC reasons */
2337-
if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true)) {
2344+
zend_uchar numeric_string_type = is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true);
2345+
if (IS_LONG == numeric_string_type) {
23382346
/* emit Illegal string warning on leading numerical string */
23392347
if (0 == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)) {
23402348
zend_error(E_WARNING, "Illegal string offset \"%s\"", Z_STRVAL_P(dim));
23412349
}
23422350
goto out;
23432351
}
2352+
if (IS_DOUBLE == numeric_string_type) {
2353+
if (IS_DOUBLE == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)) {
2354+
zend_error(E_WARNING, "String offset cast occurred");
2355+
break;
2356+
}
2357+
}
23442358
if (type == BP_VAR_IS) {
23452359
ZVAL_NULL(result);
23462360
return;

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -680,13 +680,20 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_str_r_helper(zval *container, zval
680680
case IS_STRING:
681681
{
682682
/* allow errors in string offset for BC reasons */
683-
if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true)) {
683+
zend_uchar numeric_string_type = is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true);
684+
if (IS_LONG == numeric_string_type) {
684685
/* emit Illegal string warning on leading numerical string */
685686
if (0 == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)) {
686687
zend_error(E_WARNING, "Illegal string offset \"%s\"", Z_STRVAL_P(dim));
687688
}
688689
goto out;
689690
}
691+
if (IS_DOUBLE == numeric_string_type) {
692+
if (IS_DOUBLE == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)) {
693+
zend_error(E_WARNING, "String offset cast occurred");
694+
break;
695+
}
696+
}
690697
zend_type_error("Illegal offset type");
691698
break;
692699
}
@@ -827,14 +834,21 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type)
827834
case IS_STRING:
828835
{
829836
/* allow errors in string offset for BC reasons */
830-
if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true)) {
837+
zend_uchar numeric_string_type = is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true);
838+
if (IS_LONG == numeric_string_type) {
831839
/* emit Illegal string warning on leading numerical string */
832840
if (0 == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)
833841
&& type != BP_VAR_UNSET) {
834842
zend_error(E_WARNING, "Illegal string offset \"%s\"", Z_STRVAL_P(dim));
835843
}
836844
return offset;
837845
}
846+
if (IS_DOUBLE == numeric_string_type) {
847+
if (IS_DOUBLE == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)) {
848+
zend_error(E_WARNING, "String offset cast occurred");
849+
break;
850+
}
851+
}
838852
zend_type_error("Illegal offset type");
839853
break;
840854
}

ext/opcache/tests/jit/fetch_dim_r_003.phpt

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,30 @@ function foo() {
3636
$x = "2";
3737
$y = "x";
3838
var_dump($a[$x . $y]);
39+
try {
40+
var_dump($a["5.5"]);
41+
} catch (\TypeError $e) {
42+
echo $e->getMessage() . \PHP_EOL;
43+
}
44+
$x = "5.";
45+
$y = "5";
46+
try {
47+
var_dump($a[$x . $y]);
48+
} catch (\TypeError $e) {
49+
echo $e->getMessage() . \PHP_EOL;
50+
}
51+
try {
52+
var_dump($a["5.5cx"]);
53+
} catch (\TypeError $e) {
54+
echo $e->getMessage() . \PHP_EOL;
55+
}
56+
try {
57+
$x = "5.5";
58+
$y = "c";
59+
var_dump($a[$x . $y]);
60+
} catch (\TypeError $e) {
61+
echo $e->getMessage() . \PHP_EOL;
62+
}
3963
}
4064
foo();
4165
--EXPECTF--
@@ -58,8 +82,16 @@ string(1) "A"
5882
Illegal offset type
5983
Illegal offset type
6084

61-
Warning: Illegal string offset "2x" in %sfetch_dim_r_003.php on line 24
85+
Warning: Illegal string offset "2x" in %s on line %d
6286
string(1) "C"
6387

64-
Warning: Illegal string offset "2x" in %sfetch_dim_r_003.php on line 27
88+
Warning: Illegal string offset "2x" in %s on line %d
6589
string(1) "C"
90+
91+
Warning: String offset cast occurred in %s on line %d
92+
string(1) "F"
93+
94+
Warning: String offset cast occurred in %s on line %d
95+
string(1) "F"
96+
Illegal offset type
97+
Illegal offset type

ext/opcache/tests/jit/fetch_dim_r_004.phpt

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,22 @@ foo("2x");
3434
$x=2;
3535
$y="x";
3636
foo($x.$y);
37+
foo("5.5");
38+
$x = "5.";
39+
$y = "5";
40+
foo($x.$y);
41+
try {
42+
foo("5.5c");
43+
} catch (\TypeError $e) {
44+
echo $e->getMessage() . \PHP_EOL;
45+
}
46+
try {
47+
$x = "5.5";
48+
$y = "c";
49+
foo($x.$y);
50+
} catch (\TypeError $e) {
51+
echo $e->getMessage() . \PHP_EOL;
52+
}
3753
--EXPECTF--
3854
string(1) "A"
3955
string(1) "C"
@@ -54,8 +70,16 @@ string(1) "A"
5470
Illegal offset type
5571
Illegal offset type
5672

57-
Warning: Illegal string offset "2x" in %sfetch_dim_r_004.php on line 5
73+
Warning: Illegal string offset "2x" in %s on line %d
5874
string(1) "C"
5975

60-
Warning: Illegal string offset "2x" in %sfetch_dim_r_004.php on line 5
76+
Warning: Illegal string offset "2x" in %s on line %d
6177
string(1) "C"
78+
79+
Warning: String offset cast occurred in %s on line %d
80+
string(1) "F"
81+
82+
Warning: String offset cast occurred in %s on line %d
83+
string(1) "F"
84+
Illegal offset type
85+
Illegal offset type

0 commit comments

Comments
 (0)