@@ -24,6 +24,7 @@ use mem::size_of;
24
24
use option:: Option :: { self , Some , None } ;
25
25
use result:: Result :: { self , Ok , Err } ;
26
26
use str:: { FromStr , StrExt } ;
27
+ use slice:: SliceExt ;
27
28
28
29
/// Provides intentionally-wrapped arithmetic on `T`.
29
30
///
@@ -1448,19 +1449,30 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32)
1448
1449
-> Result < T , ParseIntError > {
1449
1450
use self :: IntErrorKind :: * ;
1450
1451
use self :: ParseIntError as PIE ;
1452
+
1451
1453
assert ! ( radix >= 2 && radix <= 36 ,
1452
1454
"from_str_radix_int: must lie in the range `[2, 36]` - found {}" ,
1453
1455
radix) ;
1454
1456
1457
+ if src. is_empty ( ) {
1458
+ return Err ( PIE { kind : Empty } ) ;
1459
+ }
1460
+
1455
1461
let is_signed_ty = T :: from_u32 ( 0 ) > T :: min_value ( ) ;
1456
1462
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 => {
1460
1472
// The number is negative
1461
1473
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) {
1464
1476
Some ( x) => x,
1465
1477
None => return Err ( PIE { kind : InvalidDigit } ) ,
1466
1478
} ;
@@ -1475,11 +1487,14 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32)
1475
1487
}
1476
1488
Ok ( result)
1477
1489
} ,
1478
- Some ( ( _ , _ ) ) => {
1490
+ ( c , digits ) => {
1479
1491
// 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) {
1483
1498
Some ( x) => x,
1484
1499
None => return Err ( PIE { kind : InvalidDigit } ) ,
1485
1500
} ;
@@ -1493,8 +1508,7 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32)
1493
1508
} ;
1494
1509
}
1495
1510
Ok ( result)
1496
- } ,
1497
- None => Err ( ParseIntError { kind : Empty } ) ,
1511
+ }
1498
1512
}
1499
1513
}
1500
1514
0 commit comments