mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 13:33:19 +00:00
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:
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user