Skip to content

Commit ebf7e7c

Browse files
committed
made scale argument of bcmath functions non-negative integer
1 parent 77ee4e6 commit ebf7e7c

File tree

4 files changed

+78
-23
lines changed

4 files changed

+78
-23
lines changed

ext/bcmath/bcmath.c

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ PHP_FUNCTION(bcadd)
152152
ZEND_PARSE_PARAMETERS_END();
153153

154154
if (ZEND_NUM_ARGS() == 3) {
155-
scale = (int) (scale_param < 0 ? 0 : scale_param);
155+
if ((int)scale_param < 0) {
156+
zend_argument_value_error(3, "must be greater than or equal to 0");
157+
RETURN_THROWS();
158+
}
159+
scale = (int) scale_param;
156160
}
157161

158162
bc_init_num(&first);
@@ -187,7 +191,11 @@ PHP_FUNCTION(bcsub)
187191
ZEND_PARSE_PARAMETERS_END();
188192

189193
if (ZEND_NUM_ARGS() == 3) {
190-
scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
194+
if ((int)scale_param < 0) {
195+
zend_argument_value_error(3, "must be greater than or equal to 0");
196+
RETURN_THROWS();
197+
}
198+
scale = (int) scale_param;
191199
}
192200

193201
bc_init_num(&first);
@@ -222,7 +230,11 @@ PHP_FUNCTION(bcmul)
222230
ZEND_PARSE_PARAMETERS_END();
223231

224232
if (ZEND_NUM_ARGS() == 3) {
225-
scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
233+
if ((int)scale_param < 0) {
234+
zend_argument_value_error(3, "must be greater than or equal to 0");
235+
RETURN_THROWS();
236+
}
237+
scale = (int) scale_param;
226238
}
227239

228240
bc_init_num(&first);
@@ -257,7 +269,11 @@ PHP_FUNCTION(bcdiv)
257269
ZEND_PARSE_PARAMETERS_END();
258270

259271
if (ZEND_NUM_ARGS() == 3) {
260-
scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
272+
if ((int)scale_param < 0) {
273+
zend_argument_value_error(3, "must be greater than or equal to 0");
274+
RETURN_THROWS();
275+
}
276+
scale = (int) scale_param;
261277
}
262278

263279
bc_init_num(&first);
@@ -299,7 +315,11 @@ PHP_FUNCTION(bcmod)
299315
ZEND_PARSE_PARAMETERS_END();
300316

301317
if (ZEND_NUM_ARGS() == 3) {
302-
scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
318+
if ((int)scale_param < 0) {
319+
zend_argument_value_error(3, "must be greater than or equal to 0");
320+
RETURN_THROWS();
321+
}
322+
scale = (int) scale_param;
303323
}
304324

