From 79c7da0e42100ad7aea009788042d6fc1d724f01 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 21 Nov 2024 17:30:27 +0100 Subject: [PATCH 1/2] 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. --- ext/gmp/gmp.c | 2 +- ext/gmp/tests/gh16890.phpt | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 ext/gmp/tests/gh16890.phpt diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 994e95409ad86..e9fd10d8087d7 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -292,7 +292,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 0000000000000..08fc060559625 --- /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) From e4c4cf5a0d86d8b6a73c11a5a0d6b08a3e9d2a5d Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 21 Nov 2024 17:51:49 +0100 Subject: [PATCH 2/2] Fix building against libgmp libgmp does not define `mpz_fits_si_p()`, so we use `mpz_fits_slong_p()` there. --- ext/gmp/gmp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index e9fd10d8087d7..dfb762e717c55 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