diff options
| author | Miquel Sabaté Solà <mssola@mssola.com> | 2026-02-03 10:49:33 +0100 |
|---|---|---|
| committer | Miquel Sabaté Solà <mssola@mssola.com> | 2026-02-03 10:49:33 +0100 |
| commit | 8b38c88ae55a6edf1028a5aa57b93afdbc4001d6 (patch) | |
| tree | dd7f8a8c369000d6579a8dd20497ab20d93f1c9c /lib | |
| parent | 948ad7f2bda3495faebf39d1bb903f863e9ad596 (diff) | |
| download | tools.nes-8b38c88ae55a6edf1028a5aa57b93afdbc4001d6.tar.gz tools.nes-8b38c88ae55a6edf1028a5aa57b93afdbc4001d6.zip | |
Avoid invalid identifiers in proc/macro/scope
This was apparently neglected and you were able to pick invalid
identifiers to identify procs, macros and scopes. Ensure this does not
happen again and provide tests for it.
Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/xixanta/src/assembler.rs | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs index cb992d4..136d416 100644 --- a/lib/xixanta/src/assembler.rs +++ b/lib/xixanta/src/assembler.rs @@ -588,12 +588,25 @@ impl<'a> Assembler<'a> { // illegal definitions. self.macros_seen += 1; - // Insert a reference to this node so it can be - // unrolled whenever we have to perform a macro - // call. - self.macros - .entry(node.left.as_ref().unwrap().value.value.clone()) - .or_insert(node); + let name = &node.left.as_ref().unwrap().value; + if let Err(e) = name.is_valid_identifier(false) { + errors.push(Error { + message: format!( + "'{}' is not a valid macro name: {e}", + name.value + ), + line: node.value.line, + global: false, + expanded_from: self.macro_context.clone(), + source: self.source_for(node), + }); + continue; + } else { + // Insert a reference to this node so it can be + // unrolled whenever we have to perform a macro + // call. + self.macros.entry(name.value.clone()).or_insert(node); + } } ControlType::EndMacro => { if self.macros_seen > 0 { @@ -616,7 +629,19 @@ impl<'a> Assembler<'a> { self.procs_seen += 1; let proc_name = &node.left.as_ref().unwrap(); - if let Err(err) = self.define_variable(proc_name) { + if let Err(err) = proc_name.value.is_valid_identifier(false) { + errors.push(Error { + message: format!( + "'{}' is not a valid proc name: {err}", + proc_name.value.value, + ), + line: node.value.line, + global: false, + expanded_from: self.macro_context.clone(), + source: self.source_for(node), + }); + continue; + } else if let Err(err) = self.define_variable(proc_name) { errors.push(err); } } @@ -638,6 +663,20 @@ impl<'a> Assembler<'a> { }); continue; } + let scope_name = &node.left.as_ref().unwrap(); + if let Err(err) = scope_name.value.is_valid_identifier(false) { + errors.push(Error { + message: format!( + "'{}' is not a valid scope name: {err}", + scope_name.value.value, + ), + line: node.value.line, + global: false, + expanded_from: self.macro_context.clone(), + source: self.source_for(node), + }); + continue; + } } ControlType::StartRepeat => { self.repeats_seen += 1; @@ -4758,6 +4797,18 @@ MACRO Var1 } #[test] + fn bad_macro_name() { + assert_error( + r#".macro __fallthrough__ arg + .endmacro + "#, + 1, + false, + "'__fallthrough__' is not a valid macro name: cannot use reserved name '__fallthrough__'", + ); + } + + #[test] fn bad_scope_definition_inside_of_proc() { assert_error( r#".proc Hey |
