Skip to content

Commit

Permalink
Fixed a bug where size_t underflows (#16696)
Browse files Browse the repository at this point in the history
fixes #16262
closes #16696
  • Loading branch information
SakiTakamachi committed Nov 4, 2024
1 parent 2fe7719 commit fd1dff9
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 1 deletion.
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ PHP NEWS
- BcMath:
. Fixed bug GH-16265 (Added early return case when result is 0)
(Saki Takamachi).
. Fixed bug GH-16262 (Fixed a bug where size_t underflows) (Saki Takamachi).

- Core:
. Fixed bug GH-16574 (Incorrect error "undefined method" messages).
Expand Down
2 changes: 1 addition & 1 deletion ext/bcmath/libbcmath/src/div.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale)
numerator_bottom_extension -= scale_diff;
} else {
numerator_bottom_extension = 0;
numeratorend -= scale_diff - numerator_bottom_extension;
numeratorend -= scale_diff > numerator_top_extension ? scale_diff - numerator_top_extension : 0;
}
} else {
numerator_bottom_extension += scale - numerator_scale;
Expand Down
158 changes: 158 additions & 0 deletions ext/bcmath/tests/gh16262.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
--TEST--
GH-16262 Stack buffer overflow in ext/bcmath/libbcmath/src/div.c:459
--EXTENSIONS--
bcmath
--INI--
bcmath.scale=0
--FILE--
<?php
$scales = [
null,
0,
1,
2,
3,
4,
5,
];
foreach ($scales as $scale) {
echo '========== scale: ', $scale ?? 'null', " ==========\n";
echo "1 / 1000:\n";
var_dump(
bcdiv('1', '1000', $scale),
(new BcMath\Number('1'))->div('1000', $scale),
);
echo "1 / 2000:\n";
var_dump(
bcdiv('1', '2000', $scale),
(new BcMath\Number('1'))->div('2000', $scale),
);
echo "\n";
}
?>
--EXPECT--
========== scale: null ==========
1 / 1000:
string(1) "0"
object(BcMath\Number)#2 (2) {
["value"]=>
string(5) "0.001"
["scale"]=>
int(3)
}
1 / 2000:
string(1) "0"
object(BcMath\Number)#1 (2) {
["value"]=>
string(6) "0.0005"
["scale"]=>
int(4)
}

========== scale: 0 ==========
1 / 1000:
string(1) "0"
object(BcMath\Number)#2 (2) {
["value"]=>
string(1) "0"
["scale"]=>
int(0)
}
1 / 2000:
string(1) "0"
object(BcMath\Number)#1 (2) {
["value"]=>
string(1) "0"
["scale"]=>
int(0)
}

========== scale: 1 ==========
1 / 1000:
string(3) "0.0"
object(BcMath\Number)#2 (2) {
["value"]=>
string(3) "0.0"
["scale"]=>
int(1)
}
1 / 2000:
string(3) "0.0"
object(BcMath\Number)#1 (2) {
["value"]=>
string(3) "0.0"
["scale"]=>
int(1)
}

========== scale: 2 ==========
1 / 1000:
string(4) "0.00"
object(BcMath\Number)#2 (2) {
["value"]=>
string(4) "0.00"
["scale"]=>
int(2)
}
1 / 2000:
string(4) "0.00"
object(BcMath\Number)#1 (2) {
["value"]=>
string(4) "0.00"
["scale"]=>
int(2)
}

========== scale: 3 ==========
1 / 1000:
string(5) "0.001"
object(BcMath\Number)#2 (2) {
["value"]=>
string(5) "0.001"
["scale"]=>
int(3)
}
1 / 2000:
string(5) "0.000"
object(BcMath\Number)#1 (2) {
["value"]=>
string(5) "0.000"
["scale"]=>
int(3)
}

========== scale: 4 ==========
1 / 1000:
string(6) "0.0010"
object(BcMath\Number)#2 (2) {
["value"]=>
string(6) "0.0010"
["scale"]=>
int(4)
}
1 / 2000:
string(6) "0.0005"
object(BcMath\Number)#1 (2) {
["value"]=>
string(6) "0.0005"
["scale"]=>
int(4)
}

========== scale: 5 ==========
1 / 1000:
string(7) "0.00100"
object(BcMath\Number)#2 (2) {
["value"]=>
string(7) "0.00100"
["scale"]=>
int(5)
}
1 / 2000:
string(7) "0.00050"
object(BcMath\Number)#1 (2) {
["value"]=>
string(7) "0.00050"
["scale"]=>
int(5)
}

0 comments on commit fd1dff9

Please sign in to comment.