Fix GH-16878: Prevent overflow in gmp_fact() for large GMP inputs (ext/gmp) #20900
+63
−2
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Fixes #16878
Problem
gmp_fact()was crashing with "GNU MP: Cannot allocate memory" abort when passed extremely large values (e.g., 2^50+1). The function callsmpz_fac_ui()which:unsigned longparameterBefore this fix:
Reference: https://3v4l.org/X428B
Solution
Added proper input validation in
gmp_fact()before callingmpz_fac_ui():unsigned long: Usesmpz_fits_ulong_p()to ensure the GMP number can be safely convertedValueError: Returns a clear error message instead of crashingAfter this fix:
Changes Made
Modified:
ext/gmp/gmp.c: Added validation logic replacing the TODO commentmpz_fits_ulong_p(gmpnum)to prevent truncation/overflowmpz_cmp_ui(gmpnum, 100000) > 0to prevent excessive resource usageAdded:
ext/gmp/tests/gh16878.phpt: Test case covering:Why the 100,000 cap?
Factorial growth is astronomical:
100!= 158 digits100,000!= ~456,574 digitsError Behavior
ValueError: must be greater than or equal to 0ULONG_MAX(GMP input)ValueError: is too largeValueError: is too large