Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional CSS validation #62

Merged
merged 2 commits into from Jan 2, 2020
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -37,8 +37,8 @@ base64 = "0.10"
rmp-serde = "0.13.7" # rmp-serde 0.14.0 breaks deserialization by changing how enums are deserialized
hashbrown = { version = "0.6", features = ["serde"] }
lifeguard = { version = "0.6", optional = true }
cssparser = "0.25"
selectors = "0.21"
cssparser = { version = "0.25", optional = true }
selectors = { version = "0.21", optional = true }
psl = "0.4.1"

[dev-dependencies]
@@ -81,3 +81,4 @@ full-domain-matching = [] # feature has no explicit dependencies
metrics = []
full-regex-handling = []
object-pooling = ["lifeguard"]
css-validation = ["cssparser", "selectors"]
@@ -12,6 +12,19 @@ lazy_static! {
static ref PUBLIC_SUFFIXES: psl::List = psl::List::new();
}

/// Contains cosmetic filter information intended to be injected into a particular hostname.
///
/// `hide_selectors` is a set of any CSS selector on the page that should be hidden, i.e. styled as
/// `{ display: none !important; }`.
///
/// `style_selectors` is a map of CSS selectors on the page to respective non-hide style rules,
/// i.e. any required styles other than `display: none`.
///
/// `exceptions` is a set of any class or id CSS selectors that should not have generic rules
/// applied. In practice, these should be passed to `class_id_stylesheet` and not used otherwise.
///
/// `injected_script` is the Javascript code for any scriptlets that should be injected into the
/// page.
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct HostnameSpecificResources {
pub hide_selectors: HashSet<String>,
@@ -217,10 +217,18 @@ impl Engine {

// Cosmetic filter functionality

pub fn class_id_stylesheet(&self, classes: &[String], ids: &[String], exceptions: HashSet<String>) -> Option<String> {
self.cosmetic_cache.class_id_stylesheet(classes, ids, &exceptions)
}

/// If any of the provided CSS classes or ids could cause a certain generic CSS hide rule
/// (i.e. `{ display: none !important; }`) to be required, this method will return a stylesheet
/// including it, providing that the corresponding rule does not have an exception.
///
/// `exceptions` should be passed directly from `HostnameSpecificResources`.
pub fn class_id_stylesheet(&self, classes: &[String], ids: &[String], exceptions: &HashSet<String>) -> Option<String> {
self.cosmetic_cache.class_id_stylesheet(classes, ids, exceptions)
}

/// Returns a set of cosmetic filter resources required for a particular hostname. Once this
/// has been called, all CSS ids and classes on a page should be passed to
/// `class_id_stylesheet` to obtain any stylesheets consisting of generic rules.
pub fn hostname_cosmetic_resources(&self, hostname: &str) -> HostnameSpecificResources {
self.cosmetic_cache.hostname_cosmetic_resources(hostname)
}
@@ -20,6 +20,7 @@ pub enum CosmeticFilterError {
GenericScriptInject,
GenericStyle,
DoubleNegation,
EmptyRule,
}

bitflags! {
@@ -207,6 +208,10 @@ impl CosmeticFilter {
};

let mut selector = &line[suffix_start_index..];

if selector.trim().len() == 0 {
return Err(CosmeticFilterError::EmptyRule);
}
let mut style = None;
if line.len() - suffix_start_index > 4 && line[suffix_start_index..].starts_with("+js(") {
if sharp_index == 0 {
@@ -371,6 +376,18 @@ pub fn get_hostname_hashes_from_labels(hostname: &str, domain: &str) -> Vec<Hash
get_hashes_from_labels(hostname, hostname.len(), hostname.len() - domain.len())
}

#[cfg(not(feature="css-validation"))]
mod css_validation {
pub fn is_valid_css_selector(_selector: &str) -> bool {
true
}

pub fn is_valid_css_style(_style: &str) -> bool {
true
}
}

#[cfg(feature="css-validation")]
mod css_validation {
//! Methods for validating CSS selectors and style rules extracted from cosmetic filter rules.
use cssparser::ParserInput;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.