conv: Fix overflow hanndling in readIntegral
This commit is contained in:
parent
99e06e0d04
commit
1b203507f6
@ -282,8 +282,8 @@ final class ConvException : Exception
|
|||||||
*
|
*
|
||||||
* The function doesn't handle the sign (+ or -) or number prefixes (like 0x).
|
* The function doesn't handle the sign (+ or -) or number prefixes (like 0x).
|
||||||
*/
|
*/
|
||||||
package T readIntegral(T, R)(ref R range, ubyte base = 10)
|
package T readIntegral(T, R)(ref R range, const ubyte base = 10)
|
||||||
if (isForwardRange!R
|
if (isInputRange!R
|
||||||
&& isSomeChar!(ElementType!R)
|
&& isSomeChar!(ElementType!R)
|
||||||
&& isIntegral!T
|
&& isIntegral!T
|
||||||
&& isUnsigned!T)
|
&& isUnsigned!T)
|
||||||
@ -301,9 +301,9 @@ do
|
|||||||
}
|
}
|
||||||
|
|
||||||
T n;
|
T n;
|
||||||
while (n <= boundary)
|
|
||||||
{
|
|
||||||
int digit;
|
int digit;
|
||||||
|
do
|
||||||
|
{
|
||||||
if (range.front >= 'a')
|
if (range.front >= 'a')
|
||||||
{
|
{
|
||||||
digit = range.front - 'W';
|
digit = range.front - 'W';
|
||||||
@ -332,17 +332,30 @@ do
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (range.length > 1)
|
while (n < boundary);
|
||||||
|
|
||||||
|
if (range.front >= 'a')
|
||||||
|
{
|
||||||
|
digit = range.front - 'W';
|
||||||
|
}
|
||||||
|
else if (range.front >= 'A')
|
||||||
|
{
|
||||||
|
digit = range.front - '7';
|
||||||
|
}
|
||||||
|
else if (range.front >= '0')
|
||||||
|
{
|
||||||
|
digit = range.front - '0';
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int digit = range.front - '0';
|
|
||||||
if (n > cast(T) ((T.max - digit) / base))
|
if (n > cast(T) ((T.max - digit) / base))
|
||||||
{
|
{
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
n = cast(T) (n * base + digit);
|
n = cast(T) (n * base + digit);
|
||||||
|
range.popFront();
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@ -410,6 +423,14 @@ do
|
|||||||
assert(number.empty);
|
assert(number.empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handles small overflows
|
||||||
|
@nogc nothrow pure @safe unittest
|
||||||
|
{
|
||||||
|
string number = "256";
|
||||||
|
assert(readIntegral!ubyte(number, 10) == 25);
|
||||||
|
assert(number.front == '6');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the source type $(D_PARAM From) and the target type $(D_PARAM To) are
|
* If the source type $(D_PARAM From) and the target type $(D_PARAM To) are
|
||||||
* equal, does nothing. If $(D_PARAM From) can be implicitly converted to
|
* equal, does nothing. If $(D_PARAM From) can be implicitly converted to
|
||||||
|
Loading…
Reference in New Issue
Block a user