Fix GH-16890: array_sum() with GMP can loose precision (LLP64)

We must use `mpz_fits_si_p()` instead of `mpz_fits_slong_p()` since the
latter is not suitable for LLP64 data models.

libgmp, however, does not define `mpz_fits_si_p()` (which is an mpir
addition), so we use `mpz_fits_slong_p()` there which should be fine.

Closes GH-16891.
This commit is contained in:
Christoph M. Becker 2024-11-21 17:51:49 +01:00
parent ac57b81c7c
commit cfcf5cfde8
No known key found for this signature in database
GPG key ID: D66C9593118BCCB6
3 changed files with 20 additions and 1 deletions

4
NEWS
View file

@ -30,6 +30,10 @@ PHP NEWS
- GD:
. Fixed GH-16776 (imagecreatefromstring overflow). (David Carlier)
- GMP:
. Fixed bug GH-16890 (array_sum() with GMP can loose precision (LLP64)).
(cmb)
- Hash:
. Fixed GH-16711: Segfault in mhash(). (Girgias)

View file

@ -32,6 +32,10 @@
/* Needed for gmp_random() */
#include "ext/random/php_random.h"
#ifndef mpz_fits_si_p
# define mpz_fits_si_p mpz_fits_slong_p
#endif
#define GMP_ROUND_ZERO 0
#define GMP_ROUND_PLUSINF 1
#define GMP_ROUND_MINUSINF 2
@ -292,7 +296,7 @@ static zend_result gmp_cast_object(zend_object *readobj, zval *writeobj, int typ
return SUCCESS;
case _IS_NUMBER:
gmpnum = GET_GMP_OBJECT_FROM_OBJ(readobj)->num;
if (mpz_fits_slong_p(gmpnum)) {
if (mpz_fits_si_p(gmpnum)) {
ZVAL_LONG(writeobj, mpz_get_si(gmpnum));
} else {
ZVAL_DOUBLE(writeobj, mpz_get_d(gmpnum));

View file

@ -0,0 +1,11 @@
--TEST--
GH-16890 (array_sum() with GMP can loose precision (LLP64))
--EXTENSIONS--
gmp
--FILE--
<?php
$large_int_string = (string) (PHP_INT_MAX - 1);
var_dump(array_sum([new GMP($large_int_string), 1]) === PHP_INT_MAX);
?>
--EXPECT--
bool(true)