summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2018-07-17 16:03:05 +0200
committerEugen Wissner <belka@caraus.de>2018-07-17 16:03:05 +0200
commit1b203507f6d7b4ab167f6e575fd7c206bba24d1c (patch)
tree15b1eb5fd20907fdcfb1dbad04548da3a2e38b4a
parent99e06e0d049b67eff31e3656d105b1273bc7f887 (diff)
downloadtanya-1b203507f6d7b4ab167f6e575fd7c206bba24d1c.tar.gz
conv: Fix overflow hanndling in readIntegral
-rw-r--r--source/tanya/conv.d35
1 files changed, 28 insertions, 7 deletions
diff --git a/source/tanya/conv.d b/source/tanya/conv.d
index 61935f6..a244841 100644
--- a/source/tanya/conv.d
+++ b/source/tanya/conv.d
@@ -282,8 +282,8 @@ final class ConvException : Exception
*
* The function doesn't handle the sign (+ or -) or number prefixes (like 0x).
*/
-package T readIntegral(T, R)(ref R range, ubyte base = 10)
-if (isForwardRange!R
+package T readIntegral(T, R)(ref R range, const ubyte base = 10)
+if (isInputRange!R
&& isSomeChar!(ElementType!R)
&& isIntegral!T
&& isUnsigned!T)
@@ -301,9 +301,9 @@ do
}
T n;
- while (n <= boundary)
+ int digit;
+ do
{
- int digit;
if (range.front >= 'a')
{
digit = range.front - 'W';
@@ -332,17 +332,30 @@ do
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;
}
-
- int digit = range.front - '0';
if (n > cast(T) ((T.max - digit) / base))
{
return n;
}
n = cast(T) (n * base + digit);
+ range.popFront();
return n;
}
@@ -410,6 +423,14 @@ do
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
* equal, does nothing. If $(D_PARAM From) can be implicitly converted to