Skip to content

Commit

Permalink
fix for issue #7588, overflow now handled correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronlaursen committed Sep 6, 2013
1 parent 116c034 commit caf5321
Showing 1 changed file with 31 additions and 4 deletions.
35 changes: 31 additions & 4 deletions src/libstd/num/strconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,8 +552,18 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+
// 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();
}
Expand Down Expand Up @@ -597,8 +607,8 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+
}

// 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 {
Expand Down Expand Up @@ -702,6 +712,23 @@ mod test {
ExpNone, false, false);
assert_eq!(n, None);
}

#[test]
fn from_str_issue7588() {
let u : Option<u8> = from_str_common("1000", 10, false, false, false,
ExpNone, false, false);
assert_eq!(u, None);
let s : Option<i16> = from_str_common("80000", 10, false, false, false,
ExpNone, false, false);
assert_eq!(s, None);
let f : Option<f32> = from_str_common(
"10000000000000000000000000000000000000000", 10, false, false, false,
ExpNone, false, false);
assert_eq!(f, NumStrConv::inf())
let fe : Option<f32> = from_str_common("1e40", 10, false, false, false,
ExpDec, false, false);
assert_eq!(fe, NumStrConv::inf())
}
}

#[cfg(test)]
Expand Down

5 comments on commit caf5321

@bors
Copy link
Contributor

@bors bors commented on caf5321 Sep 7, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on caf5321 Sep 7, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging aaronlaursen/rust/master = caf5321 into auto

@bors
Copy link
Contributor

@bors bors commented on caf5321 Sep 7, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aaronlaursen/rust/master = caf5321 merged ok, testing candidate = 25f3b29

@bors
Copy link
Contributor

@bors bors commented on caf5321 Sep 7, 2013

@bors
Copy link
Contributor

@bors bors commented on caf5321 Sep 7, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 25f3b29

Please sign in to comment.