Skip to content

Commit b224878

Browse files
committed
Implement 'Saner Numeric Strings' RFC:
RFC: https://wiki.php.net/rfc/saner-numeric-strings This removes the -1 allow_error mode from is_numeric_string functions and replaces it by a trailing boolean out argument to preserve BC in a couple of places. Most of the changes can be resumed to "numeric" strings which emitted a E_NOTICE now emit a E_WARNING and "numeric" strings which emitted a E_WARNING now throw a TypeError. This mostly affects: - String offsets - Arithmetic operations - Bitwise operations Closes GH-5762
1 parent f759936 commit b224878

File tree

65 files changed

+2088
-1343
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+2088
-1343
lines changed

UPGRADING

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,27 @@ PHP 8.0 UPGRADE NOTES
217217
. debug_backtrace() and Exception::getTrace() will no longer provide
218218
references to arguments. It will not be possible to change function
219219
arguments through the backtrace.
220+
. The concept of numeric-string has been altered to be less error prone.
221+
Trailing whitespaces are now allowed in numeric strings making it symmetric
222+
with how leading whitespaces were treated.
223+
This mostly affects:
224+
- The is_numeric() function
225+
- String-to-string comparisons
226+
- Type declarations
227+
- Increment and Decrement operations
228+
The concept of "leading-numeric string" has been mostly dropped, the cases
229+
where this concept remains is in order to ease migration.
230+
String which emitted an E_NOTICE "A non well formed numeric value encountered"
231+
will now emit an E_WARNING "A non-numeric value encountered"
232+
and all strings which emitted an E_WARNING "A non-numeric value encountered"
233+
will now throw a TypeError.
234+
This mostly affects:
235+
- Arithmetic operations
236+
- Bitwise operations
237+
This E_WARNING to TypeError change also affects the E_WARNING
238+
"Illegal string offset 'string'" for illegal string offsets.
239+
This does not change the behaviour of explicit casts to int/float from strings.
240+
RFC: https://wiki.php.net/rfc/saner-numeric-strings
220241

221242
- COM:
222243
. Removed the ability to import case-insensitive constants from type

Zend/tests/add_006.phpt

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ $s2 = "876222numeric";
1111
$s3 = "48474874";
1212
$s4 = "25.68";
1313

14-
$c = $i + $s1;
15-
var_dump($c);
16-
14+
try {
15+
$c = $i + $s1;
16+
var_dump($c);
17+
} catch (\TypeError $e) {
18+
echo $e->getMessage() . \PHP_EOL;
19+
}
1720
$c = $i + $s2;
1821
var_dump($c);
1922

@@ -23,8 +26,12 @@ var_dump($c);
2326
$c = $i + $s4;
2427
var_dump($c);
2528

26-
$c = $s1 + $i;
27-
var_dump($c);
29+
try {
30+
$c = $s1 + $i;
31+
var_dump($c);
32+
} catch (\TypeError $e) {
33+
echo $e->getMessage() . \PHP_EOL;
34+
}
2835

2936
$c = $s2 + $i;
3037
var_dump($c);
@@ -38,18 +45,15 @@ var_dump($c);
3845
echo "Done\n";
3946
?>
4047
--EXPECTF--
41-
Warning: A non-numeric value encountered in %s on line %d
42-
int(75636)
48+
Unsupported operand types: int + string
4349

44-
Notice: A non well formed numeric value encountered in %s on line %d
50+
Warning: A non-numeric value encountered in %s on line %d
4551
int(951858)
4652
int(48550510)
4753
float(75661.68)
54+
Unsupported operand types: string + int
4855

4956
Warning: A non-numeric value encountered in %s on line %d
50-
int(75636)
51-
52-
Notice: A non well formed numeric value encountered in %s on line %d
5357
int(951858)
5458
int(48550510)
5559
float(75661.68)

Zend/tests/bug24773.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Bug #24773 (unset() of integers treated as arrays causes a crash)
66
unset($array["lvl1"]["lvl2"]["b"]);
77
?>
88
--EXPECTF--
9-
Fatal error: Uncaught Error: Cannot use string offset as an array in %s:%d
9+
Fatal error: Uncaught TypeError: Cannot access offset of type string on string in %s:%d
1010
Stack trace:
1111
#0 {main}
1212
thrown in %s on line %d

