From 1956835a1e76d85e4e3017766e5cb43b6b7daee7 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 18 Apr 2026 07:17:48 +0100 Subject: [PATCH] ext/gmp: gmp_fact() reject values larger than unsigned long. --- ext/gmp/gmp.c | 6 ++++-- ext/gmp/tests/gmp_fact_overflow.phpt | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 ext/gmp/tests/gmp_fact_overflow.phpt diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index cf6580e95e9b..a20974580904 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -1092,8 +1092,10 @@ ZEND_FUNCTION(gmp_fact) RETURN_THROWS(); } - // TODO: Check that we don't an int that is larger than an unsigned long? - // Could use mpz_fits_slong_p() if we revert to using mpz_get_si() + if (!mpz_fits_ulong_p(gmpnum)) { + zend_argument_value_error(1, "must be between 0 and %lu", ULONG_MAX); + RETURN_THROWS(); + } INIT_GMP_RETVAL(gmpnum_result); mpz_fac_ui(gmpnum_result, mpz_get_ui(gmpnum)); diff --git a/ext/gmp/tests/gmp_fact_overflow.phpt b/ext/gmp/tests/gmp_fact_overflow.phpt new file mode 100644 index 000000000000..2d22005818c5 --- /dev/null +++ b/ext/gmp/tests/gmp_fact_overflow.phpt @@ -0,0 +1,25 @@ +--TEST-- +gmp_fact() rejects values larger than unsigned long +--EXTENSIONS-- +gmp +--FILE-- +getMessage() . \PHP_EOL; +} + +try { + var_dump(gmp_fact(gmp_init("18446744073709551616"))); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo "Done\n"; +?> +--EXPECTF-- +gmp_fact(): Argument #1 ($num) must be between 0 and %d +gmp_fact(): Argument #1 ($num) must be between 0 and %d +Done