305325
bc_init_num(&first);
@@ -329,16 +349,16 @@ PHP_FUNCTION(bcmod)
329349
PHP_FUNCTION(bcpowmod)
330350
{
331351
zend_string *left, *right, *modulus;
352+
zend_long scale_param = 0;
332353
bc_num first, second, mod, result;
333-
zend_long scale = BCG(bc_precision);
334-
int scale_int;
354+
int scale = (int)BCG(bc_precision);
335355

336356
ZEND_PARSE_PARAMETERS_START(3, 4)
337357
Z_PARAM_STR(left)
338358
Z_PARAM_STR(right)
339359
Z_PARAM_STR(modulus)
340360
Z_PARAM_OPTIONAL
341-
Z_PARAM_LONG(scale)
361+
Z_PARAM_LONG(scale_param)
342362
ZEND_PARSE_PARAMETERS_END();
343363

344364
bc_init_num(&first);
@@ -349,10 +369,16 @@ PHP_FUNCTION(bcpowmod)
349369
php_str2num(&second, ZSTR_VAL(right));
350370
php_str2num(&mod, ZSTR_VAL(modulus));
351371

352-
scale_int = (int) ((int)scale < 0 ? 0 : scale);
372+
if (ZEND_NUM_ARGS() == 4) {
373+
if ((int)scale_param < 0) {
374+
zend_argument_value_error(4, "must be greater than or equal to 0");
375+
RETURN_THROWS();
376+
}
377+
scale = (int) scale_param;
378+
}
353379

354-
if (bc_raisemod(first, second, mod, &result, scale_int) != -1) {
355-
RETVAL_STR(bc_num2str_ex(result, scale_int));
380+
if (bc_raisemod(first, second, mod, &result, scale) != -1) {
381+
RETVAL_STR(bc_num2str_ex(result, scale));
356382
} else {
357383
RETVAL_FALSE;
358384
}
@@ -382,7 +408,11 @@ PHP_FUNCTION(bcpow)
382408
ZEND_PARSE_PARAMETERS_END();
383409

384410
if (ZEND_NUM_ARGS() == 3) {
385-
scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
411+
if ((int)scale_param < 0) {
412+
zend_argument_value_error(3, "must be greater than or equal to 0");
413+
RETURN_THROWS();
414+
}
415+
scale = (int) scale_param;
386416
}
387417

388418
bc_init_num(&first);
@@ -416,7 +446,11 @@ PHP_FUNCTION(bcsqrt)
416446
ZEND_PARSE_PARAMETERS_END();
417447

418448
if (ZEND_NUM_ARGS() == 2) {
419-
scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
449+
if ((int)scale_param < 0) {
450+
zend_argument_value_error(2, "must be greater than or equal to 0");
451+
RETURN_THROWS();
452+
}
453+
scale = (int) scale_param;
420454
}
421455

422456
bc_init_num(&result);
@@ -450,7 +484,11 @@ PHP_FUNCTION(bccomp)
450484
ZEND_PARSE_PARAMETERS_END();
451485

452486
if (ZEND_NUM_ARGS() == 3) {
453-
scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
487+
if ((int)scale_param < 0) {
488+
zend_argument_value_error(3, "must be greater than or equal to 0");
489+
RETURN_THROWS();
490+
}
491+
scale = (int) scale_param;
454492
}
455493

456494
bc_init_num(&first);
@@ -484,7 +522,11 @@ PHP_FUNCTION(bcscale)
484522
old_scale = BCG(bc_precision);
485523

486524
if (ZEND_NUM_ARGS() == 1) {
487-
BCG(bc_precision) = ((int)new_scale < 0) ? 0 : new_scale;
525+
if ((int)new_scale < 0) {
526+
zend_argument_value_error(1, "must be greater than or equal to 0");
527+
RETURN_THROWS();
528+
}
529+
BCG(bc_precision) = new_scale;
488530
}
489531

490532
RETURN_LONG(old_scale);
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
--TEST--
2-
bcscale() with negative argument
2+
bcscale() fails with negative argument
33
--SKIPIF--
44
<?php if(!extension_loaded("bcmath")) print "skip"; ?>
55
--INI--
66
bcmath.scale=0
77
--FILE--
88
<?php
9-
bcscale(-4);
109
echo bcdiv("20.56", "4");
10+
try {
11+
bcscale(-4);
12+
} catch (\ValueError $e) {
13+
echo \PHP_EOL . $e->getMessage() . \PHP_EOL;
14+
}
1115
?>
1216
--EXPECT--
1317
5
18+
bcscale(): Argument #1 ($scale) must be greater than or equal to 0

ext/bcmath/tests/bug60377.phpt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@ bcscale related problem on 64bits platforms
55
if (PHP_INT_SIZE != 8) die("skip: 64-bit only"); ?>
66
--FILE--
77
<?php
8-
$var48 = bcscale(634314234334311);
8+
try {
9+
$var48 = bcscale(634314234334311);
10+
} catch (\ValueError $e) {
11+
echo $e->getMessage() . \PHP_EOL;
12+
}
913
$var67 = bcsqrt(0);
1014
$var414 = bcadd(0,-1,10);
11-
die('ALIVE');
1215
?>
16+
1317
--EXPECT--
14-
ALIVE
18+
bcscale(): Argument #1 ($scale) must be greater than or equal to 0

ext/bcmath/tests/bug72093.phpt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
--TEST--
2-
Bug 72093: bcpowmod accepts negative scale and corrupts _one_ definition
2+
Bug 72093: bcpowmod fails on negative scale and corrupts _one_ definition
33
--SKIPIF--
44
<?php
55
if(!extension_loaded("bcmath")) print "skip";
66
?>
77
--FILE--
88
<?php
9-
var_dump(bcpowmod(1, 0, 128, -200));
9+
try {
10+
var_dump(bcpowmod(1, 0, 128, -200));
11+
} catch (\ValueError $e) {
12+
echo $e->getMessage() . \PHP_EOL;
13+
}
1014
var_dump(bcpowmod(1, 1.2, 1, 1));
1115
?>
1216
--EXPECTF--
13-
string(1) "1"
17+
bcpowmod(): Argument #4 ($scale) must be greater than or equal to 0
1418

1519
Warning: bcpowmod(): Non-zero scale in exponent in %s on line %d
1620
string(3) "0.0"

0 commit comments

Comments
 (0)