Skip to content

Commit 897c377

Browse files
committed
Change warning type for well formed numeric float strings used as string offset
1 parent bc8d067 commit 897c377

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
@@ -1330,14 +1330,21 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type
13301330
case IS_STRING:
13311331
{
13321332
/* allow errors in string offset for BC reasons */
1333-
if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true)) {
1333+
zend_uchar numeric_string_type = is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true);
1334+
if (IS_LONG == numeric_string_type) {
13341335
/* emit Illegal string warning on leading numerical string */
13351336
if (0 == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)
13361337
&& type != BP_VAR_UNSET) {
13371338
zend_error(E_WARNING, "Illegal string offset \"%s\"", Z_STRVAL_P(dim));
13381339
}
13391340
return offset;
13401341
}
1342+
if (IS_DOUBLE == numeric_string_type) {
1343+
if (IS_DOUBLE == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)) {
1344+
zend_error(E_WARNING, "String offset cast occurred");
1345+
break;
1346+
}
1347+
}
13411348
zend_illegal_offset();
13421349
break;
13431350
}
@@ -2322,13 +2329,20 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z
23222329
case IS_STRING:
23232330
{
23242331
/* allow errors in string offset for BC reasons */
2325-
if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true)) {
2332+
zend_uchar numeric_string_type = is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true);
2333+
if (IS_LONG == numeric_string_type) {
23262334
/* emit Illegal string warning on leading numerical string */
23272335
if (0 == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)) {
23282336
zend_error(E_WARNING, "Illegal string offset \"%s\"", Z_STRVAL_P(dim));
23292337
}
23302338
goto out;
23312339
}
2340+
if (IS_DOUBLE == numeric_string_type) {
2341+
if (IS_DOUBLE == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)) {
2342+
zend_error(E_WARNING, "String offset cast occurred");
2343+
break;
2344+
}
2345+
}
23322346
if (type == BP_VAR_IS) {
23332347
ZVAL_NULL(result);
23342348
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
}
@@ -833,14 +840,21 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type)
833840
case IS_STRING:
834841
{
835842
/* allow errors in string offset for BC reasons */
836-
if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true)) {
843+
zend_uchar numeric_string_type = is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, true);
844+
if (IS_LONG == numeric_string_type) {
837845
/* emit Illegal string warning on leading numerical string */
838846
if (0 == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)
839847
&& type != BP_VAR_UNSET) {
840848
zend_error(E_WARNING, "Illegal string offset \"%s\"", Z_STRVAL_P(dim));
841849
}
842850
return offset;
843851
}
852+
if (IS_DOUBLE == numeric_string_type) {
853+
if (IS_DOUBLE == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)) {
854+
zend_error(E_WARNING, "String offset cast occurred");
855+
break;
856+
}
857+
}
844858
zend_type_error("Illegal offset type");
845859
break;
846860
}

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)