From bad314e1cfbfc06579838ebfafd01cdbcb0a0a6e Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Thu, 9 Jan 2025 13:08:13 +0100 Subject: Prevent numeric literals from having spaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It has been found that having literals like "# 20" can potentially be troublesome and even introduce crashes. Hence, as it's done in other assemblers, disallow this kind of syntax. Signed-off-by: Miquel Sabaté Solà --- lib/xixanta/src/parser.rs | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'lib/xixanta/src') diff --git a/lib/xixanta/src/parser.rs b/lib/xixanta/src/parser.rs index c171624..7e72082 100644 --- a/lib/xixanta/src/parser.rs +++ b/lib/xixanta/src/parser.rs @@ -994,11 +994,22 @@ impl Parser { self.column = id.start; self.offset = 0; self.next(); - self.skip_whitespace(line); - // With this, just fetch the inner expression and return the literal - // node. + // Enforce that literal symbols and their values are not separated by + // random white space characters. Other assemblers (e.g. ca65) also take + // this stance, and through fuzzy testing I realized that not doing this + // could result in general bad behavior. let inner = line.get(self.offset..).unwrap_or(""); + if let Some(c) = inner.chars().nth(0) { + if c.is_whitespace() { + return Err(ParseError { + line: id.line, + message: "numeric literals cannot have white spaces".to_string(), + }); + } + } + + // Just fetch the inner expression and return the literal node. self.offset = 0; let left = self.parse_expression(inner)?; @@ -1200,7 +1211,7 @@ mod tests { #[test] fn parse_pound_literal() { - for line in vec!["#20", " #20 ", " #20 ; Comment", " label: # 20"].into_iter() { + for line in vec!["#20", " #20 ", " #20 ; Comment", " label: #20"].into_iter() { let mut parser = Parser::default(); assert!(parser.parse(line.as_bytes()).is_ok()); @@ -1295,6 +1306,16 @@ mod tests { assert_eq!(err.first().unwrap().message, "invalid identifier"); } + + for line in vec!["$ 2", "#% 2", "# 2"].into_iter() { + let mut parser = Parser::default(); + let err = parser.parse(line.as_bytes()).unwrap_err(); + + assert_eq!( + err.first().unwrap().message, + "numeric literals cannot have white spaces" + ); + } } // Regular instructions. -- cgit v1.2.3