disallow more at-rules in @function

This commit is contained in:
Connor Skees 2020-08-02 23:00:00 -04:00
parent 2df5e1b274
commit 3e5f69118b
6 changed files with 157 additions and 0 deletions

View File

@ -31,6 +31,10 @@ impl<'a> Parser<'a> {
return Err(("Functions may not be declared in control directives.", span).into());
}
if self.flags.in_function() {
return Err(("This at-rule is not allowed here.", self.span_before).into());
}
if RESERVED_IDENTIFIERS.contains(&unvendor(&name)) {
return Err(("Invalid function name.", span).into());
}

View File

@ -111,6 +111,10 @@ impl<'a> Parser<'a> {
}
pub(super) fn import(&mut self) -> SassResult<Vec<Stmt>> {
if self.flags.in_function() {
return Err(("This at-rule is not allowed here.", self.span_before).into());
}
self.whitespace();
match self.toks.peek() {

View File

@ -185,6 +185,10 @@ impl<'a> Parser<'a> {
}
pub(super) fn parse_keyframes(&mut self, rule: String) -> SassResult<Stmt> {
if self.flags.in_function() {
return Err(("This at-rule is not allowed here.", self.span_before).into());
}
let name = self.parse_keyframes_name()?;
self.whitespace();

View File

@ -66,6 +66,10 @@ impl<'a> Parser<'a> {
}
pub(super) fn parse_include(&mut self) -> SassResult<Vec<Stmt>> {
if self.flags.in_function() {
return Err(("This at-rule is not allowed here.", self.span_before).into());
}
self.whitespace_or_comment();
let name = self.parse_identifier()?.map_node(Into::into);

View File

@ -131,6 +131,14 @@ impl<'a> Parser<'a> {
}
}
AtRuleKind::AtRoot => {
if self.flags.in_function() {
return Err((
"This at-rule is not allowed here.",
kind_string.span,
)
.into());
}
if self.at_root {
stmts.append(&mut self.parse_at_root()?);
} else {
@ -186,6 +194,14 @@ impl<'a> Parser<'a> {
AtRuleKind::For => stmts.append(&mut self.parse_for()?),
AtRuleKind::While => stmts.append(&mut self.parse_while()?),
AtRuleKind::Charset => {
if self.flags.in_function() {
return Err((
"This at-rule is not allowed here.",
kind_string.span,
)
.into());
}
read_until_semicolon_or_closing_curly_brace(self.toks)?;
if let Some(Token { kind: ';', .. }) = self.toks.peek() {
self.toks.next();
@ -532,6 +548,10 @@ impl<'a> Parser<'a> {
impl<'a> Parser<'a> {
fn parse_unknown_at_rule(&mut self, name: String) -> SassResult<Stmt> {
if self.flags.in_function() {
return Err(("This at-rule is not allowed here.", self.span_before).into());
}
let mut params = String::new();
self.whitespace();
if let Some(Token { kind: ';', .. }) | None = self.toks.peek() {
@ -595,6 +615,10 @@ impl<'a> Parser<'a> {
}
fn parse_media(&mut self) -> SassResult<Stmt> {
if self.flags.in_function() {
return Err(("This at-rule is not allowed here.", self.span_before).into());
}
let query = self.parse_media_query_list()?;
self.whitespace();
@ -690,6 +714,9 @@ impl<'a> Parser<'a> {
}
fn parse_extend(&mut self) -> SassResult<()> {
if self.flags.in_function() {
return Err(("This at-rule is not allowed here.", self.span_before).into());
}
// todo: track when inside ruleset or `@content`
// if !self.in_style_rule && !self.in_mixin && !self.in_content_block {
// return Err(("@extend may only be used within style rules.", self.span_before).into());
@ -757,6 +784,10 @@ impl<'a> Parser<'a> {
}
fn parse_supports(&mut self) -> SassResult<Stmt> {
if self.flags.in_function() {
return Err(("This at-rule is not allowed here.", self.span_before).into());
}
let params = self.parse_media_args()?;
if params.is_empty() {

View File

@ -195,3 +195,113 @@ test!(
}",
"a {\n color: foo;\n color: bar;\n}\n"
);
error!(
disallows_unknown_at_rule,
"@function foo() {
@foo;
}
a {
color: foo();
}",
"Error: This at-rule is not allowed here."
);
error!(
disallows_media_query,
"@function foo() {
@media screen {};
}
a {
color: foo();
}",
"Error: This at-rule is not allowed here."
);
error!(
disallows_at_root,
"@function foo() {
@at-root {};
}
a {
color: foo();
}",
"Error: This at-rule is not allowed here."
);
error!(
disallows_charset,
"@function foo() {
@charset 'utf-8';
}
a {
color: foo();
}",
"Error: This at-rule is not allowed here."
);
error!(
disallows_extend,
"@function foo() {
@extend a;
}
a {
color: foo();
}",
"Error: This at-rule is not allowed here."
);
error!(
disallows_keyframes,
"@function foo() {
@keyframes foo {}
}
a {
color: foo();
}",
"Error: This at-rule is not allowed here."
);
error!(
disallows_supports,
"@function foo() {
@supports foo {}
}
a {
color: foo();
}",
"Error: This at-rule is not allowed here."
);
error!(
disallows_import,
"@function foo() {
@import \"foo.css\";
}
a {
color: foo();
}",
"Error: This at-rule is not allowed here."
);
error!(
disallows_inner_function_declaration,
"@function foo() {
@function bar() {}
}
a {
color: foo();
}",
"Error: This at-rule is not allowed here."
);
error!(
disallows_include,
"@function foo() {
@include bar;
}
a {
color: foo();
}",
"Error: This at-rule is not allowed here."
);