style: Disallow @import rules for all Constructable StyleSheets functions.

- Add enum AllowImportRules to CSS parsing.
- `replaceSync()` will skip over @import rules and continue parsing.
- `replace()` will skip over @import rules and continue parsing.
- `insertRule()` will throw a syntax error on @import rules.
- Modify WPT test cases to reflect these changes.

Differential Revision: https://phabricator.services.mozilla.com/D61882
This commit is contained in:
Erik Nordin 2020-03-12 18:11:09 +00:00 committed by Emilio Cobos Álvarez
parent 635f5fbf1b
commit edddf9e503
4 changed files with 34 additions and 3 deletions

View file

@ -59,7 +59,7 @@ pub use self::rules_iterator::{AllRules, EffectiveRules};
pub use self::rules_iterator::{NestedRuleIterationCondition, RulesIterator};
pub use self::style_rule::StyleRule;
pub use self::stylesheet::{DocumentStyleSheet, Namespaces, Stylesheet};
pub use self::stylesheet::{SanitizationData, SanitizationKind};
pub use self::stylesheet::{SanitizationData, SanitizationKind, AllowImportRules};
pub use self::stylesheet::{StylesheetContents, StylesheetInDocument, UserAgentStylesheets};
pub use self::supports_rule::SupportsRule;
pub use self::viewport_rule::ViewportRule;
@ -369,6 +369,7 @@ impl CssRule {
shared_lock: &SharedRwLock,
state: State,
loader: Option<&dyn StylesheetLoader>,
allow_import_rules: AllowImportRules,
) -> Result<Self, RulesMutateError> {
let url_data = parent_stylesheet_contents.url_data.read();
let context = ParserContext::new(
@ -395,6 +396,7 @@ impl CssRule {
dom_error: None,
namespaces: &mut *guard,
insert_rule_context: Some(insert_rule_context),
allow_import_rules,
};
parse_one_rule(&mut input, &mut rule_parser)

View file

@ -10,7 +10,7 @@ use crate::str::CssStringWriter;
use crate::stylesheets::loader::StylesheetLoader;
use crate::stylesheets::rule_parser::{InsertRuleContext, State};
use crate::stylesheets::stylesheet::StylesheetContents;
use crate::stylesheets::{CssRule, RulesMutateError};
use crate::stylesheets::{CssRule, RulesMutateError, AllowImportRules};
#[cfg(feature = "gecko")]
use malloc_size_of::{MallocShallowSizeOf, MallocSizeOfOps};
use servo_arc::{Arc, RawOffsetArc};
@ -128,6 +128,7 @@ pub trait CssRulesHelpers {
index: usize,
nested: bool,
loader: Option<&dyn StylesheetLoader>,
allow_import_rules: AllowImportRules,
) -> Result<CssRule, RulesMutateError>;
}
@ -140,6 +141,7 @@ impl CssRulesHelpers for RawOffsetArc<Locked<CssRules>> {
index: usize,
nested: bool,
loader: Option<&dyn StylesheetLoader>,
allow_import_rules: AllowImportRules,
) -> Result<CssRule, RulesMutateError> {
let new_rule = {
let read_guard = lock.read();
@ -176,6 +178,7 @@ impl CssRulesHelpers for RawOffsetArc<Locked<CssRules>> {
lock,
state,
loader,
allow_import_rules,
)?
};

View file

@ -19,6 +19,7 @@ use crate::stylesheets::keyframes_rule::parse_keyframe_list;
use crate::stylesheets::stylesheet::Namespaces;
use crate::stylesheets::supports_rule::SupportsCondition;
use crate::stylesheets::viewport_rule;
use crate::stylesheets::AllowImportRules;
use crate::stylesheets::{CorsMode, DocumentRule, FontFeatureValuesRule, KeyframesRule, MediaRule};
use crate::stylesheets::{CssRule, CssRuleType, CssRules, RulesMutateError, StylesheetLoader};
use crate::stylesheets::{NamespaceRule, PageRule, StyleRule, SupportsRule, ViewportRule};
@ -50,7 +51,7 @@ pub struct TopLevelRuleParser<'a> {
/// This won't contain any namespaces, and only nested parsers created with
/// `ParserContext::new_with_rule_type` will.
pub context: ParserContext<'a>,
/// The current state of the parser.
/// The current stajkj/te of the parser.
pub state: State,
/// Whether we have tried to parse was invalid due to being in the wrong
/// place (e.g. an @import rule was found while in the `Body` state). Reset
@ -62,6 +63,8 @@ pub struct TopLevelRuleParser<'a> {
pub namespaces: &'a mut Namespaces,
/// The info we need insert a rule in a list.
pub insert_rule_context: Option<InsertRuleContext<'a>>,
/// Whether @import rules will be allowed.
pub allow_import_rules: AllowImportRules,
}
impl<'b> TopLevelRuleParser<'b> {
@ -189,6 +192,10 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedImportRule))
}
if let AllowImportRules::No = self.allow_import_rules {
return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedImportRule))
}
// FIXME(emilio): We should always be able to have a loader
// around! See bug 1533783.
if self.loader.is_none() {
@ -203,6 +210,7 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
let media = Arc::new(self.shared_lock.wrap(media));
let prelude = AtRuleNonBlockPrelude::Import(url, media);
return Ok(AtRuleType::WithoutBlock(prelude));
},
"namespace" => {

View file

@ -81,6 +81,7 @@ impl StylesheetContents {
quirks_mode: QuirksMode,
line_number_offset: u32,
use_counters: Option<&UseCounters>,
allow_import_rules: AllowImportRules,
sanitization_data: Option<&mut SanitizationData>,
) -> Self {
let namespaces = RwLock::new(Namespaces::default());
@ -95,6 +96,7 @@ impl StylesheetContents {
quirks_mode,
line_number_offset,
use_counters,
allow_import_rules,
sanitization_data,
);
@ -355,6 +357,16 @@ pub enum SanitizationKind {
NoConditionalRules,
}
/// Whether @import rules are allowed.
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum AllowImportRules {
/// @import rules will be parsed.
Yes,
/// @import rules will not be parsed.
No,
}
impl SanitizationKind {
fn allows(self, rule: &CssRule) -> bool {
debug_assert_ne!(self, SanitizationKind::None);
@ -415,6 +427,7 @@ impl Stylesheet {
stylesheet_loader: Option<&dyn StylesheetLoader>,
error_reporter: Option<&dyn ParseErrorReporter>,
line_number_offset: u32,
allow_import_rules: AllowImportRules,
) {
let namespaces = RwLock::new(Namespaces::default());
@ -430,6 +443,7 @@ impl Stylesheet {
existing.contents.quirks_mode,
line_number_offset,
/* use_counters = */ None,
allow_import_rules,
/* sanitization_data = */ None,
);
@ -457,6 +471,7 @@ impl Stylesheet {
quirks_mode: QuirksMode,
line_number_offset: u32,
use_counters: Option<&UseCounters>,
allow_import_rules: AllowImportRules,
mut sanitization_data: Option<&mut SanitizationData>,
) -> (Vec<CssRule>, Option<String>, Option<String>) {
let mut rules = Vec::new();
@ -481,6 +496,7 @@ impl Stylesheet {
dom_error: None,
insert_rule_context: None,
namespaces,
allow_import_rules,
};
{
@ -537,6 +553,7 @@ impl Stylesheet {
error_reporter: Option<&dyn ParseErrorReporter>,
quirks_mode: QuirksMode,
line_number_offset: u32,
allow_import_rules: AllowImportRules,
) -> Self {
// FIXME: Consider adding use counters to Servo?
let contents = StylesheetContents::from_str(
@ -549,6 +566,7 @@ impl Stylesheet {
quirks_mode,
line_number_offset,
/* use_counters = */ None,
allow_import_rules,
/* sanitized_output = */ None,
);