aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mikisabate@gmail.com>2025-01-09 15:02:20 +0100
committerMiquel Sabaté Solà <mikisabate@gmail.com>2025-01-09 15:02:20 +0100
commit4f5710aa516ab149d132cdb5863db08f08c10563 (patch)
tree1c72ac0b9510b03654f4e4f26532fe8d30ae3d5f /lib
parentbad314e1cfbfc06579838ebfafd01cdbcb0a0a6e (diff)
downloadtools.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')
-rw-r--r--lib/xixanta/src/parser.rs27
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.