mirror of
https://github.com/askama-rs/askama.git
synced 2025-09-28 05:21:14 +00:00
Prevent crate
, Self
and super
to be used as identifiers
This commit is contained in:
parent
6ac39d24d9
commit
244980e0e9
@ -39,6 +39,14 @@ fn check_expr<'a>(
|
||||
allow_underscore: bool,
|
||||
) -> Result<(), ParseErr<'a>> {
|
||||
match &expr.inner {
|
||||
// List can be found in rust compiler "can_be_raw" function (although in our case, it's also
|
||||
// used in cases like `match`, so `self` is allowed in this case).
|
||||
Expr::Var(name @ ("crate" | "super" | "Self")) => {
|
||||
Err(winnow::error::ErrMode::Cut(ErrorContext::new(
|
||||
format!("`{name}` cannot be used as an identifier"),
|
||||
expr.span,
|
||||
)))
|
||||
}
|
||||
Expr::Var("_") if !allow_underscore => Err(winnow::error::ErrMode::Cut(ErrorContext::new(
|
||||
"reserved keyword `_` cannot be used here",
|
||||
expr.span,
|
||||
@ -53,11 +61,21 @@ fn check_expr<'a>(
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Expr::Path(path) => {
|
||||
if let [name] = path.as_slice() {
|
||||
if !crate::can_be_variable_name(name) {
|
||||
return Err(winnow::error::ErrMode::Cut(ErrorContext::new(
|
||||
format!("`{name}` cannot be used as an identifier"),
|
||||
expr.span,
|
||||
)));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Expr::BoolLit(_)
|
||||
| Expr::NumLit(_, _)
|
||||
| Expr::StrLit(_)
|
||||
| Expr::CharLit(_)
|
||||
| Expr::Path(_)
|
||||
| Expr::Attr(_, _)
|
||||
| Expr::Filter(_)
|
||||
| Expr::NamedArgument(_, _)
|
||||
@ -702,7 +720,17 @@ impl<'a> Suffix<'a> {
|
||||
preceded(
|
||||
ws(('.', not('.'))),
|
||||
cut_err((
|
||||
alt((digit1, identifier)),
|
||||
|i: &mut _| {
|
||||
let name = alt((digit1, identifier)).parse_next(i)?;
|
||||
if !crate::can_be_variable_name(name) {
|
||||
Err(winnow::error::ErrMode::Cut(ErrorContext::new(
|
||||
format!("`{name}` cannot be used as an identifier"),
|
||||
*i,
|
||||
)))
|
||||
} else {
|
||||
Ok(name)
|
||||
}
|
||||
},
|
||||
opt(|i: &mut _| call_generics(i, level)),
|
||||
)),
|
||||
)
|
||||
|
@ -1077,6 +1077,11 @@ pub fn strip_common(base: &Path, path: &Path) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn can_be_variable_name(name: &str) -> bool {
|
||||
!matches!(name, "self" | "Self" | "super" | "crate")
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum IntKind {
|
||||
I8,
|
||||
|
@ -108,6 +108,15 @@ impl<'a> Target<'a> {
|
||||
return Ok(Self::Struct(path, targets));
|
||||
}
|
||||
|
||||
// If the path only contains one item, we need to check the name.
|
||||
if let [name] = path.as_slice() {
|
||||
if !crate::can_be_variable_name(name) {
|
||||
return Err(winnow::error::ErrMode::Cut(ErrorContext::new(
|
||||
format!("`{name}` cannot be used as an identifier"),
|
||||
i_before_matching_with,
|
||||
)));
|
||||
}
|
||||
}
|
||||
*i = i_before_matching_with;
|
||||
return Ok(Self::Path(path));
|
||||
}
|
||||
@ -204,6 +213,11 @@ fn verify_name<'a>(
|
||||
format!("cannot use `{name}` as a name: it is a rust keyword"),
|
||||
input,
|
||||
)))
|
||||
} else if !crate::can_be_variable_name(name) {
|
||||
Err(winnow::error::ErrMode::Cut(ErrorContext::new(
|
||||
format!("`{name}` cannot be used as an identifier"),
|
||||
input,
|
||||
)))
|
||||
} else if name.starts_with("__askama") {
|
||||
Err(winnow::error::ErrMode::Cut(ErrorContext::new(
|
||||
format!("cannot use `{name}` as a name: it is reserved for `askama`"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user