@@ -621,7 +621,7 @@ impl<'a> StringReader<'a> {
621621        let  base = 10 ; 
622622
623623        // find the integer representing the name 
624-         self . scan_digits ( base) ; 
624+         self . scan_digits ( base,  base ) ; 
625625        let  encoded_name :  u32  = self . with_str_from ( start_bpos,  |s| { 
626626            num:: from_str_radix ( s,  10 ) . unwrap_or_else ( |_| { 
627627                panic ! ( "expected digits representing a name, got {:?}, {}, range [{:?},{:?}]" , 
@@ -639,7 +639,7 @@ impl<'a> StringReader<'a> {
639639
640640        // find the integer representing the ctxt 
641641        let  start_bpos = self . last_pos ; 
642-         self . scan_digits ( base) ; 
642+         self . scan_digits ( base,  base ) ; 
643643        let  encoded_ctxt :  ast:: SyntaxContext  = self . with_str_from ( start_bpos,  |s| { 
644644            num:: from_str_radix ( s,  10 ) . unwrap_or_else ( |_| { 
645645                panic ! ( "expected digits representing a ctxt, got {:?}, {}" ,  s,  whence) ; 
@@ -653,16 +653,28 @@ impl<'a> StringReader<'a> {
653653                     ctxt :  encoded_ctxt,  } 
654654    } 
655655
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) ; 
659664        let  mut  len = 0 ; 
660665        loop  { 
661666            let  c = self . curr ; 
662667            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 ) )  { 
664669                Some ( _)  => { 
665670                    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+                     } 
666678                    len += 1 ; 
667679                    self . bump ( ) ; 
668680                } 
@@ -681,19 +693,19 @@ impl<'a> StringReader<'a> {
681693
682694        if  c == '0'  { 
683695            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 ) ;  } 
687699                '0' ...'9'  | '_'  | '.'  => { 
688-                     num_digits = self . scan_digits ( 10 )  + 1 ; 
700+                     num_digits = self . scan_digits ( 10 ,   10 )  + 1 ; 
689701                } 
690702                _ => { 
691703                    // just a 0 
692704                    return  token:: Integer ( self . name_from ( start_bpos) ) ; 
693705                } 
694706            } 
695707        }  else  if  c. is_digit ( 10 )  { 
696-             num_digits = self . scan_digits ( 10 )  + 1 ; 
708+             num_digits = self . scan_digits ( 10 ,   10 )  + 1 ; 
697709        }  else  { 
698710            num_digits = 0 ; 
699711        } 
@@ -712,7 +724,7 @@ impl<'a> StringReader<'a> {
712724            // with a number 
713725            self . bump ( ) ; 
714726            if  self . curr . unwrap_or ( '\0' ) . is_digit ( 10 )  { 
715-                 self . scan_digits ( 10 ) ; 
727+                 self . scan_digits ( 10 ,   10 ) ; 
716728                self . scan_float_exponent ( ) ; 
717729            } 
718730            let  last_pos = self . last_pos ; 
@@ -935,7 +947,7 @@ impl<'a> StringReader<'a> {
935947            if  self . curr_is ( '-' )  || self . curr_is ( '+' )  { 
936948                self . bump ( ) ; 
937949            } 
938-             if  self . scan_digits ( 10 )  == 0  { 
950+             if  self . scan_digits ( 10 ,   10 )  == 0  { 
939951                self . err_span_ ( self . last_pos ,  self . pos ,  "expected at least one digit in exponent" ) 
940952            } 
941953        } 
0 commit comments