Skip to content

Commit ea6f78e

Browse files
committed
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: Fix GH-16411: gmp_export() can cause overflow
2 parents 900afb6 + ab595c0 commit ea6f78e

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
@@ -39,6 +39,7 @@ PHP NEWS
3939
- GMP:
4040
. Fixed floating point exception bug with gmp_pow when using
4141
large exposant values. (David Carlier).
42+
. Fixed bug GH-16411 (gmp_export() can cause overflow). (cmb)
4243

4344
- MBstring:
4445
. 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
@@ -1002,8 +1002,14 @@ ZEND_FUNCTION(gmp_export)
10021002
if (mpz_sgn(gmpnumber) == 0) {
10031003
RETVAL_EMPTY_STRING();
10041004
} else {
1005-
size_t bits_per_word = size * 8;
1006-
size_t count = (mpz_sizeinbase(gmpnumber, 2) + bits_per_word - 1) / bits_per_word;
1005+
ZEND_ASSERT(size > 0);
1006+
size_t size_in_base_2 = mpz_sizeinbase(gmpnumber, 2);
1007+
if (size > ZEND_LONG_MAX / 4 || size_in_base_2 > SIZE_MAX - (size_t) size * 8 + 1) {
1008+
zend_argument_value_error(2, "is too large for argument #1 ($num)");
1009+
RETURN_THROWS();
1010+
}
1011+
size_t bits_per_word = (size_t) size * 8;
1012+
size_t count = (size_in_base_2 + bits_per_word - 1) / bits_per_word;
10071013

10081014
zend_string *out_string = zend_string_safe_alloc(count, size, 0, 0);
10091015
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)