From cfcf5cfde8a1d69b14c00c8e83c17d529e698729 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 21 Nov 2024 17:51:49 +0100 Subject: [PATCH] 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. --- NEWS | 4 ++++ ext/gmp/gmp.c | 6 +++++- ext/gmp/tests/gh16890.phpt | 11 +++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 ext/gmp/tests/gh16890.phpt diff --git a/NEWS b/NEWS index 30d156a3540..cf40cc748cc 100644 --- a/NEWS +++ b/NEWS @@ -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) diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 994e95409ad..dfb762e717c 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -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)); diff --git a/ext/gmp/tests/gh16890.phpt b/ext/gmp/tests/gh16890.phpt new file mode 100644 index 00000000000..08fc0605596 --- /dev/null +++ b/ext/gmp/tests/gh16890.phpt @@ -0,0 +1,11 @@ +--TEST-- +GH-16890 (array_sum() with GMP can loose precision (LLP64)) +--EXTENSIONS-- +gmp +--FILE-- + +--EXPECT-- +bool(true)