diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index cf6580e95e9b8..a209745809044 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 0000000000000..2d22005818c50 --- /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