Zend/tests/bug31098.phpt

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,28 @@ var_dump(isset($a['b']));
1717

1818
$simpleString = "Bogus String Text";
1919
echo isset($simpleString->wrong)?"bug\n":"ok\n";
20-
echo isset($simpleString["wrong"])?"bug\n":"ok\n";
20+
try {
21+
echo isset($simpleString["wrong"])?"bug\n":"ok\n";
22+
} catch (\TypeError $e) {
23+
echo $e->getMessage() . \PHP_EOL;
24+
}
2125
echo isset($simpleString[-20])?"bug\n":"ok\n";
2226
echo isset($simpleString[0])?"ok\n":"bug\n";
2327
echo isset($simpleString["0"])?"ok\n":"bug\n";
2428
echo isset($simpleString["16"])?"ok\n":"bug\n";
2529
echo isset($simpleString["17"])?"bug\n":"ok\n";
2630
echo $simpleString->wrong === null?"ok\n":"bug\n";
27-
echo $simpleString["wrong"] === "B"?"ok\n":"bug\n";
31+
try {
32+
echo $simpleString["wrong"] === "B"?"ok\n":"bug\n";
33+
} catch (\TypeError $e) {
34+
echo $e->getMessage() . \PHP_EOL;
35+
}
2836
echo $simpleString["0"] === "B"?"ok\n":"bug\n";
29-
$simpleString["wrong"] = "f";
37+
try {
38+
$simpleString["wrong"] = "f";
39+
} catch (\TypeError $e) {
40+
echo $e->getMessage() . \PHP_EOL;
41+
}
3042
echo $simpleString["0"] === "f"?"ok\n":"bug\n";
3143
?>
3244
--EXPECTF--
@@ -46,10 +58,7 @@ ok
4658

4759
Warning: Attempt to read property "wrong" on string in %s on line %d
4860
ok
49-
50-
Warning: Illegal string offset "wrong" in %s on line %d
51-
ok
61+
Cannot access offset of type string on string
5262
ok
53-
54-
Warning: Illegal string offset "wrong" in %s on line %d
63+
Cannot access offset of type string on string
5564
ok

Zend/tests/bug39018_2.phpt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,8 @@ error_reporting(E_ALL);
88
$foo = 'test';
99
$x = @$foo[6];
1010

11-
print @($foo[100] + $foo[130]);
12-
13-
print "\nDone\n";
11+
var_dump(@($foo[100] . $foo[130]));
1412

1513
?>
1614
--EXPECT--
17-
0
18-
Done
15+
string(0) ""

Zend/tests/bug53432.phpt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ var_dump($str[-1] = 'a');
1616
var_dump($str);
1717

1818
$str = '';
19-
var_dump($str['foo'] = 'a');
19+
try {
20+
var_dump($str['foo'] = 'a');
21+
} catch (\TypeError $e) {
22+
echo $e->getMessage() . \PHP_EOL;
23+
}
2024
var_dump($str);
2125

2226
$str = '';
@@ -53,9 +57,7 @@ string(6) " a"
5357
Warning: Illegal string offset -1 in %s on line %d
5458
NULL
5559
string(0) ""
56-
57-
Warning: Illegal string offset "foo" in %s on line %d
58-
string(1) "a"
60+
Cannot access offset of type string on string
5961
string(1) "a"
6062
Error: [] operator not supported for strings
6163
string(0) ""

Zend/tests/bug64578.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ Bug #64578 (debug_backtrace in set_error_handler corrupts zend heap: segfault)
55

66
set_error_handler(function($no, $err) { var_dump($err); });
77

8-
function x($s) { $s['a'] = 1; };
8+
function x($s) { $s['2a'] = 1; };
99
$y = '1';
1010
x($y);
1111
print_r($y);
1212
--EXPECT--
13-
string(25) "Illegal string offset "a""
13+
string(26) "Illegal string offset "2a""
1414
1

