diff options
| author | Miquel Sabaté Solà <mikisabate@gmail.com> | 2025-01-09 15:02:20 +0100 |
|---|---|---|
| committer | Miquel Sabaté Solà <mikisabate@gmail.com> | 2025-01-09 15:02:20 +0100 |
| commit | 4f5710aa516ab149d132cdb5863db08f08c10563 (patch) | |
| tree | 1c72ac0b9510b03654f4e4f26532fe8d30ae3d5f /lib/xixanta/src | |
| parent | bad314e1cfbfc06579838ebfafd01cdbcb0a0a6e (diff) | |
| download | tools.nes-4f5710aa516ab149d132cdb5863db08f08c10563.tar.gz tools.nes-4f5710aa516ab149d132cdb5863db08f08c10563.zip | |
Restrict literal characters further
In bad314e1cfbf ("Prevent numeric literals from having spaces") it was
added already the restriction on not having whitespace characters in
literal expressions. Here we go a step further and we more explicitely
limit which symbol combinations can go into a literal declaration (e.g.
"#$2" is valid but "##2" is not).
Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'lib/xixanta/src')
| -rw-r--r-- | lib/xixanta/src/parser.rs | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/lib/xixanta/src/parser.rs b/lib/xixanta/src/parser.rs index 7e72082..0757505 100644 --- a/lib/xixanta/src/parser.rs +++ b/lib/xixanta/src/parser.rs @@ -840,11 +840,27 @@ impl Parser { return Err(self.parser_error("invalid identifier")); } + // Cache the first character on the next part as it's used in lots of + // places. + let start = line.chars().nth(0).unwrap_or(' '); + if id.value.starts_with(".") { self.parse_control(id, line) - } else if line.starts_with('$') || line.starts_with('#') || line.starts_with('%') { + } else if start == '$' || start == '#' || start == '%' { + // Literal symbols come with a single character, or with two only on + // '#$' or '#%'. Other variations are illegal and should be avoided + // to prevent crashes. + if let Some(next) = line.chars().nth(1) { + if next == '#' || (start != '#' && (next == '$' || next == '%')) { + return Err(ParseError { + line: id.line, + message: "bad literal syntax".to_string(), + }); + } + } + self.parse_literal(id, line) - } else if line.starts_with('\'') { + } else if start == '\'' { self.parse_char(id) } else { // Skip any whitespace after our identifier. @@ -1316,6 +1332,13 @@ mod tests { "numeric literals cannot have white spaces" ); } + + for line in vec!["##2", "#$$2", "$$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, "bad literal syntax"); + } } // Regular instructions. |
