From efe0d1722b0d873afc9b177edfb052c0fda4181e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20Bo=C3=9Fung?= Date: Sun, 20 Jul 2014 00:09:47 +0200 Subject: [PATCH 1/3] fix issue 13163 - std.conv.parse misses overflow when it doesn't result in a smaller value --- std/conv.d | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/std/conv.d b/std/conv.d index 3a91e85b72a..551dc4ba169 100644 --- a/std/conv.d +++ b/std/conv.d @@ -21,7 +21,7 @@ WIKI = Phobos/StdConv */ module std.conv; -import core.stdc.string; +import core.checkedint, core.stdc.string; import std.algorithm, std.array, std.ascii, std.exception, std.range, std.string, std.traits, std.typecons, std.typetuple, std.uni, std.utf; @@ -2188,10 +2188,16 @@ body c -= 'a'-10-'0'; } } - auto blah = cast(Target) (v * radix + c - '0'); - if (blah < v) + + bool overflow = false; + static if (isSigned!Target) + auto nextv = v.muls(radix, overflow).adds(c - '0', overflow); + else + auto nextv = v.mulu(radix, overflow).addu(c - '0', overflow); + if (overflow || nextv > Target.max) goto Loverflow; - v = blah; + v = cast(Target) nextv; + atStart = false; } if (atStart) @@ -2246,6 +2252,12 @@ Lerr: assert(r.front == '!'); } +@safe pure unittest // bugzilla 13163 +{ + foreach (s; ["fff", "123"]) + assertThrown!ConvOverflowException(s.parse!ubyte(16)); +} + Target parse(Target, Source)(ref Source s) if (isExactSomeString!Source && is(Target == enum)) From 2606fd5f41375fac474c50c4f8519dd24796b39b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20Bo=C3=9Fung?= Date: Fri, 25 Jul 2014 01:22:41 +0200 Subject: [PATCH 2/3] don't bother with signed types Everything is >= 0 all the time anyway. --- std/conv.d | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/std/conv.d b/std/conv.d index 551dc4ba169..6c43790ef97 100644 --- a/std/conv.d +++ b/std/conv.d @@ -2190,10 +2190,7 @@ body } bool overflow = false; - static if (isSigned!Target) - auto nextv = v.muls(radix, overflow).adds(c - '0', overflow); - else - auto nextv = v.mulu(radix, overflow).addu(c - '0', overflow); + auto nextv = v.mulu(radix, overflow).addu(c - '0', overflow); if (overflow || nextv > Target.max) goto Loverflow; v = cast(Target) nextv; From b4e31a5348b0fe5e5f0f04a8ab6fbc2e1011d6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20Bo=C3=9Fung?= Date: Fri, 25 Jul 2014 01:23:49 +0200 Subject: [PATCH 3/3] fix whitespace --- std/conv.d | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/std/conv.d b/std/conv.d index 6c43790ef97..2d68f6e54a5 100644 --- a/std/conv.d +++ b/std/conv.d @@ -2188,13 +2188,13 @@ body c -= 'a'-10-'0'; } } - + bool overflow = false; auto nextv = v.mulu(radix, overflow).addu(c - '0', overflow); if (overflow || nextv > Target.max) goto Loverflow; v = cast(Target) nextv; - + atStart = false; } if (atStart)