Script checker: a private name that starts with a directive's name is read to its end

Inside braces, a line such as `#include$size = 1` was taken for an `#include` line, because only the ASCII letters, digits and `_` after the `#` were compared with the directive names. The name now runs over every character a name may hold, written out or as an escape, before the comparison.
This commit is contained in:
dotCooCoo
2026-11-11 22:49:43 -08:00
parent 283e1267f6
commit f388a795ce
2 changed files with 27 additions and 2 deletions
+12 -2
View File
@@ -457,10 +457,20 @@ impl<'s> Lexer<'s> {
/// A line that starts with `#` and then `rest` is a private name here, not a preprocessor line:
/// the line is inside braces or in the code of an XML literal, and the name `rest` starts with
/// is not a directive's.
/// is not a directive's. The name runs over every character a name may hold, written out or as
/// an escape, so `#include$size` is not `#include`.
pub fn private_line(&self, rest: &str) -> bool {
let in_code = !self.braces.is_empty() || self.deeper_braces > 0 || !self.xml.is_empty();
let end = rest.find(|c: char| !c.is_ascii_alphanumeric() && c != '_').unwrap_or(rest.len());
let mut end = 0;
while let Some(more) = rest.get(end..) {
let len = match more.chars().next() {
Some('\\') => escape(more).filter(|&(c, _)| ident_part(c)).map(|(_, len)| len),
Some(c) if ident_part(c) => Some(c.len_utf8()),
_ => None,
};
let Some(len) = len else { break };
end += len;
}
let name = rest.get(..end).unwrap_or_default();
in_code && !catalog::DIRECTIVES.iter().any(|d| d.eq_ignore_ascii_case(name))
}
+15
View File
@@ -491,6 +491,21 @@ fn private_name_at_line_start_is_not_a_directive() {
);
}
#[test]
fn private_name_that_starts_with_a_directive_name_is_not_a_directive() {
let r = report(concat!(
"class Box {\n",
" #include$size = 1;\n",
" #include\u{e9} = 2;\n",
" #include\\u0041 = 3;\n",
" #include\\u{41} = 4;\n",
" #INCLUDE 'a.jsxinc'\n",
"}\n",
));
let directives: Vec<_> = r.directives.iter().map(|d| (d.name, d.line)).collect();
assert_eq!(directives, [("include", 6)]);
}
#[test]
fn xml_code_uses_escaped_names() {
let r = report("var x = <a>{\\u{61}pp.activeDocument}</a>;\nvar y = <b>\\u0061pp.z \\u{61}</b>;\n");