Skip to content

Commit 4855226

Browse files
committed
Merge branch 'PHP-8.2'
* PHP-8.2: Prevent int overflow on $decimals in number_format
2 parents e90c96b + 31bd628 commit 4855226

File tree

3 files changed

+68
-24
lines changed

3 files changed

+68
-24
lines changed

ext/standard/math.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -282,15 +282,11 @@ PHP_FUNCTION(round)
282282
ZEND_PARSE_PARAMETERS_END();
283283

284284
if (ZEND_NUM_ARGS() >= 2) {
285-
#if SIZEOF_ZEND_LONG > SIZEOF_INT
286285
if (precision >= 0) {
287-
places = precision > INT_MAX ? INT_MAX : (int)precision;
286+
places = ZEND_LONG_INT_OVFL(precision) ? INT_MAX : (int)precision;
288287
} else {
289-
places = precision <= INT_MIN ? INT_MIN+1 : (int)precision;
288+
places = ZEND_LONG_INT_UDFL(precision) ? INT_MIN : (int)precision;
290289
}
291-
#else
292-
places = precision;
293-
#endif
294290
}
295291

296292
switch (Z_TYPE_P(value)) {
@@ -1253,6 +1249,7 @@ PHP_FUNCTION(number_format)
12531249
{
12541250
zval* num;
12551251
zend_long dec = 0;
1252+
int dec_int;
12561253
char *thousand_sep = NULL, *dec_point = NULL;
12571254
size_t thousand_sep_len = 0, dec_point_len = 0;
12581255

@@ -1279,7 +1276,12 @@ PHP_FUNCTION(number_format)
12791276
break;
12801277

12811278
case IS_DOUBLE:
1282-
RETURN_STR(_php_math_number_format_ex(Z_DVAL_P(num), (int)dec, dec_point, dec_point_len, thousand_sep, thousand_sep_len));
1279+
if (dec >= 0) {
1280+
dec_int = ZEND_LONG_INT_OVFL(dec) ? INT_MAX : (int)dec;
1281+
} else {
1282+
dec_int = ZEND_LONG_INT_UDFL(dec) ? INT_MIN : (int)dec;
1283+
}
1284+
RETURN_STR(_php_math_number_format_ex(Z_DVAL_P(num), dec_int, dec_point, dec_point_len, thousand_sep, thousand_sep_len));
12831285
break;
12841286

12851287
EMPTY_SWITCH_DEFAULT_CASE()

ext/standard/tests/math/number_format_basiclong_64bit.phpt

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ define("MIN_32Bit", -2147483647 - 1);
1515
$longVals = array(
1616
MAX_64Bit, MIN_64Bit, MAX_32Bit, MIN_32Bit, MAX_64Bit - MAX_32Bit, MIN_64Bit - MIN_32Bit,
1717
MAX_32Bit + 1, MIN_32Bit - 1, MAX_32Bit * 2, (MAX_32Bit * 2) + 1, (MAX_32Bit * 2) - 1,
18-
MAX_64Bit -1, MIN_64Bit + 1
18+
MAX_64Bit -1, MAX_64Bit + 1, MIN_64Bit + 1, MIN_64Bit - 1
1919
);
2020

2121
$precisions = array(
@@ -41,7 +41,7 @@ foreach ($longVals as $longVal) {
4141
}
4242

4343
?>
44-
--EXPECTF--
44+
--EXPECT--
4545
--- testing: int(9223372036854775807)
4646
... with precision 5: string(31) "9,223,372,036,854,775,807.00000"
4747
... with precision 0: string(25) "9,223,372,036,854,775,807"
@@ -52,7 +52,7 @@ foreach ($longVals as $longVal) {
5252
... with precision -17: string(25) "9,200,000,000,000,000,000"
5353
... with precision -19: string(26) "10,000,000,000,000,000,000"
5454
... with precision -20: string(1) "0"
55-
... with precision %i: string(1) "0"
55+
... with precision -9223372036854775808: string(1) "0"
5656
--- testing: int(-9223372036854775808)
5757
... with precision 5: string(32) "-9,223,372,036,854,775,808.00000"
5858
... with precision 0: string(26) "-9,223,372,036,854,775,808"
@@ -63,7 +63,7 @@ foreach ($longVals as $longVal) {
6363
... with precision -17: string(26) "-9,200,000,000,000,000,000"
6464
... with precision -19: string(27) "-10,000,000,000,000,000,000"
6565
... with precision -20: string(1) "0"
66-
... with precision %i: string(1) "0"
66+
... with precision -9223372036854775808: string(1) "0"
6767
--- testing: int(2147483647)
6868
... with precision 5: string(19) "2,147,483,647.00000"
6969
... with precision 0: string(13) "2,147,483,647"
@@ -74,7 +74,7 @@ foreach ($longVals as $longVal) {
7474
... with precision -17: string(1) "0"
7575
... with precision -19: string(1) "0"
7676
... with precision -20: string(1) "0"
77-
... with precision %i: string(1) "0"
77+
... with precision -9223372036854775808: string(1) "0"
7878
--- testing: int(-2147483648)
7979
... with precision 5: string(20) "-2,147,483,648.00000"
8080
... with precision 0: string(14) "-2,147,483,648"
@@ -85,7 +85,7 @@ foreach ($longVals as $longVal) {
8585
... with precision -17: string(1) "0"
8686
... with precision -19: string(1) "0"
8787
... with precision -20: string(1) "0"
88-
... with precision %i: string(1) "0"
88+
... with precision -9223372036854775808: string(1) "0"
8989
--- testing: int(9223372034707292160)
9090
... with precision 5: string(31) "9,223,372,034,707,292,160.00000"
9191
... with precision 0: string(25) "9,223,372,034,707,292,160"
@@ -96,7 +96,7 @@ foreach ($longVals as $longVal) {
9696
... with precision -17: string(25) "9,200,000,000,000,000,000"
9797
... with precision -19: string(26) "10,000,000,000,000,000,000"
9898
... with precision -20: string(1) "0"
99-
... with precision %i: string(1) "0"
99+
... with precision -9223372036854775808: string(1) "0"
100100
--- testing: int(-9223372034707292160)
101101
... with precision 5: string(32) "-9,223,372,034,707,292,160.00000"
102102
... with precision 0: string(26) "-9,223,372,034,707,292,160"
@@ -107,7 +107,7 @@ foreach ($longVals as $longVal) {
107107
... with precision -17: string(26) "-9,200,000,000,000,000,000"
108108
... with precision -19: string(27) "-10,000,000,000,000,000,000"
109109
... with precision -20: string(1) "0"
110-
... with precision %i: string(1) "0"
110+
... with precision -9223372036854775808: string(1) "0"
111111
--- testing: int(2147483648)
112112
... with precision 5: string(19) "2,147,483,648.00000"
113113
... with precision 0: string(13) "2,147,483,648"
@@ -118,7 +118,7 @@ foreach ($longVals as $longVal) {
118118
... with precision -17: string(1) "0"
119119
... with precision -19: string(1) "0"
120120
... with precision -20: string(1) "0"
121-
... with precision %i: string(1) "0"
121+
... with precision -9223372036854775808: string(1) "0"
122122
--- testing: int(-2147483649)
123123
... with precision 5: string(20) "-2,147,483,649.00000"
124124
... with precision 0: string(14) "-2,147,483,649"
@@ -129,7 +129,7 @@ foreach ($longVals as $longVal) {
129129
... with precision -17: string(1) "0"
130130
... with precision -19: string(1) "0"
131131
... with precision -20: string(1) "0"
132-
... with precision %i: string(1) "0"
132+
... with precision -9223372036854775808: string(1) "0"
133133
--- testing: int(4294967294)
134134
... with precision 5: string(19) "4,294,967,294.00000"
135135
... with precision 0: string(13) "4,294,967,294"
@@ -140,7 +140,7 @@ foreach ($longVals as $longVal) {
140140
... with precision -17: string(1) "0"
141141
... with precision -19: string(1) "0"
142142
... with precision -20: string(1) "0"
143-
... with precision %i: string(1) "0"
143+
... with precision -9223372036854775808: string(1) "0"
144144
--- testing: int(4294967295)
145145
... with precision 5: string(19) "4,294,967,295.00000"
146146
... with precision 0: string(13) "4,294,967,295"
@@ -151,7 +151,7 @@ foreach ($longVals as $longVal) {
151151
... with precision -17: string(1) "0"
152152
... with precision -19: string(1) "0"
153153
... with precision -20: string(1) "0"
154-
... with precision %i: string(1) "0"
154+
... with precision -9223372036854775808: string(1) "0"
155155
--- testing: int(4294967293)
156156
... with precision 5: string(19) "4,294,967,293.00000"
157157
... with precision 0: string(13) "4,294,967,293"
@@ -162,7 +162,7 @@ foreach ($longVals as $longVal) {
162162
... with precision -17: string(1) "0"
163163
... with precision -19: string(1) "0"
164164
... with precision -20: string(1) "0"
165-
... with precision %i: string(1) "0"
165+
... with precision -9223372036854775808: string(1) "0"
166166
--- testing: int(9223372036854775806)
167167
... with precision 5: string(31) "9,223,372,036,854,775,806.00000"
168168
... with precision 0: string(25) "9,223,372,036,854,775,806"
@@ -173,7 +173,18 @@ foreach ($longVals as $longVal) {
173173
... with precision -17: string(25) "9,200,000,000,000,000,000"
174174
... with precision -19: string(26) "10,000,000,000,000,000,000"
175175
... with precision -20: string(1) "0"
176-
... with precision %i: string(1) "0"
176+
... with precision -9223372036854775808: string(1) "0"
177+
--- testing: float(9.223372036854776E+18)
178+
... with precision 5: string(31) "9,223,372,036,854,775,808.00000"
179+
... with precision 0: string(25) "9,223,372,036,854,775,808"
180+
... with precision -1: string(25) "9,223,372,036,854,775,808"
181+
... with precision -5: string(25) "9,223,372,036,854,800,384"
182+
... with precision -10: string(25) "9,223,372,040,000,000,000"
183+
... with precision -11: string(25) "9,223,372,000,000,000,000"
184+
... with precision -17: string(25) "9,200,000,000,000,000,000"
185+
... with precision -19: string(26) "10,000,000,000,000,000,000"
186+
... with precision -20: string(1) "0"
187+
... with precision -9223372036854775808: string(1) "0"
177188
--- testing: int(-9223372036854775807)
178189
... with precision 5: string(32) "-9,223,372,036,854,775,807.00000"
179190
... with precision 0: string(26) "-9,223,372,036,854,775,807"
@@ -184,4 +195,15 @@ foreach ($longVals as $longVal) {
184195
... with precision -17: string(26) "-9,200,000,000,000,000,000"
185196
... with precision -19: string(27) "-10,000,000,000,000,000,000"
186197
... with precision -20: string(1) "0"
187-
... with precision %i: string(1) "0"
198+
... with precision -9223372036854775808: string(1) "0"
199+
--- testing: float(-9.223372036854776E+18)
200+
... with precision 5: string(32) "-9,223,372,036,854,775,808.00000"
201+
... with precision 0: string(26) "-9,223,372,036,854,775,808"
202+
... with precision -1: string(26) "-9,223,372,036,854,775,808"
203+
... with precision -5: string(26) "-9,223,372,036,854,800,384"
204+
... with precision -10: string(26) "-9,223,372,040,000,000,000"
205+
... with precision -11: string(26) "-9,223,372,000,000,000,000"
206+
... with precision -17: string(26) "-9,200,000,000,000,000,000"
207+
... with precision -19: string(27) "-10,000,000,000,000,000,000"
208+
... with precision -20: string(1) "0"
209+
... with precision -9223372036854775808: string(1) "0"

ext/standard/tests/math/number_format_decimals.phpt

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ $values = array(
2929
MIN_INT32,
3030
);
3131

32-
$decimals = array(0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5);
32+
$decimals = array(0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5, PHP_INT_MIN);
3333

3434
foreach ($values as $value) {
3535
echo 'testing ';
@@ -42,7 +42,7 @@ foreach ($values as $value) {
4242
}
4343

4444
?>
45-
--EXPECT--
45+
--EXPECTF--
4646
testing float(1.5151)
4747
... with decimal places of 0: string(1) "2"
4848
... with decimal places of 1: string(3) "1.5"
@@ -55,6 +55,7 @@ testing float(1.5151)
5555
... with decimal places of -3: string(1) "0"
5656
... with decimal places of -4: string(1) "0"
5757
... with decimal places of -5: string(1) "0"
58+
... with decimal places of %i: string(1) "0"
5859
testing float(15.151)
5960
... with decimal places of 0: string(2) "15"
6061
... with decimal places of 1: string(4) "15.2"
@@ -67,6 +68,7 @@ testing float(15.151)
6768
... with decimal places of -3: string(1) "0"
6869
... with decimal places of -4: string(1) "0"
6970
... with decimal places of -5: string(1) "0"
71+
... with decimal places of %i: string(1) "0"
7072
testing float(151.51)
7173
... with decimal places of 0: string(3) "152"
7274
... with decimal places of 1: string(5) "151.5"
@@ -79,6 +81,7 @@ testing float(151.51)
7981
... with decimal places of -3: string(1) "0"
8082
... with decimal places of -4: string(1) "0"
8183
... with decimal places of -5: string(1) "0"
84+
... with decimal places of %i: string(1) "0"
8285
testing float(1515.1)
8386
... with decimal places of 0: string(5) "1,515"
8487
... with decimal places of 1: string(7) "1,515.1"
@@ -91,6 +94,7 @@ testing float(1515.1)
9194
... with decimal places of -3: string(5) "2,000"
9295
... with decimal places of -4: string(1) "0"
9396
... with decimal places of -5: string(1) "0"
97+
... with decimal places of %i: string(1) "0"
9498
testing int(15151)
9599
... with decimal places of 0: string(6) "15,151"
96100
... with decimal places of 1: string(8) "15,151.0"
@@ -103,6 +107,7 @@ testing int(15151)
103107
... with decimal places of -3: string(6) "15,000"
104108
... with decimal places of -4: string(6) "20,000"
105109
... with decimal places of -5: string(1) "0"
110+
... with decimal places of %i: string(1) "0"
106111
testing float(-1.5151)
107112
... with decimal places of 0: string(2) "-2"
108113
... with decimal places of 1: string(4) "-1.5"
@@ -115,6 +120,7 @@ testing float(-1.5151)
115120
... with decimal places of -3: string(1) "0"
116121
... with decimal places of -4: string(1) "0"
117122
... with decimal places of -5: string(1) "0"
123+
... with decimal places of %i: string(1) "0"
118124
testing float(-15.151)
119125
... with decimal places of 0: string(3) "-15"
120126
... with decimal places of 1: string(5) "-15.2"
@@ -127,6 +133,7 @@ testing float(-15.151)
127133
... with decimal places of -3: string(1) "0"
128134
... with decimal places of -4: string(1) "0"
129135
... with decimal places of -5: string(1) "0"
136+
... with decimal places of %i: string(1) "0"
130137
testing float(-151.51)
131138
... with decimal places of 0: string(4) "-152"
132139
... with decimal places of 1: string(6) "-151.5"
@@ -139,6 +146,7 @@ testing float(-151.51)
139146
... with decimal places of -3: string(1) "0"
140147
... with decimal places of -4: string(1) "0"
141148
... with decimal places of -5: string(1) "0"
149+
... with decimal places of %i: string(1) "0"
142150
testing float(-1515.1)
143151
... with decimal places of 0: string(6) "-1,515"
144152
... with decimal places of 1: string(8) "-1,515.1"
@@ -151,6 +159,7 @@ testing float(-1515.1)
151159
... with decimal places of -3: string(6) "-2,000"
152160
... with decimal places of -4: string(1) "0"
153161
... with decimal places of -5: string(1) "0"
162+
... with decimal places of %i: string(1) "0"
154163
testing int(-15151)
155164
... with decimal places of 0: string(7) "-15,151"
156165
... with decimal places of 1: string(9) "-15,151.0"
@@ -163,6 +172,7 @@ testing int(-15151)
163172
... with decimal places of -3: string(7) "-15,000"
164173
... with decimal places of -4: string(7) "-20,000"
165174
... with decimal places of -5: string(1) "0"
175+
... with decimal places of %i: string(1) "0"
166176
testing int(999)
167177
... with decimal places of 0: string(3) "999"
168178
... with decimal places of 1: string(5) "999.0"
@@ -175,6 +185,7 @@ testing int(999)
175185
... with decimal places of -3: string(5) "1,000"
176186
... with decimal places of -4: string(1) "0"
177187
... with decimal places of -5: string(1) "0"
188+
... with decimal places of %i: string(1) "0"
178189
testing int(-999)
179190
... with decimal places of 0: string(4) "-999"
180191
... with decimal places of 1: string(6) "-999.0"
@@ -187,6 +198,7 @@ testing int(-999)
187198
... with decimal places of -3: string(6) "-1,000"
188199
... with decimal places of -4: string(1) "0"
189200
... with decimal places of -5: string(1) "0"
201+
... with decimal places of %i: string(1) "0"
190202
testing float(999)
191203
... with decimal places of 0: string(3) "999"
192204
... with decimal places of 1: string(5) "999.0"
@@ -199,6 +211,7 @@ testing float(999)
199211
... with decimal places of -3: string(5) "1,000"
200212
... with decimal places of -4: string(1) "0"
201213
... with decimal places of -5: string(1) "0"
214+
... with decimal places of %i: string(1) "0"
202215
testing float(-999)
203216
... with decimal places of 0: string(4) "-999"
204217
... with decimal places of 1: string(6) "-999.0"
@@ -211,6 +224,7 @@ testing float(-999)
211224
... with decimal places of -3: string(6) "-1,000"
212225
... with decimal places of -4: string(1) "0"
213226
... with decimal places of -5: string(1) "0"
227+
... with decimal places of %i: string(1) "0"
214228
testing int(999999)
215229
... with decimal places of 0: string(7) "999,999"
216230
... with decimal places of 1: string(9) "999,999.0"
@@ -223,6 +237,7 @@ testing int(999999)
223237
... with decimal places of -3: string(9) "1,000,000"
224238
... with decimal places of -4: string(9) "1,000,000"
225239
... with decimal places of -5: string(9) "1,000,000"
240+
... with decimal places of %i: string(1) "0"
226241
testing int(-999999)
227242
... with decimal places of 0: string(8) "-999,999"
228243
... with decimal places of 1: string(10) "-999,999.0"
@@ -235,6 +250,7 @@ testing int(-999999)
235250
... with decimal places of -3: string(10) "-1,000,000"
236251
... with decimal places of -4: string(10) "-1,000,000"
237252
... with decimal places of -5: string(10) "-1,000,000"
253+
... with decimal places of %i: string(1) "0"
238254
testing float(999999)
239255
... with decimal places of 0: string(7) "999,999"
240256
... with decimal places of 1: string(9) "999,999.0"
@@ -247,6 +263,7 @@ testing float(999999)
247263
... with decimal places of -3: string(9) "1,000,000"
248264
... with decimal places of -4: string(9) "1,000,000"
249265
... with decimal places of -5: string(9) "1,000,000"
266+
... with decimal places of %i: string(1) "0"
250267
testing float(-999999)
251268
... with decimal places of 0: string(8) "-999,999"
252269
... with decimal places of 1: string(10) "-999,999.0"
@@ -259,6 +276,7 @@ testing float(-999999)
259276
... with decimal places of -3: string(10) "-1,000,000"
260277
... with decimal places of -4: string(10) "-1,000,000"
261278
... with decimal places of -5: string(10) "-1,000,000"
279+
... with decimal places of %i: string(1) "0"
262280
testing int(2147483647)
263281
... with decimal places of 0: string(13) "2,147,483,647"
264282
... with decimal places of 1: string(15) "2,147,483,647.0"
@@ -271,6 +289,7 @@ testing int(2147483647)
271289
... with decimal places of -3: string(13) "2,147,484,000"
272290
... with decimal places of -4: string(13) "2,147,480,000"
273291
... with decimal places of -5: string(13) "2,147,500,000"
292+
... with decimal places of %i: string(1) "0"
274293
testing int(-2147483648)
275294
... with decimal places of 0: string(14) "-2,147,483,648"
276295
... with decimal places of 1: string(16) "-2,147,483,648.0"
@@ -283,3 +302,4 @@ testing int(-2147483648)
283302
... with decimal places of -3: string(14) "-2,147,484,000"
284303
... with decimal places of -4: string(14) "-2,147,480,000"
285304
... with decimal places of -5: string(14) "-2,147,500,000"
305+
... with decimal places of %i: string(1) "0"

0 commit comments

Comments
 (0)