Skip to content

Commit b1fbdd8

Browse files
committed
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3: Fix GH-16411: gmp_export() can cause overflow
2 parents 8aa3260 + ea6f78e commit b1fbdd8

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ PHP NEWS
4343
- GMP:
4444
. Fixed floating point exception bug with gmp_pow when using
4545
large exposant values. (David Carlier).
46+
. Fixed bug GH-16411 (gmp_export() can cause overflow). (cmb)
4647

4748
- MBstring:
4849
. Fixed bug GH-16361 (mb_substr overflow on start/length arguments).

ext/gmp/gmp.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,8 +1012,14 @@ ZEND_FUNCTION(gmp_export)
10121012
if (mpz_sgn(gmpnumber) == 0) {
10131013
RETVAL_EMPTY_STRING();
10141014
} else {
1015-
size_t bits_per_word = size * 8;
1016-
size_t count = (mpz_sizeinbase(gmpnumber, 2) + bits_per_word - 1) / bits_per_word;
1015+
ZEND_ASSERT(size > 0);
1016+
size_t size_in_base_2 = mpz_sizeinbase(gmpnumber, 2);
1017+
if (size > ZEND_LONG_MAX / 4 || size_in_base_2 > SIZE_MAX - (size_t) size * 8 + 1) {
1018+
zend_argument_value_error(2, "is too large for argument #1 ($num)");
1019+
RETURN_THROWS();
1020+
}
1021+
size_t bits_per_word = (size_t) size * 8;
1022+
size_t count = (size_in_base_2 + bits_per_word - 1) / bits_per_word;
10171023

10181024
zend_string *out_string = zend_string_safe_alloc(count, size, 0, 0);
10191025
mpz_export(ZSTR_VAL(out_string), NULL, order, size, endian, 0, gmpnumber);

ext/gmp/tests/gh16411.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
GH-16411 (gmp_export() can cause overflow)
3+
--EXTENSIONS--
4+
gmp
5+
--FILE--
6+
<?php
7+
gmp_export("-9223372036854775808", PHP_INT_MAX, PHP_INT_MIN);
8+
?>
9+
--EXPECTF--
10+
Fatal error: Uncaught ValueError: gmp_export(): Argument #2 ($word_size) is too large for argument #1 ($num) in %s:%d
11+
%A

0 commit comments

Comments
 (0)