@@ -24,6 +24,7 @@ use mem::size_of;
2424use option:: Option :: { self , Some , None } ;
2525use result:: Result :: { self , Ok , Err } ;
2626use str:: { FromStr , StrExt } ;
27+ use slice:: SliceExt ;
2728
2829/// Provides intentionally-wrapped arithmetic on `T`.
2930///
@@ -1448,19 +1449,30 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32)
14481449 -> Result < T , ParseIntError > {
14491450 use self :: IntErrorKind :: * ;
14501451 use self :: ParseIntError as PIE ;
1452+
14511453 assert ! ( radix >= 2 && radix <= 36 ,
14521454 "from_str_radix_int: must lie in the range `[2, 36]` - found {}" ,
14531455 radix) ;
14541456
1457+ if src. is_empty ( ) {
1458+ return Err ( PIE { kind : Empty } ) ;
1459+ }
1460+
14551461 let is_signed_ty = T :: from_u32 ( 0 ) > T :: min_value ( ) ;
14561462
1457- match src. slice_shift_char ( ) {
1458- Some ( ( '-' , "" ) ) => Err ( PIE { kind : Empty } ) ,
1459- Some ( ( '-' , src) ) if is_signed_ty => {
1463+ // all valid digits are ascii, so we will just iterate over the utf8 bytes
1464+ // and cast them to chars. .to_digit() will safely return None for anything
1465+ // other than a valid ascii digit for a the given radix, including the first-byte
1466+ // of multi-byte sequences
1467+ let src = src. as_bytes ( ) ;
1468+
1469+ match ( src[ 0 ] , & src[ 1 ..] ) {
1470+ ( b'-' , digits) if digits. is_empty ( ) => Err ( PIE { kind : Empty } ) ,
1471+ ( b'-' , digits) if is_signed_ty => {
14601472 // The number is negative
14611473 let mut result = T :: from_u32 ( 0 ) ;
1462- for c in src . chars ( ) {
1463- let x = match c . to_digit ( radix) {
1474+ for & c in digits {
1475+ let x = match ( c as char ) . to_digit ( radix) {
14641476 Some ( x) => x,
14651477 None => return Err ( PIE { kind : InvalidDigit } ) ,
14661478 } ;
@@ -1475,11 +1487,14 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32)
14751487 }
14761488 Ok ( result)
14771489 } ,
1478- Some ( ( _ , _ ) ) => {
1490+ ( c , digits ) => {
14791491 // The number is signed
1480- let mut result = T :: from_u32 ( 0 ) ;
1481- for c in src. chars ( ) {
1482- let x = match c. to_digit ( radix) {
1492+ let mut result = match ( c as char ) . to_digit ( radix) {
1493+ Some ( x) => T :: from_u32 ( x) ,
1494+ None => return Err ( PIE { kind : InvalidDigit } ) ,
1495+ } ;
1496+ for & c in digits {
1497+ let x = match ( c as char ) . to_digit ( radix) {
14831498 Some ( x) => x,
14841499 None => return Err ( PIE { kind : InvalidDigit } ) ,
14851500 } ;
@@ -1493,8 +1508,7 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32)
14931508 } ;
14941509 }
14951510 Ok ( result)
1496- } ,
1497- None => Err ( ParseIntError { kind : Empty } ) ,
1511+ }
14981512 }
14991513}
15001514
0 commit comments