Zend/tests/bug72057.phpt

Lines changed: 0 additions & 19 deletions
This file was deleted.

Zend/tests/bug73792.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ Bug #73792 (invalid foreach loop hangs script)
44
<?php
55
$a = 'aaa';
66

7-
foreach ($a['bbb'] as &$value) {
7+
foreach ($a['2bbb'] as &$value) {
88
echo 'loop';
99
}
1010

1111
unset($value);
1212
echo 'done';
1313
?>
1414
--EXPECTF--
15-
Warning: Illegal string offset "bbb" in %s on line %d
15+
Warning: Illegal string offset "2bbb" in %s on line %d
1616

1717
Fatal error: Uncaught Error: Cannot iterate on string offsets by reference in %sbug73792.php:4
1818
Stack trace:

Zend/tests/bug76534.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ set_error_handler(function ($severity, $message, $file, $line) {
77
});
88

99
$x = "foo";
10-
$y = &$x["bar"];
10+
$y = &$x["2bar"];
1111
?>
1212
--EXPECTF--
13-
Fatal error: Uncaught Exception: Illegal string offset "bar" in %s:%d
13+
Fatal error: Uncaught Exception: Illegal string offset "2bar" in %s:%d
1414
Stack trace:
1515
#0 %sbug76534.php(%d): {closure}(2, 'Illegal string ...', '%s', %d)
1616
#1 {main}

Zend/tests/const_dereference_002.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ error_reporting(E_ALL);
66

77
var_dump("foobar"[3]);
88
var_dump("foobar"[2][0]);
9-
var_dump("foobar"["foo"]["bar"]);
9+
var_dump("foobar"["0foo"]["0bar"]);
1010
--EXPECTF--
1111
string(1) "b"
1212
string(1) "o"
1313

14-
Warning: Illegal string offset "foo" in %s on line %d
14+
Warning: Illegal string offset "0foo" in %s on line %d
1515

16-
Warning: Illegal string offset "bar" in %s on line %d
16+
Warning: Illegal string offset "0bar" in %s on line %d
1717
string(1) "f"

Zend/tests/constant_expressions_dynamic.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Dynamic Constant Expressions
55

66
const C_0 = 0;
77
const C_1 = 1;
8-
const C_foo = "foo";
8+
const C_foo = "0foo";
99
const C_arr = [0 => 0, "foo" => "foo"];
1010

1111
const T_1 = C_1 | 2;

Zend/tests/indexing_001.phpt

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,13 @@ array(1) {
7575
}
7676
}
7777

78-
Warning: Illegal string offset "foo" in %s on line %d
79-
8078
Warning: Array to string conversion in %s on line %d
81-
82-
Warning: Only the first byte will be assigned to the string offset in %s on line %d
83-
string(1) "A"
84-
85-
Warning: Illegal string offset "foo" in %s on line %d
79+
Cannot access offset of type string on string
80+
string(0) ""
8681

8782
Warning: Array to string conversion in %s on line %d
88-
89-
Warning: Only the first byte will be assigned to the string offset in %s on line %d
90-
string(1) "A"
83+
Cannot access offset of type string on string
84+
string(1) " "
9185
Cannot use a scalar value as an array
9286
float(0.1)
9387
array(1) {

Zend/tests/int_conversion_exponents.phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@ int(-1234500000)
3939
int(1234500000)
4040
int(-1234500000)
4141

42-
Notice: A non well formed numeric value encountered in %s on line %d
42+
Warning: A non-numeric value encountered in %s on line %d
4343
int(1234500000)
4444

45-
Notice: A non well formed numeric value encountered in %s on line %d
45+
Warning: A non-numeric value encountered in %s on line %d
4646
int(-1234500000)
4747

48-
Notice: A non well formed numeric value encountered in %s on line %d
48+
Warning: A non-numeric value encountered in %s on line %d
4949
int(1234500000)
5050

51-
Notice: A non well formed numeric value encountered in %s on line %d
51+
Warning: A non-numeric value encountered in %s on line %d
5252
int(-1234500000)

Zend/tests/non_well_formed_param_exception.phpt

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)