Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions ext/gmp/gmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment shouldn't be deleted (?)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TODO is resolved by the new check right below — mpz_fits_ulong_p(gmpnum) is exactly what it was asking for. Keeping the comment would misleadingly suggest the
work is still pending. But wiating fairly Gina's opinion on it first :)

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));
Expand Down
25 changes: 25 additions & 0 deletions ext/gmp/tests/gmp_fact_overflow.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
--TEST--
gmp_fact() rejects values larger than unsigned long
--EXTENSIONS--
gmp
--FILE--
<?php

try {
var_dump(gmp_fact(gmp_pow(2, 100)));
} catch (\ValueError $e) {
echo $e->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
Loading