diff --git a/src/blocker.rs b/src/blocker.rs index 6e89db19..71a04e8d 100644 --- a/src/blocker.rs +++ b/src/blocker.rs @@ -927,7 +927,7 @@ mod tests { let filters = vec!["||foo.com"]; let network_filters: Vec<_> = filters .into_iter() - .map(|f| NetworkFilter::parse(&f, true)) + .map(|f| NetworkFilter::parse(&f, true, Default::default())) .filter_map(Result::ok) .collect(); let filter_list = NetworkFilterList::new(network_filters, false); @@ -939,7 +939,7 @@ mod tests { let filters = vec!["||foo.com", "||bar.com/foo"]; let network_filters: Vec<_> = filters .into_iter() - .map(|f| NetworkFilter::parse(&f, true)) + .map(|f| NetworkFilter::parse(&f, true, Default::default())) .filter_map(Result::ok) .collect(); let filter_list = NetworkFilterList::new(network_filters, false); @@ -957,7 +957,7 @@ mod tests { let filters = vec!["||foo.com", "||foo.com/bar", "||www"]; let network_filters: Vec<_> = filters .into_iter() - .map(|f| NetworkFilter::parse(&f, true)) + .map(|f| NetworkFilter::parse(&f, true, Default::default())) .filter_map(Result::ok) .collect(); let filter_list = NetworkFilterList::new(network_filters, false); @@ -976,7 +976,7 @@ mod tests { let filters = vec!["||foo.com", "||foo.com$domain=bar.com"]; let network_filters: Vec<_> = filters .into_iter() - .map(|f| NetworkFilter::parse(&f, true)) + .map(|f| NetworkFilter::parse(&f, true, Default::default())) .filter_map(Result::ok) .collect(); let filter_list = NetworkFilterList::new(network_filters, false); @@ -999,7 +999,7 @@ mod tests { let filters = vec!["foo*$domain=bar.com|baz.com"]; let network_filters: Vec<_> = filters .into_iter() - .map(|f| NetworkFilter::parse(&f, true)) + .map(|f| NetworkFilter::parse(&f, true, Default::default())) .filter_map(Result::ok) .collect(); let filter_list = NetworkFilterList::new(network_filters, false); @@ -1036,7 +1036,7 @@ mod tests { fn test_requests_filters(filters: &Vec<&str>, requests: &Vec<(Request, bool)>) { let network_filters: Vec<_> = filters .into_iter() - .map(|f| NetworkFilter::parse(&f, true)) + .map(|f| NetworkFilter::parse(&f, true, Default::default())) .filter_map(Result::ok) .collect(); let filter_list = NetworkFilterList::new(network_filters, false); @@ -1201,7 +1201,7 @@ mod tests { mod blocker_tests { use super::*; - use crate::lists::{parse_filters, FilterFormat}; + use crate::lists::{parse_filters, FilterFormat, parse_filters_with_opts, ParseOptions}; use crate::request::Request; use std::collections::HashSet; use std::iter::FromIterator; @@ -1233,7 +1233,9 @@ mod blocker_tests { let request = Request::from_urls("https://foo.com", "https://foo.com", "script").unwrap(); - let (network_filters, _) = parse_filters(&filters, true, FilterFormat::Standard); + let opts = ParseOptions { parse_redirect_urls: true, ..Default::default() }; + + let (network_filters, _) = parse_filters_with_opts(&filters, true, opts); let blocker_options: BlockerOptions = BlockerOptions { enable_optimizations: false, @@ -1248,6 +1250,28 @@ mod blocker_tests { assert_eq!(matched_rule.error, None); } + #[test] + fn redirect_url_not_recognized_without_parse_opt() { + let filters = vec![ + String::from("||foo.com$important,redirect-url=http://xyz.com"), + ]; + + let request = Request::from_urls("https://foo.com", "https://foo.com", "script").unwrap(); + + let (network_filters, _) = parse_filters(&filters, true, FilterFormat::Standard); + + let blocker_options: BlockerOptions = BlockerOptions { + enable_optimizations: false, + }; + + let blocker = Blocker::new(network_filters, &blocker_options); + + let matched_rule = blocker.check(&request); + assert_eq!(matched_rule.matched, false); + assert_eq!(matched_rule.redirect, None); + assert_eq!(matched_rule.error, None); + } + #[test] fn redirect_url_malformed() { let filters = vec![ @@ -1256,7 +1280,9 @@ mod blocker_tests { let request = Request::from_urls("https://foo.com", "https://foo.com", "script").unwrap(); - let (network_filters, _) = parse_filters(&filters, true, FilterFormat::Standard); + let opts = ParseOptions { parse_redirect_urls: true, ..Default::default() }; + + let (network_filters, _) = parse_filters_with_opts(&filters, true, opts); let blocker_options: BlockerOptions = BlockerOptions { enable_optimizations: false, @@ -1280,7 +1306,9 @@ mod blocker_tests { let request = Request::from_urls("https://imdb-video.media-imdb.com/kBOeI88k1o23eNAi", "https://www.imdb.com/video/13", "media").unwrap(); - let (network_filters, _) = parse_filters(&filters, true, FilterFormat::Standard); + let opts = ParseOptions { parse_redirect_urls: true, ..Default::default() }; + + let (network_filters, _) = parse_filters_with_opts(&filters, true, opts); let blocker_options: BlockerOptions = BlockerOptions { enable_optimizations: false, @@ -1596,7 +1624,7 @@ mod blocker_tests { let mut blocker = Blocker::new(Vec::new(), &blocker_options); - let filter = NetworkFilter::parse("adv$badfilter", true).unwrap(); + let filter = NetworkFilter::parse("adv$badfilter", true, Default::default()).unwrap(); let added = blocker.add_filter(filter); assert!(added.is_err()); assert_eq!(added.err().unwrap(), BlockerError::BadFilterAddUnsupported); @@ -1613,7 +1641,7 @@ mod blocker_tests { let mut blocker = Blocker::new(Vec::new(), &blocker_options); - let filter = NetworkFilter::parse("adv", true).unwrap(); + let filter = NetworkFilter::parse("adv", true, Default::default()).unwrap(); blocker.add_filter(filter.clone()).unwrap(); assert!(blocker.filter_exists(&filter), "Expected filter to be inserted"); let added = blocker.add_filter(filter); @@ -1628,7 +1656,7 @@ mod blocker_tests { let mut blocker = Blocker::new(Vec::new(), &blocker_options); - let filter = NetworkFilter::parse("adv", true).unwrap(); + let filter = NetworkFilter::parse("adv", true, Default::default()).unwrap(); blocker.add_filter(filter.clone()).unwrap(); let added = blocker.add_filter(filter); assert!(added.is_ok()); @@ -1645,10 +1673,10 @@ mod blocker_tests { let mut blocker = Blocker::new(Vec::new(), &blocker_options); blocker.enable_tags(&["brian"]); - blocker.add_filter(NetworkFilter::parse("adv$tag=stuff", true).unwrap()).unwrap(); - blocker.add_filter(NetworkFilter::parse("somelongpath/test$tag=stuff", true).unwrap()).unwrap(); - blocker.add_filter(NetworkFilter::parse("||brianbondy.com/$tag=brian", true).unwrap()).unwrap(); - blocker.add_filter(NetworkFilter::parse("||brave.com$tag=brian", true).unwrap()).unwrap(); + blocker.add_filter(NetworkFilter::parse("adv$tag=stuff", true, Default::default()).unwrap()).unwrap(); + blocker.add_filter(NetworkFilter::parse("somelongpath/test$tag=stuff", true, Default::default()).unwrap()).unwrap(); + blocker.add_filter(NetworkFilter::parse("||brianbondy.com/$tag=brian", true, Default::default()).unwrap()).unwrap(); + blocker.add_filter(NetworkFilter::parse("||brave.com$tag=brian", true, Default::default()).unwrap()).unwrap(); let url_results = vec![ (Request::from_url("http://example.com/advert.html").unwrap(), false), @@ -1675,7 +1703,7 @@ mod blocker_tests { let mut blocker = Blocker::new(Vec::new(), &blocker_options); - blocker.add_filter(NetworkFilter::parse("@@*ad_banner.png", true).unwrap()).unwrap(); + blocker.add_filter(NetworkFilter::parse("@@*ad_banner.png", true, Default::default()).unwrap()).unwrap(); let request = Request::from_url("http://example.com/ad_banner.png").unwrap(); @@ -1692,7 +1720,7 @@ mod blocker_tests { let mut blocker = Blocker::new(Vec::new(), &blocker_options); - blocker.add_filter(NetworkFilter::parse("@@||example.com$generichide", true).unwrap()).unwrap(); + blocker.add_filter(NetworkFilter::parse("@@||example.com$generichide", true, Default::default()).unwrap()).unwrap(); assert!(blocker.check_generic_hide(&Request::from_url("https://example.com").unwrap())); } diff --git a/src/engine.rs b/src/engine.rs index 0cbf44f7..6e2e7535 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1,6 +1,6 @@ use crate::blocker::{Blocker, BlockerError, BlockerOptions, BlockerResult}; use crate::cosmetic_filter_cache::{CosmeticFilterCache, UrlSpecificResources}; -use crate::lists::{FilterFormat, FilterSet}; +use crate::lists::{FilterFormat, FilterSet, ParseOptions}; use crate::request::Request; use crate::resources::{Resource, RedirectResource}; @@ -44,12 +44,24 @@ impl Engine { /// Loads rules, enabling optimizations and including debug information. pub fn from_rules_debug(rules: &[String], format: FilterFormat) -> Self { - Self::from_rules_parametrised(&rules, format, true, true) + let opts = ParseOptions { format, ..Default::default() }; + Self::from_rules_debug_with_opts(&rules, opts) + } + + /// Loads rules, enabling optimizations and including debug information. + /// Include opts + pub fn from_rules_debug_with_opts(rules: &[String], opts: ParseOptions) -> Self { + Self::from_rules_parametrised_with_opts(&rules, opts, true, true) } pub fn from_rules_parametrised(filter_rules: &[String], format: FilterFormat, debug: bool, optimize: bool) -> Self { + let opts = ParseOptions { format, ..Default::default() }; + Self::from_rules_parametrised_with_opts(filter_rules, opts, debug, optimize) + } + + pub fn from_rules_parametrised_with_opts(filter_rules: &[String], opts: ParseOptions, debug: bool, optimize: bool) -> Self { let mut filter_set = FilterSet::new(debug); - filter_set.add_filters(filter_rules, format); + filter_set.add_filters_with_opts(filter_rules, opts); Self::from_filter_set(filter_set, optimize) } @@ -184,7 +196,7 @@ impl Engine { /// Note that only network filters are currently supported by this method. pub fn filter_exists(&self, filter: &str) -> bool { use crate::filters::network::NetworkFilter; - let filter_parsed = NetworkFilter::parse(filter, false); + let filter_parsed = NetworkFilter::parse(filter, false, Default::default()); match filter_parsed.map(|f| self.blocker.filter_exists(&f)) { Ok(exists) => exists, Err(_e) => { diff --git a/src/filters/network.rs b/src/filters/network.rs index e4b69f25..4555ffef 100644 --- a/src/filters/network.rs +++ b/src/filters/network.rs @@ -9,6 +9,7 @@ use std::sync::{Arc, RwLock}; use crate::request; use crate::utils; use crate::utils::Hash; +use crate::lists::ParseOptions; pub const TOKENS_BUFFER_SIZE: usize = 200; @@ -252,7 +253,7 @@ struct AbstractNetworkFilter { } impl AbstractNetworkFilter { - fn parse(line: &str) -> Result { + fn parse(line: &str, opts: ParseOptions) -> Result { let mut filter_index_start: usize = 0; let mut filter_index_end: usize = line.len(); @@ -272,7 +273,7 @@ impl AbstractNetworkFilter { // slicing here is safe; the first byte after '$' will be a character boundary let raw_options = &line[filter_index_end + 1..]; - options = Some(parse_filter_options(raw_options)?); + options = Some(parse_filter_options(raw_options, opts)?); } let left_anchor = if line[filter_index_start..].starts_with("||") { @@ -306,7 +307,7 @@ impl AbstractNetworkFilter { } } -fn parse_filter_options(raw_options: &str) -> Result, NetworkFilterError> { +fn parse_filter_options(raw_options: &str, opts: ParseOptions) -> Result, NetworkFilterError> { let mut result = vec![]; for raw_option in raw_options.split(',') { @@ -354,6 +355,10 @@ fn parse_filter_options(raw_options: &str) -> Result, N } ("redirect-url", true) => return Err(NetworkFilterError::NegatedRedirection), ("redirect-url", false) => { + // Only parse filter option if parse options allow it + if !opts.parse_redirect_urls { + return Err(NetworkFilterError::UnrecognisedOption); + } // Ignore this filter if no redirection resource is specified if value.is_empty() { return Err(NetworkFilterError::EmptyRedirection); @@ -463,8 +468,8 @@ fn validate_options(options: &[NetworkFilterOption]) -> Result<(), NetworkFilter } impl NetworkFilter { - pub fn parse(line: &str, debug: bool) -> Result { - let parsed = AbstractNetworkFilter::parse(line)?; + pub fn parse(line: &str, debug: bool, opts: ParseOptions) -> Result { + let parsed = AbstractNetworkFilter::parse(line, opts)?; // Represent options as a bitmask let mut mask: NetworkFilterMask = NetworkFilterMask::THIRD_PARTY @@ -835,7 +840,7 @@ impl NetworkFilter { } hostname.push('^'); - NetworkFilter::parse(&hostname, debug) + NetworkFilter::parse(&hostname, debug, Default::default()) } pub fn get_id_without_badfilter(&self) -> Hash { @@ -1708,21 +1713,21 @@ mod parse_tests { // pattern fn parses_plain_pattern() { { - let filter = NetworkFilter::parse("ads", true).unwrap(); + let filter = NetworkFilter::parse("ads", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.filter = Some(String::from("ads")); defaults.is_plain = true; assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("/ads/foo-", true).unwrap(); + let filter = NetworkFilter::parse("/ads/foo-", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.filter = Some(String::from("/ads/foo-")); defaults.is_plain = true; assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("/ads/foo-$important", true).unwrap(); + let filter = NetworkFilter::parse("/ads/foo-$important", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.filter = Some(String::from("/ads/foo-")); defaults.is_plain = true; @@ -1730,7 +1735,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("foo.com/ads$important", true).unwrap(); + let filter = NetworkFilter::parse("foo.com/ads$important", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.filter = Some(String::from("foo.com/ads")); defaults.is_plain = true; @@ -1743,7 +1748,7 @@ mod parse_tests { // ||pattern fn parses_hostname_anchor_pattern() { { - let filter = NetworkFilter::parse("||foo.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.filter = None; defaults.hostname = Some(String::from("foo.com")); @@ -1752,7 +1757,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("||foo.com$important", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$important", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.filter = None; defaults.hostname = Some(String::from("foo.com")); @@ -1762,7 +1767,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("||foo.com/bar/baz$important", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com/bar/baz$important", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.filter = Some(String::from("/bar/baz")); @@ -1778,7 +1783,7 @@ mod parse_tests { // ||pattern| fn parses_hostname_right_anchor_pattern() { { - let filter = NetworkFilter::parse("||foo.com|", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com|", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.filter = None; @@ -1788,7 +1793,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("||foo.com|$important", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com|$important", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.filter = None; @@ -1799,7 +1804,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("||foo.com/bar/baz|$important", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com/bar/baz|$important", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.filter = Some(String::from("/bar/baz")); @@ -1811,7 +1816,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("||foo.com^bar/*baz|$important", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com^bar/*baz|$important", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.filter = Some(String::from("^bar/*baz")); @@ -1828,7 +1833,7 @@ mod parse_tests { // |pattern fn parses_left_anchor_pattern() { { - let filter = NetworkFilter::parse("|foo.com", true).unwrap(); + let filter = NetworkFilter::parse("|foo.com", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.filter = Some(String::from("foo.com")); defaults.is_plain = true; @@ -1836,7 +1841,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("|foo.com/bar/baz", true).unwrap(); + let filter = NetworkFilter::parse("|foo.com/bar/baz", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.filter = Some(String::from("foo.com/bar/baz")); defaults.is_plain = true; @@ -1844,7 +1849,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("|foo.com^bar/*baz", true).unwrap(); + let filter = NetworkFilter::parse("|foo.com^bar/*baz", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.filter = Some(String::from("foo.com^bar/*baz")); defaults.is_regex = true; @@ -1857,7 +1862,7 @@ mod parse_tests { // |pattern| fn parses_left_right_anchor_pattern() { { - let filter = NetworkFilter::parse("|foo.com|", true).unwrap(); + let filter = NetworkFilter::parse("|foo.com|", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.filter = Some(String::from("foo.com")); @@ -1867,7 +1872,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("|foo.com/bar|", true).unwrap(); + let filter = NetworkFilter::parse("|foo.com/bar|", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.filter = Some(String::from("foo.com/bar")); @@ -1877,7 +1882,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("|foo.com*bar^|", true).unwrap(); + let filter = NetworkFilter::parse("|foo.com*bar^|", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.filter = Some(String::from("foo.com*bar^")); @@ -1892,7 +1897,7 @@ mod parse_tests { // ||regexp fn parses_hostname_anchor_regex_pattern() { { - let filter = NetworkFilter::parse("||foo.com*bar^", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com*bar^", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.filter = Some(String::from("bar^")); @@ -1902,7 +1907,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("||foo.com^bar*/baz^", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com^bar*/baz^", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.filter = Some(String::from("^bar*/baz^")); @@ -1918,7 +1923,7 @@ mod parse_tests { // ||regexp| fn parses_hostname_right_anchor_regex_pattern() { { - let filter = NetworkFilter::parse("||foo.com*bar^|", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com*bar^|", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.filter = Some(String::from("bar^")); @@ -1929,7 +1934,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("||foo.com^bar*/baz^|", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com^bar*/baz^|", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.filter = Some(String::from("^bar*/baz^")); @@ -1946,7 +1951,7 @@ mod parse_tests { // |regexp fn parses_hostname_left_anchor_regex_pattern() { { - let filter = NetworkFilter::parse("|foo.com*bar^", true).unwrap(); + let filter = NetworkFilter::parse("|foo.com*bar^", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = None; defaults.filter = Some(String::from("foo.com*bar^")); @@ -1956,7 +1961,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("|foo.com^bar*/baz^", true).unwrap(); + let filter = NetworkFilter::parse("|foo.com^bar*/baz^", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = None; defaults.filter = Some(String::from("foo.com^bar*/baz^")); @@ -1971,7 +1976,7 @@ mod parse_tests { // |regexp| fn parses_hostname_left_right_anchor_regex_pattern() { { - let filter = NetworkFilter::parse("|foo.com*bar^|", true).unwrap(); + let filter = NetworkFilter::parse("|foo.com*bar^|", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = None; defaults.filter = Some(String::from("foo.com*bar^")); @@ -1982,7 +1987,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)) } { - let filter = NetworkFilter::parse("|foo.com^bar*/baz^|", true).unwrap(); + let filter = NetworkFilter::parse("|foo.com^bar*/baz^|", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = None; defaults.filter = Some(String::from("foo.com^bar*/baz^")); @@ -1998,7 +2003,7 @@ mod parse_tests { // @@pattern fn parses_exception_pattern() { { - let filter = NetworkFilter::parse("@@ads", true).unwrap(); + let filter = NetworkFilter::parse("@@ads", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.is_exception = true; defaults.filter = Some(String::from("ads")); @@ -2006,7 +2011,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)); } { - let filter = NetworkFilter::parse("@@||foo.com/ads", true).unwrap(); + let filter = NetworkFilter::parse("@@||foo.com/ads", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.is_exception = true; defaults.filter = Some(String::from("/ads")); @@ -2017,7 +2022,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)); } { - let filter = NetworkFilter::parse("@@|foo.com/ads", true).unwrap(); + let filter = NetworkFilter::parse("@@|foo.com/ads", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.is_exception = true; defaults.filter = Some(String::from("foo.com/ads")); @@ -2026,7 +2031,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)); } { - let filter = NetworkFilter::parse("@@|foo.com/ads|", true).unwrap(); + let filter = NetworkFilter::parse("@@|foo.com/ads|", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.is_exception = true; defaults.filter = Some(String::from("foo.com/ads")); @@ -2036,7 +2041,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)); } { - let filter = NetworkFilter::parse("@@foo.com/ads|", true).unwrap(); + let filter = NetworkFilter::parse("@@foo.com/ads|", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.is_exception = true; defaults.filter = Some(String::from("foo.com/ads")); @@ -2045,7 +2050,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)); } { - let filter = NetworkFilter::parse("@@||foo.com/ads|", true).unwrap(); + let filter = NetworkFilter::parse("@@||foo.com/ads|", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.is_exception = true; defaults.filter = Some(String::from("/ads")); @@ -2063,7 +2068,7 @@ mod parse_tests { #[test] fn accepts_any_content_type() { { - let filter = NetworkFilter::parse("||foo.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.from_network_types = true; defaults.hostname = Some(String::from("foo.com")); @@ -2073,7 +2078,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)); } { - let filter = NetworkFilter::parse("||foo.com$first-party", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$first-party", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.from_network_types = true; defaults.hostname = Some(String::from("foo.com")); @@ -2085,7 +2090,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)); } { - let filter = NetworkFilter::parse("||foo.com$third-party", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$third-party", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.from_network_types = true; defaults.hostname = Some(String::from("foo.com")); @@ -2097,7 +2102,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&filter)); } { - let filter = NetworkFilter::parse("||foo.com$domain=test.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$domain=test.com", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.from_network_types = true; defaults.hostname = Some(String::from("foo.com")); @@ -2109,7 +2114,7 @@ mod parse_tests { } { let filter = - NetworkFilter::parse("||foo.com$domain=test.com,match-case", true).unwrap(); + NetworkFilter::parse("||foo.com$domain=test.com,match-case", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.from_network_types = true; defaults.hostname = Some(String::from("foo.com")); @@ -2125,17 +2130,17 @@ mod parse_tests { #[test] fn parses_important() { { - let filter = NetworkFilter::parse("||foo.com$important", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$important", true, Default::default()).unwrap(); assert_eq!(filter.is_important(), true); } { // parses ~important - let filter = NetworkFilter::parse("||foo.com$~important", true); + let filter = NetworkFilter::parse("||foo.com$~important", true, Default::default()); assert_eq!(filter.err(), Some(NetworkFilterError::NegatedImportant)); } { // defaults to false - let filter = NetworkFilter::parse("||foo.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com", true, Default::default()).unwrap(); assert_eq!(filter.is_important(), false); } } @@ -2143,25 +2148,25 @@ mod parse_tests { #[test] fn parses_csp() { { - let filter = NetworkFilter::parse("||foo.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com", true, Default::default()).unwrap(); assert_eq!(filter.csp, None); } { // parses simple CSP - let filter = NetworkFilter::parse(r#"||foo.com$csp=self bar """#, true).unwrap(); + let filter = NetworkFilter::parse(r#"||foo.com$csp=self bar """#, true, Default::default()).unwrap(); assert_eq!(filter.is_csp(), true); assert_eq!(filter.csp, Some(String::from(r#"self bar """#))); } { // parses empty CSP - let filter = NetworkFilter::parse("||foo.com$csp", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$csp", true, Default::default()).unwrap(); assert_eq!(filter.is_csp(), true); assert_eq!(filter.csp, None); } { // CSP mixed with content type is an error let filter = - NetworkFilter::parse(r#"||foo.com$domain=foo|bar,csp=self bar "",image"#, true); + NetworkFilter::parse(r#"||foo.com$domain=foo|bar,csp=self bar "",image"#, true, Default::default()); assert_eq!(filter.err(), Some(NetworkFilterError::CspWithContentType)); } } @@ -2170,12 +2175,12 @@ mod parse_tests { fn parses_domain() { // parses domain { - let filter = NetworkFilter::parse("||foo.com$domain=bar.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$domain=bar.com", true, Default::default()).unwrap(); assert_eq!(filter.opt_domains, Some(vec![utils::fast_hash("bar.com")])); assert_eq!(filter.opt_not_domains, None); } { - let filter = NetworkFilter::parse("||foo.com$domain=bar.com|baz.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$domain=bar.com|baz.com", true, Default::default()).unwrap(); let mut domains = vec![utils::fast_hash("bar.com"), utils::fast_hash("baz.com")]; domains.sort_unstable(); assert_eq!(filter.opt_domains, Some(domains)); @@ -2184,7 +2189,7 @@ mod parse_tests { // parses ~domain { - let filter = NetworkFilter::parse("||foo.com$domain=~bar.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$domain=~bar.com", true, Default::default()).unwrap(); assert_eq!(filter.opt_domains, None); assert_eq!( filter.opt_not_domains, @@ -2192,7 +2197,7 @@ mod parse_tests { ); } { - let filter = NetworkFilter::parse("||foo.com$domain=~bar.com|~baz.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$domain=~bar.com|~baz.com", true, Default::default()).unwrap(); assert_eq!(filter.opt_domains, None); let mut domains = vec![utils::fast_hash("bar.com"), utils::fast_hash("baz.com")]; domains.sort_unstable(); @@ -2200,7 +2205,7 @@ mod parse_tests { } // parses domain and ~domain { - let filter = NetworkFilter::parse("||foo.com$domain=~bar.com|baz.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$domain=~bar.com|baz.com", true, Default::default()).unwrap(); assert_eq!(filter.opt_domains, Some(vec![utils::fast_hash("baz.com")])); assert_eq!( filter.opt_not_domains, @@ -2208,7 +2213,7 @@ mod parse_tests { ); } { - let filter = NetworkFilter::parse("||foo.com$domain=bar.com|~baz.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$domain=bar.com|~baz.com", true, Default::default()).unwrap(); assert_eq!(filter.opt_domains, Some(vec![utils::fast_hash("bar.com")])); assert_eq!( filter.opt_not_domains, @@ -2216,7 +2221,7 @@ mod parse_tests { ); } { - let filter = NetworkFilter::parse("||foo.com$domain=foo|~bar|baz", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$domain=foo|~bar|baz", true, Default::default()).unwrap(); let mut domains = vec![utils::fast_hash("foo"), utils::fast_hash("baz")]; domains.sort(); assert_eq!(filter.opt_domains, Some(domains)); @@ -2224,7 +2229,7 @@ mod parse_tests { } // defaults to no constraint { - let filter = NetworkFilter::parse("||foo.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com", true, Default::default()).unwrap(); assert_eq!(filter.opt_domains, None); assert_eq!(filter.opt_not_domains, None); } @@ -2232,50 +2237,57 @@ mod parse_tests { #[test] fn parses_redirect_urls() { + let opts = ParseOptions { parse_redirect_urls: true, ..Default::default() }; + { + // No parsing without parse option + let filter = NetworkFilter::parse("||foo.com$redirect-url=http://xyz.com", true, Default::default()); + let err = filter.clone().err(); + assert_eq!(err, Some(NetworkFilterError::UnrecognisedOption)); + } { - let filter = NetworkFilter::parse("||foo.com$redirect-url=http://xyz.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$redirect-url=http://xyz.com", true, opts).unwrap(); assert_eq!(filter.redirect, Some(String::from("http://xyz.com"))); assert_eq!(filter.is_redirect_url(), true); } { - let filter = NetworkFilter::parse("$redirect-url=http://xyz.com", true).unwrap(); + let filter = NetworkFilter::parse("$redirect-url=http://xyz.com", true, opts).unwrap(); assert_eq!(filter.is_redirect_url(), true); assert_eq!(filter.redirect, Some(String::from("http://xyz.com"))); } // parses ~redirect-url { // ~redirect-url is not a valid option - let filter = NetworkFilter::parse("||foo.com$~redirect-url", true); + let filter = NetworkFilter::parse("||foo.com$~redirect-url", true, opts); let err = filter.clone().err(); assert_eq!(err, Some(NetworkFilterError::NegatedRedirection)); } // parses redirect-url without a value { // Not valid - let filter = NetworkFilter::parse("||foo.com$redirect-url", true); + let filter = NetworkFilter::parse("||foo.com$redirect-url", true, opts); let err = filter.clone().err(); assert_eq!(err, Some(NetworkFilterError::EmptyRedirection)); } { - let filter = NetworkFilter::parse("||foo.com$redirect-url=", true); + let filter = NetworkFilter::parse("||foo.com$redirect-url=", true, opts); let err = filter.clone().err(); assert_eq!(err, Some(NetworkFilterError::EmptyRedirection)) } { // Has to be valid URL - let filter = NetworkFilter::parse("||foo.com$redirect-url=xyz.com", true); + let filter = NetworkFilter::parse("||foo.com$redirect-url=xyz.com", true, opts); let err = filter.clone().err(); assert_eq!(err, Some(NetworkFilterError::RedirectionUrlInvalid)) } { // only one between redirect and redirect-url can be specified - let filter = NetworkFilter::parse("||foo.com$redirect=xyz,redirect-url=http://xyz.com", true); + let filter = NetworkFilter::parse("||foo.com$redirect=xyz,redirect-url=http://xyz.com", true, opts); let err = filter.clone().err(); assert_eq!(err, Some(NetworkFilterError::MultipleRedirectionTypes)) } // defaults to false { - let filter = NetworkFilter::parse("||foo.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com", true, opts).unwrap(); assert_eq!(filter.is_redirect_url(), false); assert_eq!(filter.redirect, None); } @@ -2286,32 +2298,32 @@ mod parse_tests { fn parses_redirects() { // parses redirect { - let filter = NetworkFilter::parse("||foo.com$redirect=bar.js", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$redirect=bar.js", true, Default::default()).unwrap(); assert_eq!(filter.redirect, Some(String::from("bar.js"))); } { - let filter = NetworkFilter::parse("$redirect=bar.js", true).unwrap(); + let filter = NetworkFilter::parse("$redirect=bar.js", true, Default::default()).unwrap(); assert_eq!(filter.redirect, Some(String::from("bar.js"))); } // parses ~redirect { // ~redirect is not a valid option - let filter = NetworkFilter::parse("||foo.com$~redirect", true); + let filter = NetworkFilter::parse("||foo.com$~redirect", true, Default::default()); assert_eq!(filter.err(), Some(NetworkFilterError::NegatedRedirection)); } // parses redirect without a value { // Not valid - let filter = NetworkFilter::parse("||foo.com$redirect", true); + let filter = NetworkFilter::parse("||foo.com$redirect", true, Default::default()); assert_eq!(filter.err(), Some(NetworkFilterError::EmptyRedirection)); } { - let filter = NetworkFilter::parse("||foo.com$redirect=", true); + let filter = NetworkFilter::parse("||foo.com$redirect=", true, Default::default()); assert_eq!(filter.err(), Some(NetworkFilterError::EmptyRedirection)) } // defaults to false { - let filter = NetworkFilter::parse("||foo.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com", true, Default::default()).unwrap(); assert_eq!(filter.redirect, None); } } @@ -2320,28 +2332,28 @@ mod parse_tests { fn parses_match_case() { // parses match-case { - let filter = NetworkFilter::parse("||foo.com$match-case", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$match-case", true, Default::default()).unwrap(); assert_eq!(filter.match_case(), true); } { - let filter = NetworkFilter::parse("||foo.com$image,match-case", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$image,match-case", true, Default::default()).unwrap(); assert_eq!(filter.match_case(), true); } { - let filter = NetworkFilter::parse("||foo.com$media,match-case,image", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$media,match-case,image", true, Default::default()).unwrap(); assert_eq!(filter.match_case(), true); } // parses ~match-case { // ~match-case is not supported - let filter = NetworkFilter::parse("||foo.com$~match-case", true); + let filter = NetworkFilter::parse("||foo.com$~match-case", true, Default::default()); assert_eq!(filter.err(), Some(NetworkFilterError::NegatedOptionMatchCase)); } // defaults to false { - let filter = NetworkFilter::parse("||foo.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com", true, Default::default()).unwrap(); assert_eq!(filter.match_case(), false) } } @@ -2350,39 +2362,39 @@ mod parse_tests { fn parses_first_party() { // parses first-party assert_eq!( - NetworkFilter::parse("||foo.com$first-party", true) + NetworkFilter::parse("||foo.com$first-party", true, Default::default()) .unwrap() .first_party(), true ); assert_eq!( - NetworkFilter::parse("@@||foo.com$first-party", true) + NetworkFilter::parse("@@||foo.com$first-party", true, Default::default()) .unwrap() .first_party(), true ); assert_eq!( - NetworkFilter::parse("@@||foo.com|$first-party", true) + NetworkFilter::parse("@@||foo.com|$first-party", true, Default::default()) .unwrap() .first_party(), true ); // parses ~first-party assert_eq!( - NetworkFilter::parse("||foo.com$~first-party", true) + NetworkFilter::parse("||foo.com$~first-party", true, Default::default()) .unwrap() .first_party(), false ); assert_eq!( - NetworkFilter::parse("||foo.com$first-party,~first-party", true) + NetworkFilter::parse("||foo.com$first-party,~first-party", true, Default::default()) .unwrap() .first_party(), false ); // defaults to true assert_eq!( - NetworkFilter::parse("||foo.com", true) + NetworkFilter::parse("||foo.com", true, Default::default()) .unwrap() .first_party(), true @@ -2393,45 +2405,45 @@ mod parse_tests { fn parses_third_party() { // parses third-party assert_eq!( - NetworkFilter::parse("||foo.com$third-party", true) + NetworkFilter::parse("||foo.com$third-party", true, Default::default()) .unwrap() .third_party(), true ); assert_eq!( - NetworkFilter::parse("@@||foo.com$third-party", true) + NetworkFilter::parse("@@||foo.com$third-party", true, Default::default()) .unwrap() .third_party(), true ); assert_eq!( - NetworkFilter::parse("@@||foo.com|$third-party", true) + NetworkFilter::parse("@@||foo.com|$third-party", true, Default::default()) .unwrap() .third_party(), true ); assert_eq!( - NetworkFilter::parse("||foo.com$~first-party", true) + NetworkFilter::parse("||foo.com$~first-party", true, Default::default()) .unwrap() .third_party(), true ); // parses ~third-party assert_eq!( - NetworkFilter::parse("||foo.com$~third-party", true) + NetworkFilter::parse("||foo.com$~third-party", true, Default::default()) .unwrap() .third_party(), false ); assert_eq!( - NetworkFilter::parse("||foo.com$first-party,~third-party", true) + NetworkFilter::parse("||foo.com$first-party,~third-party", true, Default::default()) .unwrap() .third_party(), false ); // defaults to true assert_eq!( - NetworkFilter::parse("||foo.com", true) + NetworkFilter::parse("||foo.com", true, Default::default()) .unwrap() .third_party(), true @@ -2442,24 +2454,24 @@ mod parse_tests { fn parses_bug() { // parses bug { - let filter = NetworkFilter::parse("||foo.com$bug=42", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com$bug=42", true, Default::default()).unwrap(); assert_eq!(filter.has_bug(), true); assert_eq!(filter.bug, Some(42)); } { - let filter = NetworkFilter::parse("@@||foo.com$bug=1337", true).unwrap(); + let filter = NetworkFilter::parse("@@||foo.com$bug=1337", true, Default::default()).unwrap(); assert_eq!(filter.is_exception(), true); assert_eq!(filter.has_bug(), true); assert_eq!(filter.bug, Some(1337)); } { - let filter = NetworkFilter::parse("@@||foo.com|$bug=11111", true).unwrap(); + let filter = NetworkFilter::parse("@@||foo.com|$bug=11111", true, Default::default()).unwrap(); assert_eq!(filter.is_exception(), true); assert_eq!(filter.has_bug(), true); assert_eq!(filter.bug, Some(11111)); } { - let filter = NetworkFilter::parse("@@$bug=11111", true).unwrap(); + let filter = NetworkFilter::parse("@@$bug=11111", true, Default::default()).unwrap(); assert_eq!(filter.is_exception(), true); assert_eq!(filter.has_bug(), true); assert_eq!(filter.bug, Some(11111)); @@ -2467,7 +2479,7 @@ mod parse_tests { // defaults to undefined { - let filter = NetworkFilter::parse("||foo.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com", true, Default::default()).unwrap(); assert_eq!(filter.has_bug(), false); assert_eq!(filter.bug, None); } @@ -2476,27 +2488,27 @@ mod parse_tests { #[test] fn parses_generic_hide() { { - let filter = NetworkFilter::parse("||foo.com$generichide", true); + let filter = NetworkFilter::parse("||foo.com$generichide", true, Default::default()); assert!(filter.is_err()); } { - let filter = NetworkFilter::parse("@@||foo.com$generichide", true).unwrap(); + let filter = NetworkFilter::parse("@@||foo.com$generichide", true, Default::default()).unwrap(); assert_eq!(filter.is_exception(), true); assert_eq!(filter.is_generic_hide(), true); } { - let filter = NetworkFilter::parse("@@||foo.com|$generichide", true).unwrap(); + let filter = NetworkFilter::parse("@@||foo.com|$generichide", true, Default::default()).unwrap(); assert_eq!(filter.is_exception(), true); assert_eq!(filter.is_generic_hide(), true); } { - let filter = NetworkFilter::parse("@@$generichide,domain=example.com", true).unwrap(); + let filter = NetworkFilter::parse("@@$generichide,domain=example.com", true, Default::default()).unwrap(); assert_eq!(filter.is_generic_hide(), true); let breakdown = NetworkFilterBreakdown::from(&filter); assert_eq!(breakdown.opt_domains, Some(vec![utils::fast_hash("example.com")])); } { - let filter = NetworkFilter::parse("||foo.com", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com", true, Default::default()).unwrap(); assert_eq!(filter.is_generic_hide(), false); } } @@ -2549,7 +2561,7 @@ mod parse_tests { ]; for option in options { - let filter = NetworkFilter::parse(&format!("||foo.com${}", option), true); + let filter = NetworkFilter::parse(&format!("||foo.com${}", option), true, Default::default()); assert!(filter.err().is_some()); } } @@ -2608,7 +2620,7 @@ mod parse_tests { for option in options { // positive { - let filter = NetworkFilter::parse(&format!("||foo.com${}", option), true).unwrap(); + let filter = NetworkFilter::parse(&format!("||foo.com${}", option), true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.is_hostname_anchor = true; @@ -2621,7 +2633,7 @@ mod parse_tests { { let filter = - NetworkFilter::parse(&format!("||foo.com$object,{}", option), true).unwrap(); + NetworkFilter::parse(&format!("||foo.com$object,{}", option), true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.is_hostname_anchor = true; @@ -2635,7 +2647,7 @@ mod parse_tests { { let filter = - NetworkFilter::parse(&format!("||foo.com$domain=bar.com,{}", option), true) + NetworkFilter::parse(&format!("||foo.com$domain=bar.com,{}", option), true, Default::default()) .unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); @@ -2650,7 +2662,7 @@ mod parse_tests { // negative { - let filter = NetworkFilter::parse(&format!("||foo.com$~{}", option), true).unwrap(); + let filter = NetworkFilter::parse(&format!("||foo.com$~{}", option), true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.is_hostname_anchor = true; @@ -2663,7 +2675,7 @@ mod parse_tests { { let filter = - NetworkFilter::parse(&format!("||foo.com${},~{}", option, option), true) + NetworkFilter::parse(&format!("||foo.com${},~{}", option, option), true, Default::default()) .unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); @@ -2676,7 +2688,7 @@ mod parse_tests { } // default - positive { - let filter = NetworkFilter::parse(&format!("||foo.com"), true).unwrap(); + let filter = NetworkFilter::parse(&format!("||foo.com"), true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.is_hostname_anchor = true; @@ -2692,7 +2704,7 @@ mod parse_tests { fn binary_serialization_works() { use rmp_serde::{Deserializer, Serializer}; { - let filter = NetworkFilter::parse("||foo.com/bar/baz$important", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com/bar/baz$important", true, Default::default()).unwrap(); let mut encoded = Vec::new(); filter.serialize(&mut Serializer::new(&mut encoded)).unwrap(); @@ -2709,7 +2721,7 @@ mod parse_tests { assert_eq!(defaults, NetworkFilterBreakdown::from(&decoded)) } { - let filter = NetworkFilter::parse("||foo.com*bar^", true).unwrap(); + let filter = NetworkFilter::parse("||foo.com*bar^", true, Default::default()).unwrap(); let mut defaults = default_network_filter_breakdown(); defaults.hostname = Some(String::from("foo.com")); defaults.filter = Some(String::from("bar^")); @@ -2730,7 +2742,7 @@ mod parse_tests { #[test] fn parse_empty_host_anchor_exception() { - let filter_parsed = NetworkFilter::parse("@@||$domain=auth.wi-fi.ru", true); + let filter_parsed = NetworkFilter::parse("@@||$domain=auth.wi-fi.ru", true, Default::default()); assert!(filter_parsed.is_ok()); let filter = filter_parsed.unwrap(); @@ -2835,7 +2847,7 @@ mod match_tests { } fn filter_match_url(filter: &str, url: &str, matching: bool) { - let network_filter = NetworkFilter::parse(filter, true).unwrap(); + let network_filter = NetworkFilter::parse(filter, true, Default::default()).unwrap(); let request = request::Request::from_url(url).unwrap(); assert!( @@ -3017,7 +3029,7 @@ mod match_tests { { let filter = "@@||fastly.net/ad2/$image,script,xmlhttprequest"; let url = "https://0914.global.ssl.fastly.net/ad2/script/x.js?cb=1549980040838"; - let network_filter = NetworkFilter::parse(filter, true).unwrap(); + let network_filter = NetworkFilter::parse(filter, true, Default::default()).unwrap(); let request = request::Request::from_urls( url, "https://www.gamespot.com/metro-exodus/", @@ -3034,7 +3046,7 @@ mod match_tests { { let filter = "@@||swatchseries.to/public/js/edit-show.js$script,domain=swatchseries.to"; let url = "https://www1.swatchseries.to/public/js/edit-show.js"; - let network_filter = NetworkFilter::parse(filter, true).unwrap(); + let network_filter = NetworkFilter::parse(filter, true, Default::default()).unwrap(); let request = request::Request::from_urls( url, "https://www1.swatchseries.to/serie/roswell_new_mexico", @@ -3052,7 +3064,7 @@ mod match_tests { #[test] fn check_ws_vs_http_matching() { - let network_filter = NetworkFilter::parse("|ws://$domain=4shared.com", true).unwrap(); + let network_filter = NetworkFilter::parse("|ws://$domain=4shared.com", true, Default::default()).unwrap(); assert!(network_filter.matches(&request::Request::from_urls("ws://example.com", "https://4shared.com", "websocket").unwrap())); assert!(network_filter.matches(&request::Request::from_urls("wss://example.com", "https://4shared.com", "websocket").unwrap())); @@ -3071,31 +3083,31 @@ mod match_tests { fn check_options_works() { // cpt test { - let network_filter = NetworkFilter::parse("||foo$image", true).unwrap(); + let network_filter = NetworkFilter::parse("||foo$image", true, Default::default()).unwrap(); let request = request::Request::from_urls("https://foo.com/bar", "", "image").unwrap(); assert_eq!(check_options(&network_filter, &request), true); } { - let network_filter = NetworkFilter::parse("||foo$image", true).unwrap(); + let network_filter = NetworkFilter::parse("||foo$image", true, Default::default()).unwrap(); let request = request::Request::from_urls("https://foo.com/bar", "", "script").unwrap(); assert_eq!(check_options(&network_filter, &request), false); } { - let network_filter = NetworkFilter::parse("||foo$~image", true).unwrap(); + let network_filter = NetworkFilter::parse("||foo$~image", true, Default::default()).unwrap(); let request = request::Request::from_urls("https://foo.com/bar", "", "script").unwrap(); assert_eq!(check_options(&network_filter, &request), true); } // ~third-party { - let network_filter = NetworkFilter::parse("||foo$~third-party", true).unwrap(); + let network_filter = NetworkFilter::parse("||foo$~third-party", true, Default::default()).unwrap(); let request = request::Request::from_urls("https://foo.com/bar", "http://baz.foo.com", "") .unwrap(); assert_eq!(check_options(&network_filter, &request), true); } { - let network_filter = NetworkFilter::parse("||foo$~third-party", true).unwrap(); + let network_filter = NetworkFilter::parse("||foo$~third-party", true, Default::default()).unwrap(); let request = request::Request::from_urls("https://foo.com/bar", "http://baz.bar.com", "") .unwrap(); @@ -3104,14 +3116,14 @@ mod match_tests { // ~first-party { - let network_filter = NetworkFilter::parse("||foo$~first-party", true).unwrap(); + let network_filter = NetworkFilter::parse("||foo$~first-party", true, Default::default()).unwrap(); let request = request::Request::from_urls("https://foo.com/bar", "http://baz.bar.com", "") .unwrap(); assert_eq!(check_options(&network_filter, &request), true); } { - let network_filter = NetworkFilter::parse("||foo$~first-party", true).unwrap(); + let network_filter = NetworkFilter::parse("||foo$~first-party", true, Default::default()).unwrap(); let request = request::Request::from_urls("https://foo.com/bar", "http://baz.foo.com", "") .unwrap(); @@ -3120,13 +3132,13 @@ mod match_tests { // opt-domain { - let network_filter = NetworkFilter::parse("||foo$domain=foo.com", true).unwrap(); + let network_filter = NetworkFilter::parse("||foo$domain=foo.com", true, Default::default()).unwrap(); let request = request::Request::from_urls("https://foo.com/bar", "http://foo.com", "").unwrap(); assert_eq!(check_options(&network_filter, &request), true); } { - let network_filter = NetworkFilter::parse("||foo$domain=foo.com", true).unwrap(); + let network_filter = NetworkFilter::parse("||foo$domain=foo.com", true, Default::default()).unwrap(); let request = request::Request::from_urls("https://foo.com/bar", "http://bar.com", "").unwrap(); assert_eq!(check_options(&network_filter, &request), false); @@ -3134,13 +3146,13 @@ mod match_tests { // opt-not-domain { - let network_filter = NetworkFilter::parse("||foo$domain=~bar.com", true).unwrap(); + let network_filter = NetworkFilter::parse("||foo$domain=~bar.com", true, Default::default()).unwrap(); let request = request::Request::from_urls("https://foo.com/bar", "http://foo.com", "").unwrap(); assert_eq!(check_options(&network_filter, &request), true); } { - let network_filter = NetworkFilter::parse("||foo$domain=~bar.com", true).unwrap(); + let network_filter = NetworkFilter::parse("||foo$domain=~bar.com", true, Default::default()).unwrap(); let request = request::Request::from_urls("https://foo.com/bar", "http://bar.com", "").unwrap(); assert_eq!(check_options(&network_filter, &request), false); @@ -3150,7 +3162,7 @@ mod match_tests { #[test] fn check_domain_option_subsetting_works() { { - let network_filter = NetworkFilter::parse("adv$domain=example.com|~foo.example.com", true).unwrap(); + let network_filter = NetworkFilter::parse("adv$domain=example.com|~foo.example.com", true, Default::default()).unwrap(); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://example.com", "").unwrap()) == true); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://foo.example.com", "").unwrap()) == false); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://subfoo.foo.example.com", "").unwrap()) == false); @@ -3158,7 +3170,7 @@ mod match_tests { assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://anotherexample.com", "").unwrap()) == false); } { - let network_filter = NetworkFilter::parse("adv$domain=~example.com|~foo.example.com", true).unwrap(); + let network_filter = NetworkFilter::parse("adv$domain=~example.com|~foo.example.com", true, Default::default()).unwrap(); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://example.com", "").unwrap()) == false); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://foo.example.com", "").unwrap()) == false); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://subfoo.foo.example.com", "").unwrap()) == false); @@ -3166,7 +3178,7 @@ mod match_tests { assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://anotherexample.com", "").unwrap()) == true); } { - let network_filter = NetworkFilter::parse("adv$domain=example.com|foo.example.com", true).unwrap(); + let network_filter = NetworkFilter::parse("adv$domain=example.com|foo.example.com", true, Default::default()).unwrap(); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://example.com", "").unwrap()) == true); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://foo.example.com", "").unwrap()) == true); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://subfoo.foo.example.com", "").unwrap()) == true); @@ -3174,7 +3186,7 @@ mod match_tests { assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://anotherexample.com", "").unwrap()) == false); } { - let network_filter = NetworkFilter::parse("adv$domain=~example.com|foo.example.com", true).unwrap(); + let network_filter = NetworkFilter::parse("adv$domain=~example.com|foo.example.com", true, Default::default()).unwrap(); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://example.com", "").unwrap()) == false); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://foo.example.com", "").unwrap()) == false); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://subfoo.foo.example.com", "").unwrap()) == false); @@ -3182,7 +3194,7 @@ mod match_tests { assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://anotherexample.com", "").unwrap()) == false); } { - let network_filter = NetworkFilter::parse("adv$domain=com|~foo.com", true).unwrap(); + let network_filter = NetworkFilter::parse("adv$domain=com|~foo.com", true, Default::default()).unwrap(); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://com", "").unwrap()) == true); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://foo.com", "").unwrap()) == false); assert!(network_filter.matches(&request::Request::from_urls("http://example.net/adv", "http://subfoo.foo.com", "").unwrap()) == false); @@ -3223,7 +3235,7 @@ mod match_tests { // regex escaping "\/" unrecognised let filter = r#"/^https?:\/\/.*(bitly|bit)\.(com|ly)\/.*/$domain=123movies.com|1337x.to"#; - let network_filter = NetworkFilter::parse(filter, true).unwrap(); + let network_filter = NetworkFilter::parse(filter, true, Default::default()).unwrap(); let url = "https://bit.ly/bar/"; let source = "http://123movies.com"; let request = request::Request::from_urls(url, source, "").unwrap(); @@ -3237,7 +3249,7 @@ mod match_tests { { // regex escaping "\:" unrecognised let filter = r#"/\:\/\/data.*\.com\/[a-zA-Z0-9]{30,}/$third-party,xmlhttprequest"#; - let network_filter = NetworkFilter::parse(filter, true).unwrap(); + let network_filter = NetworkFilter::parse(filter, true, Default::default()).unwrap(); let url = "https://data.foo.com/9VjjrjU9Or2aqkb8PDiqTBnULPgeI48WmYEHkYer"; let source = "http://123movies.com"; let request = request::Request::from_urls(url, source, "xmlhttprequest").unwrap(); @@ -3251,7 +3263,7 @@ mod match_tests { // { let filter = r#"/\.(accountant|bid|click|club|com|cricket|date|download|faith|link|loan|lol|men|online|party|racing|review|science|site|space|stream|top|trade|webcam|website|win|xyz|com)\/(([0-9]{2,9})(\.|\/)(css|\?)?)$/$script,stylesheet,third-party,xmlhttprequest"#; - let network_filter = NetworkFilter::parse(filter, true).unwrap(); + let network_filter = NetworkFilter::parse(filter, true, Default::default()).unwrap(); let url = "https://hello.club/123.css"; let source = "http://123movies.com"; let request = request::Request::from_urls(url, source, "stylesheet").unwrap(); @@ -3269,7 +3281,7 @@ mod match_tests { fn check_lookaround_regex_handled() { { let filter = r#"/^https?:\/\/([0-9a-z\-]+\.)?(9anime|animeland|animenova|animeplus|animetoon|animewow|gamestorrent|goodanime|gogoanime|igg-games|kimcartoon|memecenter|readcomiconline|toonget|toonova|watchcartoononline)\.[a-z]{2,4}\/(?!([Ee]xternal|[Ii]mages|[Ss]cripts|[Uu]ploads|ac|ajax|assets|combined|content|cov|cover|(img\/bg)|(img\/icon)|inc|jwplayer|player|playlist-cat-rss|static|thumbs|wp-content|wp-includes)\/)(.*)/$image,other,script,~third-party,xmlhttprequest,domain=~animeland.hu"#; - let network_filter = NetworkFilter::parse(filter, true).unwrap(); + let network_filter = NetworkFilter::parse(filter, true, Default::default()).unwrap(); let regex = Arc::try_unwrap(network_filter.get_regex()).unwrap(); assert!( matches!(regex, CompiledRegex::Compiled(_)), @@ -3292,7 +3304,7 @@ mod match_tests { fn check_empty_host_anchor_matches() { { let filter = "||$domain=auth.wi-fi.ru"; - let network_filter = NetworkFilter::parse(filter, true).unwrap(); + let network_filter = NetworkFilter::parse(filter, true, Default::default()).unwrap(); let url = "https://example.com/ad.js"; let source = "http://auth.wi-fi.ru"; let request = request::Request::from_urls(url, source, "script").unwrap(); @@ -3305,7 +3317,7 @@ mod match_tests { } { let filter = "@@||$domain=auth.wi-fi.ru"; - let network_filter = NetworkFilter::parse(filter, true).unwrap(); + let network_filter = NetworkFilter::parse(filter, true, Default::default()).unwrap(); let url = "https://example.com/ad.js"; let source = "http://auth.wi-fi.ru"; let request = request::Request::from_urls(url, source, "script").unwrap(); @@ -3322,7 +3334,7 @@ mod match_tests { fn check_url_path_regex_matches() { { let filter = "@@||www.google.com/aclk?*&adurl=$document,~third-party"; - let network_filter = NetworkFilter::parse(filter, true).unwrap(); + let network_filter = NetworkFilter::parse(filter, true, Default::default()).unwrap(); let url = "https://www.google.com/aclk?sa=l&ai=DChcSEwioqMfq5ovjAhVvte0KHXBYDKoYABAJGgJkZw&sig=AOD64_0IL5OYOIkZA7qWOBt0yRmKL4hKJw&ctype=5&q=&ved=0ahUKEwjQ88Hq5ovjAhXYiVwKHWAgB5gQww8IXg&adurl="; let source = "https://www.google.com/aclk?sa=l&ai=DChcSEwioqMfq5ovjAhVvte0KHXBYDKoYABAJGgJkZw&sig=AOD64_0IL5OYOIkZA7qWOBt0yRmKL4hKJw&ctype=5&q=&ved=0ahUKEwjQ88Hq5ovjAhXYiVwKHWAgB5gQww8IXg&adurl="; let request = request::Request::from_urls(url, source, "document").unwrap(); @@ -3336,7 +3348,7 @@ mod match_tests { } { let filter = "@@||www.google.*/aclk?$first-party"; - let network_filter = NetworkFilter::parse(filter, true).unwrap(); + let network_filter = NetworkFilter::parse(filter, true, Default::default()).unwrap(); let url = "https://www.google.com/aclk?sa=l&ai=DChcSEwioqMfq5ovjAhVvte0KHXBYDKoYABAJGgJkZw&sig=AOD64_0IL5OYOIkZA7qWOBt0yRmKL4hKJw&ctype=5&q=&ved=0ahUKEwjQ88Hq5ovjAhXYiVwKHWAgB5gQww8IXg&adurl="; let source = "https://www.google.com/aclk?sa=l&ai=DChcSEwioqMfq5ovjAhVvte0KHXBYDKoYABAJGgJkZw&sig=AOD64_0IL5OYOIkZA7qWOBt0yRmKL4hKJw&ctype=5&q=&ved=0ahUKEwjQ88Hq5ovjAhXYiVwKHWAgB5gQww8IXg&adurl="; let request = request::Request::from_urls(url, source, "main_frame").unwrap(); diff --git a/src/lib.rs b/src/lib.rs index 27e14345..7ba0bca3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,8 @@ #![allow(dead_code)] #![forbid(unsafe_code)] +extern crate url; + // Own modules, currently everything is exposed, will need to limit #[doc(hidden)] pub mod utils; diff --git a/src/lists.rs b/src/lists.rs index 935ca6a9..1f14db3b 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -17,6 +17,23 @@ pub enum RuleTypes { CosmeticOnly, } +/// Put `redirect-url` filter option behind a flag, so we only parse this option for filter lists +/// we trust, given that we're loading arbitrary resources over HTTP +#[derive(Copy, Clone)] +pub struct ParseOptions { + pub format: FilterFormat, + pub parse_redirect_urls: bool, +} + +impl Default for ParseOptions { + fn default() -> Self { + ParseOptions { + format: FilterFormat::Standard, + parse_redirect_urls: false + } + } +} + #[cfg(feature = "content-blocking")] impl Default for RuleTypes { fn default() -> Self { @@ -84,14 +101,26 @@ impl FilterSet { /// Adds the contents of an entire filter list to this `FilterSet`. Filters that cannot be /// parsed successfully are ignored. pub fn add_filter_list(&mut self, filter_list: &str, format: FilterFormat) { + let opts = ParseOptions { format, ..Default::default() }; + self.add_filter_list_with_opts(filter_list, opts); + } + /// Adds the contents of an entire filter list to this `FilterSet` with ParseOptions. + /// Filters that cannot be parsed successfully are ignored. + pub fn add_filter_list_with_opts(&mut self, filter_list: &str, opts: ParseOptions) { let rules = filter_list.lines().map(str::to_string).collect::>(); - self.add_filters(&rules, format); + self.add_filters_with_opts(&rules, opts); } /// Adds a collection of filter rules to this `FilterSet`. Filters that cannot be parsed /// successfully are ignored. pub fn add_filters(&mut self, filters: &[String], format: FilterFormat) { - let (mut parsed_network_filters, mut parsed_cosmetic_filters) = parse_filters(&filters, self.debug, format); + let opts = ParseOptions { format, ..Default::default() }; + self.add_filters_with_opts(filters, opts); + } + /// Adds a collection of filter rules to this `FilterSet` with ParseOptions. + /// Filters that cannot be parsed successfully are ignored. + pub fn add_filters_with_opts(&mut self, filters: &[String], opts: ParseOptions) { + let (mut parsed_network_filters, mut parsed_cosmetic_filters) = parse_filters_with_opts(&filters, self.debug, opts); self.network_filters.append(&mut parsed_network_filters); self.cosmetic_filters.append(&mut parsed_cosmetic_filters); } @@ -230,11 +259,11 @@ impl From for FilterParseError { } } -/// Parse a single filter rule -pub fn parse_filter( +/// Parse a single filter rule with ParseOptions +pub fn parse_filter_with_opts( line: &str, debug: bool, - format: FilterFormat, + opts: ParseOptions, ) -> Result { let filter = line.trim(); @@ -243,10 +272,10 @@ pub fn parse_filter( return Err(FilterParseError::Empty); } - match format { + match opts.format { FilterFormat::Standard => { match detect_filter_type(filter) { - FilterType::Network => NetworkFilter::parse(filter, debug) + FilterType::Network => NetworkFilter::parse(filter, debug, opts) .map(|f| f.into()) .map_err(|e| e.into()), FilterType::Cosmetic => CosmeticFilter::parse(filter, debug) @@ -297,17 +326,28 @@ pub fn parse_filter( } } -/// Parse an entire list of filters, ignoring any errors -pub fn parse_filters( - list: &[String], + +/// Parse a single filter rule +pub fn parse_filter( + line: &str, debug: bool, format: FilterFormat, +) -> Result { + return parse_filter_with_opts(line, debug, ParseOptions {format, ..Default::default()}); + +} + +/// Parse an entire list of filters with ParseOptions, ignoring any errors +pub fn parse_filters_with_opts( + list: &[String], + debug: bool, + opts: ParseOptions, ) -> (Vec, Vec) { let list_iter = list.iter(); let (network_filters, cosmetic_filters): (Vec<_>, Vec<_>) = list_iter - .map(|line| parse_filter(line, debug, format)) + .map(|line| parse_filter_with_opts(line, debug, opts)) .filter_map(Result::ok) .partition_map(|filter| match filter { ParsedFilter::Network(f) => Either::Left(f), @@ -317,6 +357,16 @@ pub fn parse_filters( (network_filters, cosmetic_filters) } +/// Parse an entire list of filters, ignoring any errors +pub fn parse_filters( + list: &[String], + debug: bool, + format: FilterFormat, +) -> (Vec, Vec) { + + return parse_filters_with_opts(list, debug, ParseOptions {format, ..Default::default()}); +} + /// Given a single line, checks if this would likely be a cosmetic filter, a /// network filter or something that is not supported. This check is performed /// before calling a more specific parser to create an instance of diff --git a/tests/legacy_harness.rs b/tests/legacy_harness.rs index 95f7fc88..434c1c48 100644 --- a/tests/legacy_harness.rs +++ b/tests/legacy_harness.rs @@ -11,7 +11,7 @@ mod legacy_test_filters { blocked: &[&'a str], not_blocked: &[&'a str], ) { - let filter_res = NetworkFilter::parse(raw_filter, true); + let filter_res = NetworkFilter::parse(raw_filter, true, Default::default()); assert!( filter_res.is_ok(), "Parsing {} failed: {:?}", @@ -290,7 +290,7 @@ mod legacy_test_filters { ); // explicit, separate testcase construction of the "script" option as it is not the deafult - let filter = NetworkFilter::parse("||googlesyndication.com/safeframe/$third-party,script", true).unwrap(); + let filter = NetworkFilter::parse("||googlesyndication.com/safeframe/$third-party,script", true, Default::default()).unwrap(); let request = Request::from_urls("http://tpc.googlesyndication.com/safeframe/1-0-2/html/container.html#xpc=sf-gdn-exp-2&p=http%3A//slashdot.org;", "", "script").unwrap(); assert!(filter.matches(&request)); } @@ -656,13 +656,13 @@ mod legacy_misc_tests { #[test] fn host_anchored_filters_parse_correctly() { // Host anchor is calculated correctly - let filter = NetworkFilter::parse("||test.com$third-party", false).unwrap(); + let filter = NetworkFilter::parse("||test.com$third-party", false, Default::default()).unwrap(); assert_eq!(filter.hostname, Some(String::from("test.com"))); - let filter = NetworkFilter::parse("||test.com/ok$third-party", false).unwrap(); + let filter = NetworkFilter::parse("||test.com/ok$third-party", false, Default::default()).unwrap(); assert_eq!(filter.hostname, Some(String::from("test.com"))); - let filter = NetworkFilter::parse("||test.com/ok", false).unwrap(); + let filter = NetworkFilter::parse("||test.com/ok", false, Default::default()).unwrap(); assert_eq!(filter.hostname, Some(String::from("test.com"))); } diff --git a/tests/matching.rs b/tests/matching.rs index a36b62fb..65dc8105 100644 --- a/tests/matching.rs +++ b/tests/matching.rs @@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize}; use std::fs::File; use std::io::prelude::*; use adblock::blocker::RedirectType; +use adblock::lists::ParseOptions; #[allow(non_snake_case)] #[derive(Serialize, Deserialize)] @@ -32,7 +33,7 @@ fn load_requests() -> Vec { fn build_resources_from_filters(filters: &[String]) -> Vec { filters.iter() - .map(|r| NetworkFilter::parse(&r, true)) + .map(|r| NetworkFilter::parse(&r, true, Default::default())) .filter_map(Result::ok) .filter(|f| f.is_redirect()) .map(|f| { @@ -57,11 +58,16 @@ fn check_filter_matching() { assert!(requests.len() > 0, "List of parsed request info is empty"); + let opts = ParseOptions { + parse_redirect_urls: true, + ..Default::default() + }; + for req in requests { for filter in req.filters { - let nework_filter_res = NetworkFilter::parse(&filter, true); - assert!(nework_filter_res.is_ok(), "Could not parse filter {}", filter); - let network_filter = nework_filter_res.unwrap(); + let network_filter_res = NetworkFilter::parse(&filter, true, opts); + assert!(network_filter_res.is_ok(), "Could not parse filter {}", filter); + let network_filter = network_filter_res.unwrap(); let request_res = Request::from_urls(&req.url, &req.sourceUrl, &req.r#type); // The dataset has cases where URL is set to just "http://" or "https://", which we do not support @@ -87,13 +93,14 @@ fn check_engine_matching() { continue; } for filter in req.filters { - let mut engine = Engine::from_rules_debug(&[filter.clone()], adblock::lists::FilterFormat::Standard); + let opts = ParseOptions { parse_redirect_urls: true, ..Default::default() }; + let mut engine = Engine::from_rules_debug_with_opts(&[filter.clone()], opts); let resources = build_resources_from_filters(&[filter.clone()]); engine.use_resources(&resources); - let nework_filter_res = NetworkFilter::parse(&filter, true); - assert!(nework_filter_res.is_ok(), "Could not parse filter {}", filter); - let network_filter = nework_filter_res.unwrap(); + let network_filter_res = NetworkFilter::parse(&filter, true, opts); + assert!(network_filter_res.is_ok(), "Could not parse filter {}", filter); + let network_filter = network_filter_res.unwrap(); let result = engine.check_network_urls(&req.url, &req.sourceUrl, &req.r#type); @@ -124,8 +131,6 @@ fn check_engine_matching() { assert!(resource.contains("base64")); } } - - } } } diff --git a/tests/ublock-coverage.rs b/tests/ublock-coverage.rs index 4ebcfe1f..16f48a1d 100644 --- a/tests/ublock-coverage.rs +++ b/tests/ublock-coverage.rs @@ -7,6 +7,7 @@ use serde::Deserialize; use std::collections::HashMap; use std::fs::File; use std::io::BufReader; +use adblock::blocker::RedirectType; #[allow(non_snake_case)] #[derive(Debug, Deserialize)] @@ -98,7 +99,7 @@ fn check_specific_rules() { let checked = engine.check_network_urls("http://cdn.taboola.com/libtrc/test/loader.js", "http://cnet.com", "script"); assert_eq!(checked.matched, true); - assert_eq!(checked.redirect, Some("data:application/javascript;base64,KGZ1bmN0aW9uKCkgewogICAgJ3VzZSBzdHJpY3QnOwp9KSgpOwo=".to_owned())); + assert_eq!(checked.redirect, Some(RedirectType::Url("data:application/javascript;base64,KGZ1bmN0aW9uKCkgewogICAgJ3VzZSBzdHJpY3QnOwp9KSgpOwo=".to_owned()))); } }