From caf5321eb45db8ba64d3f9f4b9e16febfeb46a4c Mon Sep 17 00:00:00 2001 From: Aaron Laursen Date: Fri, 30 Aug 2013 17:45:20 -0500 Subject: [PATCH] fix for issue #7588, overflow now handled correctly --- src/libstd/num/strconv.rs | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index 6fba8a6dd13..fe93f20e109 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -552,8 +552,18 @@ pub fn from_str_bytes_common+ // Detect overflow by comparing to last value, except // if we've not seen any non-zero digits. if last_accum != _0 { - if accum_positive && accum <= last_accum { return None; } - if !accum_positive && accum >= last_accum { return None; } + if accum_positive && accum <= last_accum { return NumStrConv::inf(); } + if !accum_positive && accum >= last_accum { return NumStrConv::neg_inf(); } + + // Detect overflow by reversing the shift-and-add proccess + if accum_positive && + (last_accum != ((accum - cast(digit as int))/radix_gen.clone())) { + return NumStrConv::inf(); + } + if !accum_positive && + (last_accum != ((accum + cast(digit as int))/radix_gen.clone())) { + return NumStrConv::neg_inf(); + } } last_accum = accum.clone(); } @@ -597,8 +607,8 @@ pub fn from_str_bytes_common+ } // Detect overflow by comparing to last value - if accum_positive && accum < last_accum { return None; } - if !accum_positive && accum > last_accum { return None; } + if accum_positive && accum < last_accum { return NumStrConv::inf(); } + if !accum_positive && accum > last_accum { return NumStrConv::neg_inf(); } last_accum = accum.clone(); } None => match c { @@ -702,6 +712,23 @@ mod test { ExpNone, false, false); assert_eq!(n, None); } + + #[test] + fn from_str_issue7588() { + let u : Option = from_str_common("1000", 10, false, false, false, + ExpNone, false, false); + assert_eq!(u, None); + let s : Option = from_str_common("80000", 10, false, false, false, + ExpNone, false, false); + assert_eq!(s, None); + let f : Option = from_str_common( + "10000000000000000000000000000000000000000", 10, false, false, false, + ExpNone, false, false); + assert_eq!(f, NumStrConv::inf()) + let fe : Option = from_str_common("1e40", 10, false, false, false, + ExpDec, false, false); + assert_eq!(fe, NumStrConv::inf()) + } } #[cfg(test)]