From 26908f17ed24e1da19a9856a8da4883d6808ae0a Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Sun, 29 Nov 2020 13:53:15 +0300 Subject: [PATCH] Fix crash on lexing octal escapes bigger than u8::MAX --- parser/src/lexer.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/parser/src/lexer.rs b/parser/src/lexer.rs index 955b4559e..064c35d95 100644 --- a/parser/src/lexer.rs +++ b/parser/src/lexer.rs @@ -447,7 +447,7 @@ where } } - fn parse_octet(&mut self, first: char) -> char { + fn parse_octet(&mut self, first: char) -> Result { let mut octet_content = String::new(); octet_content.push(first); while octet_content.len() < 3 { @@ -457,7 +457,13 @@ where break; } } - u8::from_str_radix(&octet_content, 8).unwrap() as char + match u32::from_str_radix(&octet_content, 8) { + Ok(result) => Ok(char::from_u32(result).unwrap()), + Err(error) => Err(LexicalError { + error: LexicalErrorType::OtherError(error.to_string()), + location: self.get_pos(), + }) + } } fn parse_unicode_name(&mut self) -> Result { @@ -549,7 +555,7 @@ where string_content.push('\t'); } Some('v') => string_content.push('\x0b'), - Some(o @ '0'..='7') => string_content.push(self.parse_octet(o)), + Some(o @ '0'..='7') => string_content.push(self.parse_octet(o)?), Some('x') => string_content.push(self.unicode_literal(2)?), Some('u') if !is_bytes => string_content.push(self.unicode_literal(4)?), Some('U') if !is_bytes => string_content.push(self.unicode_literal(8)?), @@ -1596,7 +1602,7 @@ mod tests { #[test] fn test_string() { - let source = r#""double" 'single' 'can\'t' "\\\"" '\t\r\n' '\g' r'raw\'' '\200\0a'"#; + let source = r#""double" 'single' 'can\'t' "\\\"" '\t\r\n' '\g' r'raw\'' '\420' '\200\0a'"#; let tokens = lex_source(source); assert_eq!( tokens, @@ -1629,6 +1635,10 @@ mod tests { value: String::from("raw\\'"), is_fstring: false, }, + Tok::String { + value: String::from("Đ"), + is_fstring: false, + }, Tok::String { value: String::from("\u{80}\u{0}a"), is_fstring: false,