Fix Issue 22637 - std.conv to!double and parse!double dont throw on under/overflow

This happened because `parse` enforced on real.
And provided number actually fits real.
Changed to enforce on `Target` type instead
This commit is contained in:
Grim Maple 2022-07-08 21:28:11 +03:00
parent 553d8cb56c
commit 1c3903c2e6

View file

@ -3419,17 +3419,20 @@ if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum
}
}
Target result = cast(Target) (sign ? -ldval : ldval);
// if overflow occurred
enforce(ldval != real.infinity, new ConvException("Range error"));
import std.math : isFinite;
enforce(isFinite(result), new ConvException("Range error"));
advanceSource();
static if (doCount)
{
return tuple!("data", "count")(cast (Target) (sign ? -ldval : ldval), count);
return tuple!("data", "count")(result, count);
}
else
{
return cast (Target) (sign ? -ldval : ldval);
return result;
}
}
@ -3785,6 +3788,16 @@ if (isInputRange!Source && isSomeChar!(ElementType!Source) && !is(Source == enum
assertThrown!ConvException(parse!double(s));
}
@safe unittest // https://issues.dlang.org/show_bug.cgi?id=22637
{
import std.exception : assertThrown, assertNotThrown;
auto src = "9991232549867999698999493543521458974414359998784641646846435132132543645435456345634541999999999999999"
~ "9999999943321231321311999231345312413646846354354354399999934153465464654646464654134135354199999999996515734999"
~ "9999999320135273486741354354731567431324134999999999999999999999999999999999999999999999135411.9";
assertThrown!ConvException(parse!double(src));
static if (real.max_10_exp > 310) assertNotThrown!ConvException(parse!real(src));
}
/**
Parsing one character off a range returns the first element and calls `popFront`.