diff --git a/src/filters/abstract_network.rs b/src/filters/abstract_network.rs index b97c9b33..be326df0 100644 --- a/src/filters/abstract_network.rs +++ b/src/filters/abstract_network.rs @@ -59,7 +59,6 @@ pub(crate) enum NetworkFilterOption { XmlHttpRequest(bool), Websocket(bool), Font(bool), - All, } impl NetworkFilterOption { @@ -78,7 +77,6 @@ impl NetworkFilterOption { | Self::XmlHttpRequest(..) | Self::Websocket(..) | Self::Font(..) - | Self::All ) } @@ -163,11 +161,14 @@ fn parse_filter_options(raw_options: &str) -> Result, N // Check for options: option=value1|value2 let mut option_and_values = maybe_negated_option.splitn(2, '='); - let (option, value) = ( + let (raw_option_name, value) = ( option_and_values.next().unwrap(), option_and_values.next().unwrap_or_default(), ); + // $all is a uBO alias for $document. + let option = if raw_option_name == "all" { "doc" } else { raw_option_name }; + result.push(match (option, negation) { ("domain", _) | ("from", _) => { let domains: Vec<(bool, String)> = value @@ -251,8 +252,6 @@ fn parse_filter_options(raw_options: &str) -> Result, N } ("websocket", negated) => NetworkFilterOption::Websocket(!negated), ("font", negated) => NetworkFilterOption::Font(!negated), - ("all", true) => return Err(NetworkFilterError::NegatedAll), - ("all", false) => NetworkFilterOption::All, (_, _) => return Err(NetworkFilterError::UnrecognisedOption), }); } diff --git a/src/filters/network.rs b/src/filters/network.rs index 4e23ca58..9758293d 100644 --- a/src/filters/network.rs +++ b/src/filters/network.rs @@ -41,8 +41,6 @@ pub enum NetworkFilterError { NegatedGenericHide, #[error("negated document")] NegatedDocument, - #[error("negated all")] - NegatedAll, #[error("generichide without exception")] GenericHideWithoutException, #[error("empty redirection")] @@ -568,7 +566,6 @@ impl NetworkFilter { apply_content_type!(FROM_WEBSOCKET, enabled) } NetworkFilterOption::Font(enabled) => apply_content_type!(FROM_FONT, enabled), - NetworkFilterOption::All => apply_content_type!(FROM_ALL_TYPES, true), } }); } diff --git a/tests/unit/filters/network.rs b/tests/unit/filters/network.rs index af9a5e35..184a0904 100644 --- a/tests/unit/filters/network.rs +++ b/tests/unit/filters/network.rs @@ -1080,6 +1080,60 @@ mod parse_tests { } } + #[test] + fn handles_all_option_as_document() { + fn doc_only_defaults() -> NetworkFilterBreakdown { + let mut d = default_network_filter_breakdown(); + d.hostname = Some(String::from("foo.com")); + d.is_hostname_anchor = true; + d.is_plain = true; + d.from_document = true; + d.from_network_types = false; + d.from_font = false; + d.from_image = false; + d.from_media = false; + d.from_object = false; + d.from_other = false; + d.from_ping = false; + d.from_script = false; + d.from_stylesheet = false; + d.from_subdocument = false; + d.from_websocket = false; + d.from_xml_http_request = false; + d + } + + { + let filter = + NetworkFilter::parse("||foo.com$all", true, Default::default()).unwrap(); + assert_eq!(doc_only_defaults(), NetworkFilterBreakdown::from(&filter)); + } + + for opt in &["document", "doc"] { + let filter = NetworkFilter::parse( + &format!("||foo.com${opt}"), + true, + Default::default(), + ) + .unwrap(); + assert_eq!(doc_only_defaults(), NetworkFilterBreakdown::from(&filter)); + } + + { + let filter = NetworkFilter::parse( + "||foo.com$all,domain=example.com", + true, + Default::default(), + ) + .unwrap(); + let mut expected = doc_only_defaults(); + expected.opt_domains = Some(vec![crate::utils::fast_hash("example.com")]); + assert_eq!(expected, NetworkFilterBreakdown::from(&filter)); + } + + assert_eq!(NetworkFilter::parse("||foo.com$~all", true, Default::default()).err(), Some(NetworkFilterError::NegatedDocument)); + } + #[test] fn handles_content_type_options() { let options = vec![ diff --git a/tests/unit/filters/network_matchers.rs b/tests/unit/filters/network_matchers.rs index 2a000f46..1fee8d28 100644 --- a/tests/unit/filters/network_matchers.rs +++ b/tests/unit/filters/network_matchers.rs @@ -804,4 +804,58 @@ mod match_tests { "" ); } + + #[test] + fn all_option_matches_document_only() { + { + let filter = + NetworkFilter::parse("||example.com^$all", true, Default::default()).unwrap(); + + let doc_request = request::Request::new( + "https://example.com/", + "https://example.com/", + "document", + ) + .unwrap(); + assert!(filter.matches_test(&doc_request)); + + let img_request = request::Request::new( + "https://example.com/image.png", + "https://example.com/", + "image", + ) + .unwrap(); + assert!(!filter.matches_test(&img_request)); + + let script_request = request::Request::new( + "https://example.com/app.js", + "https://example.com/", + "script", + ) + .unwrap(); + assert!(!filter.matches_test(&script_request)); + } + + { + let filter = + NetworkFilter::parse("||example.com^$all,image", true, Default::default()) + .unwrap(); + + let doc_request = request::Request::new( + "https://example.com/", + "https://example.com/", + "document", + ) + .unwrap(); + assert!(filter.matches_test(&doc_request)); + + let img_request = request::Request::new( + "https://example.com/image.png", + "https://example.com/", + "image", + ) + .unwrap(); + assert!(!filter.matches_test(&img_request)); + } + } }