@@ -621,7 +621,7 @@ impl<'a> StringReader<'a> {
621
621
let base = 10 ;
622
622
623
623
// find the integer representing the name
624
- self . scan_digits ( base) ;
624
+ self . scan_digits ( base, base ) ;
625
625
let encoded_name : u32 = self . with_str_from ( start_bpos, |s| {
626
626
num:: from_str_radix ( s, 10 ) . unwrap_or_else ( |_| {
627
627
panic ! ( "expected digits representing a name, got {:?}, {}, range [{:?},{:?}]" ,
@@ -639,7 +639,7 @@ impl<'a> StringReader<'a> {
639
639
640
640
// find the integer representing the ctxt
641
641
let start_bpos = self . last_pos ;
642
- self . scan_digits ( base) ;
642
+ self . scan_digits ( base, base ) ;
643
643
let encoded_ctxt : ast:: SyntaxContext = self . with_str_from ( start_bpos, |s| {
644
644
num:: from_str_radix ( s, 10 ) . unwrap_or_else ( |_| {
645
645
panic ! ( "expected digits representing a ctxt, got {:?}, {}" , s, whence) ;
@@ -653,16 +653,28 @@ impl<'a> StringReader<'a> {
653
653
ctxt : encoded_ctxt, }
654
654
}
655
655
656
- /// Scan through any digits (base `radix`) or underscores, and return how
657
- /// many digits there were.
658
- fn scan_digits ( & mut self , radix : u32 ) -> usize {
656
+ /// Scan through any digits (base `scan_radix`) or underscores,
657
+ /// and return how many digits there were.
658
+ ///
659
+ /// `real_radix` represents the true radix of the number we're
660
+ /// interested in, and errors will be emitted for any digits
661
+ /// between `real_radix` and `scan_radix`.
662
+ fn scan_digits ( & mut self , real_radix : u32 , scan_radix : u32 ) -> usize {
663
+ assert ! ( real_radix <= scan_radix) ;
659
664
let mut len = 0 ;
660
665
loop {
661
666
let c = self . curr ;
662
667
if c == Some ( '_' ) { debug ! ( "skipping a _" ) ; self . bump ( ) ; continue ; }
663
- match c. and_then ( |cc| cc. to_digit ( radix ) ) {
668
+ match c. and_then ( |cc| cc. to_digit ( scan_radix ) ) {
664
669
Some ( _) => {
665
670
debug ! ( "{:?} in scan_digits" , c) ;
671
+ // check that the hypothetical digit is actually
672
+ // in range for the true radix
673
+ if c. unwrap ( ) . to_digit ( real_radix) . is_none ( ) {
674
+ self . err_span_ ( self . last_pos , self . pos ,
675
+ & format ! ( "invalid digit for a base {} literal" ,
676
+ real_radix) ) ;
677
+ }
666
678
len += 1 ;
667
679
self . bump ( ) ;
668
680
}
@@ -681,19 +693,19 @@ impl<'a> StringReader<'a> {
681
693
682
694
if c == '0' {
683
695
match self . curr . unwrap_or ( '\0' ) {
684
- 'b' => { self . bump ( ) ; base = 2 ; num_digits = self . scan_digits ( 2 ) ; }
685
- 'o' => { self . bump ( ) ; base = 8 ; num_digits = self . scan_digits ( 8 ) ; }
686
- 'x' => { self . bump ( ) ; base = 16 ; num_digits = self . scan_digits ( 16 ) ; }
696
+ 'b' => { self . bump ( ) ; base = 2 ; num_digits = self . scan_digits ( 2 , 10 ) ; }
697
+ 'o' => { self . bump ( ) ; base = 8 ; num_digits = self . scan_digits ( 8 , 10 ) ; }
698
+ 'x' => { self . bump ( ) ; base = 16 ; num_digits = self . scan_digits ( 16 , 16 ) ; }
687
699
'0' ...'9' | '_' | '.' => {
688
- num_digits = self . scan_digits ( 10 ) + 1 ;
700
+ num_digits = self . scan_digits ( 10 , 10 ) + 1 ;
689
701
}
690
702
_ => {
691
703
// just a 0
692
704
return token:: Integer ( self . name_from ( start_bpos) ) ;
693
705
}
694
706
}
695
707
} else if c. is_digit ( 10 ) {
696
- num_digits = self . scan_digits ( 10 ) + 1 ;
708
+ num_digits = self . scan_digits ( 10 , 10 ) + 1 ;
697
709
} else {
698
710
num_digits = 0 ;
699
711
}
@@ -712,7 +724,7 @@ impl<'a> StringReader<'a> {
712
724
// with a number
713
725
self . bump ( ) ;
714
726
if self . curr . unwrap_or ( '\0' ) . is_digit ( 10 ) {
715
- self . scan_digits ( 10 ) ;
727
+ self . scan_digits ( 10 , 10 ) ;
716
728
self . scan_float_exponent ( ) ;
717
729
}
718
730
let last_pos = self . last_pos ;
@@ -935,7 +947,7 @@ impl<'a> StringReader<'a> {
935
947
if self . curr_is ( '-' ) || self . curr_is ( '+' ) {
936
948
self . bump ( ) ;
937
949
}
938
- if self . scan_digits ( 10 ) == 0 {
950
+ if self . scan_digits ( 10 , 10 ) == 0 {
939
951
self . err_span_ ( self . last_pos , self . pos , "expected at least one digit in exponent" )
940
952
}
941
953
}
0 commit comments