mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
fp_uscale.c: clamp parser underflow guard to POW10_MIN
mrb_read_float's underflow short-circuit used `final_p < -342 - nd`, which for nd > 1 can be below POW10_MIN (-343). That let parse_decimal call prescale() with a final_p below POW10_MIN, causing an out-of-bounds read of pow10_tab. Tighten the guard to `final_p < POW10_MIN`; values below that threshold cannot be represented as a non-zero double for any mantissa within the parser's 19-digit cap. Reported by OSS-Fuzz (testcase 6097379597287424). Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -1497,7 +1497,7 @@ mrb_read_float(const char *str, char **endp, double *fp)
|
||||
else if (final_p > 308) {
|
||||
res = HUGE_VAL;
|
||||
}
|
||||
else if (final_p < -342 - nd) {
|
||||
else if (final_p < POW10_MIN) {
|
||||
res = 0.0;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -293,4 +293,13 @@ assert('Float#abs') do
|
||||
assert_equal(0.0, f.abs)
|
||||
end
|
||||
|
||||
assert('Float literal underflow') do
|
||||
# Regression: float literals with exponents below POW10_MIN used to
|
||||
# index pow10_tab out of bounds in mrb_read_float. They must round
|
||||
# cleanly to 0.0.
|
||||
assert_equal 0.0, 1.0e-400
|
||||
assert_equal 0.0, 9.99e-344
|
||||
assert_equal(-0.0, -92170141183460469231731687303715884105729e-383)
|
||||
end
|
||||
|
||||
end # const_defined?(:Float)
|
||||
|
||||
Reference in New Issue
Block a user