@@ -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