Skip to content

Commit caf5321

Browse files
committed
fix for issue #7588, overflow now handled correctly
1 parent 116c034 commit caf5321

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

src/libstd/num/strconv.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -552,8 +552,18 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+
552552
// Detect overflow by comparing to last value, except
553553
// if we've not seen any non-zero digits.
554554
if last_accum != _0 {
555-
if accum_positive && accum <= last_accum { return None; }
556-
if !accum_positive && accum >= last_accum { return None; }
555+
if accum_positive && accum <= last_accum { return NumStrConv::inf(); }
556+
if !accum_positive && accum >= last_accum { return NumStrConv::neg_inf(); }
557+
558+
// Detect overflow by reversing the shift-and-add proccess
559+
if accum_positive &&
560+
(last_accum != ((accum - cast(digit as int))/radix_gen.clone())) {
561+
return NumStrConv::inf();
562+
}
563+
if !accum_positive &&
564+
(last_accum != ((accum + cast(digit as int))/radix_gen.clone())) {
565+
return NumStrConv::neg_inf();
566+
}
557567
}
558568
last_accum = accum.clone();
559569
}
@@ -597,8 +607,8 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+
597607
}
598608

599609
// Detect overflow by comparing to last value
600-
if accum_positive && accum < last_accum { return None; }
601-
if !accum_positive && accum > last_accum { return None; }
610+
if accum_positive && accum < last_accum { return NumStrConv::inf(); }
611+
if !accum_positive && accum > last_accum { return NumStrConv::neg_inf(); }
602612
last_accum = accum.clone();
603613
}
604614
None => match c {
@@ -702,6 +712,23 @@ mod test {
702712
ExpNone, false, false);
703713
assert_eq!(n, None);
704714
}
715+
716+
#[test]
717+
fn from_str_issue7588() {
718+
let u : Option<u8> = from_str_common("1000", 10, false, false, false,
719+
ExpNone, false, false);
720+
assert_eq!(u, None);
721+
let s : Option<i16> = from_str_common("80000", 10, false, false, false,
722+
ExpNone, false, false);
723+
assert_eq!(s, None);
724+
let f : Option<f32> = from_str_common(
725+
"10000000000000000000000000000000000000000", 10, false, false, false,
726+
ExpNone, false, false);
727+
assert_eq!(f, NumStrConv::inf())
728+
let fe : Option<f32> = from_str_common("1e40", 10, false, false, false,
729+
ExpDec, false, false);
730+
assert_eq!(fe, NumStrConv::inf())
731+
}
705732
}
706733

707734
#[cfg(test)]

0 commit comments

Comments
 (0)