From d6e359c271fdba9aaf5d323e0f8334a7eef0aea7 Mon Sep 17 00:00:00 2001 From: gvozdvmozgu Date: Mon, 27 Apr 2026 10:36:42 -0700 Subject: [PATCH 1/6] Prepare code for Rust 2024 edition --- benches/bench_memory.rs | 50 +++++++++------- js/src/lib.rs | 58 +++++++++---------- src/url_parser/parser.rs | 2 +- tests/test_utils.rs | 2 +- .../containers/test_containers_generated.rs | 22 ++++--- 5 files changed, 71 insertions(+), 63 deletions(-) diff --git a/benches/bench_memory.rs b/benches/bench_memory.rs index 8b7320e4..84a795f7 100644 --- a/benches/bench_memory.rs +++ b/benches/bench_memory.rs @@ -73,39 +73,47 @@ impl MemoryTracker { unsafe impl GlobalAlloc for MemoryTracker { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - let ret = self.internal.alloc(layout); - if !ret.is_null() { - self.allocations_count.fetch_add(1, Ordering::SeqCst); - self.allocated.fetch_add(layout.size(), Ordering::SeqCst); - self.update_max_allocated(self.current_usage()); + unsafe { + let ret = self.internal.alloc(layout); + if !ret.is_null() { + self.allocations_count.fetch_add(1, Ordering::SeqCst); + self.allocated.fetch_add(layout.size(), Ordering::SeqCst); + self.update_max_allocated(self.current_usage()); + } + ret } - ret } unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - self.internal.dealloc(ptr, layout); - self.allocated.fetch_sub(layout.size(), Ordering::SeqCst); + unsafe { + self.internal.dealloc(ptr, layout); + self.allocated.fetch_sub(layout.size(), Ordering::SeqCst); + } } unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - let ret = self.internal.realloc(ptr, layout, new_size); - if !ret.is_null() { - self.allocations_count.fetch_add(1, Ordering::SeqCst); - self.allocated.fetch_sub(layout.size(), Ordering::SeqCst); - self.allocated.fetch_add(new_size, Ordering::SeqCst); - self.update_max_allocated(self.current_usage()); + unsafe { + let ret = self.internal.realloc(ptr, layout, new_size); + if !ret.is_null() { + self.allocations_count.fetch_add(1, Ordering::SeqCst); + self.allocated.fetch_sub(layout.size(), Ordering::SeqCst); + self.allocated.fetch_add(new_size, Ordering::SeqCst); + self.update_max_allocated(self.current_usage()); + } + ret } - ret } unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - let ret = self.internal.alloc_zeroed(layout); - if !ret.is_null() { - self.allocations_count.fetch_add(1, Ordering::SeqCst); - self.allocated.fetch_add(layout.size(), Ordering::SeqCst); - self.update_max_allocated(self.current_usage()); + unsafe { + let ret = self.internal.alloc_zeroed(layout); + if !ret.is_null() { + self.allocations_count.fetch_add(1, Ordering::SeqCst); + self.allocated.fetch_add(layout.size(), Ordering::SeqCst); + self.update_max_allocated(self.current_usage()); + } + ret } - ret } } diff --git a/js/src/lib.rs b/js/src/lib.rs index 3809ac8f..392802ba 100644 --- a/js/src/lib.rs +++ b/js/src/lib.rs @@ -200,10 +200,9 @@ fn engine_check(mut cx: FunctionContext) -> JsResult { Err(e) => cx.throw_error(e.to_string())?, }; - let result = if let Ok(engine) = this.0.lock() { - engine.check_network_request(&request) - } else { - cx.throw_error("Failed to acquire lock on engine")? + let result = match this.0.lock() { + Ok(engine) => engine.check_network_request(&request), + _ => cx.throw_error("Failed to acquire lock on engine")?, }; if debug { json_ffi::to_js(&mut cx, &result) @@ -224,10 +223,9 @@ fn engine_hidden_class_id_selectors(mut cx: FunctionContext) -> JsResult(3)?; let exceptions: std::collections::HashSet = json_ffi::from_js(&mut cx, exceptions_arg)?; - let result = if let Ok(engine) = this.0.lock() { - engine.hidden_class_id_selectors(&classes, &ids, &exceptions) - } else { - cx.throw_error("Failed to acquire lock on engine")? + let result = match this.0.lock() { + Ok(engine) => engine.hidden_class_id_selectors(&classes, &ids, &exceptions), + _ => cx.throw_error("Failed to acquire lock on engine")?, }; json_ffi::to_js(&mut cx, &result) } @@ -237,20 +235,18 @@ fn engine_url_cosmetic_resources(mut cx: FunctionContext) -> JsResult { let url: String = cx.argument::(1)?.value(&mut cx); - let result = if let Ok(engine) = this.0.lock() { - engine.url_cosmetic_resources(&url) - } else { - cx.throw_error("Failed to acquire lock on engine")? + let result = match this.0.lock() { + Ok(engine) => engine.url_cosmetic_resources(&url), + _ => cx.throw_error("Failed to acquire lock on engine")?, }; json_ffi::to_js(&mut cx, &result) } fn engine_serialize(mut cx: FunctionContext) -> JsResult { let this = cx.argument::>(0)?; - let serialized = if let Ok(engine) = this.0.lock() { - engine.serialize().to_vec() - } else { - cx.throw_error("Failed to acquire lock on engine")? + let serialized = match this.0.lock() { + Ok(engine) => engine.serialize().to_vec(), + _ => cx.throw_error("Failed to acquire lock on engine")?, }; // initialise new Array Buffer in the JS context @@ -277,10 +273,9 @@ fn engine_enable_tag(mut cx: FunctionContext) -> JsResult { let tag: String = cx.argument::(1)?.value(&mut cx); - if let Ok(mut engine) = this.0.lock() { - engine.enable_tags(&[&tag]) - } else { - cx.throw_error("Failed to acquire lock on engine")? + match this.0.lock() { + Ok(mut engine) => engine.enable_tags(&[&tag]), + _ => cx.throw_error("Failed to acquire lock on engine")?, }; Ok(JsNull::new(&mut cx)) } @@ -291,10 +286,9 @@ fn engine_use_resources(mut cx: FunctionContext) -> JsResult { let resources_arg = cx.argument::(1)?; let resources: Vec = json_ffi::from_js(&mut cx, resources_arg)?; - if let Ok(mut engine) = this.0.lock() { - engine.use_resources(resources) - } else { - cx.throw_error("Failed to acquire lock on engine")? + match this.0.lock() { + Ok(mut engine) => engine.use_resources(resources), + _ => cx.throw_error("Failed to acquire lock on engine")?, }; Ok(JsNull::new(&mut cx)) } @@ -304,10 +298,9 @@ fn engine_tag_exists(mut cx: FunctionContext) -> JsResult { let tag: String = cx.argument::(1)?.value(&mut cx); - let result = if let Ok(engine) = this.0.lock() { - engine.tag_exists(&tag) - } else { - cx.throw_error("Failed to acquire lock on engine")? + let result = match this.0.lock() { + Ok(engine) => engine.tag_exists(&tag), + _ => cx.throw_error("Failed to acquire lock on engine")?, }; Ok(cx.boolean(result)) } @@ -315,10 +308,11 @@ fn engine_tag_exists(mut cx: FunctionContext) -> JsResult { fn engine_clear_tags(mut cx: FunctionContext) -> JsResult { let this = cx.argument::>(0)?; - if let Ok(mut engine) = this.0.lock() { - engine.use_tags(&[]); - } else { - cx.throw_error("Failed to acquire lock on engine")? + match this.0.lock() { + Ok(mut engine) => { + engine.use_tags(&[]); + } + _ => cx.throw_error("Failed to acquire lock on engine")?, }; Ok(JsNull::new(&mut cx)) } diff --git a/src/url_parser/parser.rs b/src/url_parser/parser.rs index 66bcd485..c623c2f5 100644 --- a/src/url_parser/parser.rs +++ b/src/url_parser/parser.rs @@ -153,7 +153,7 @@ impl RangeArg for RangeTo { pub type ParseResult = Result; macro_rules! simple_enum_error { - ($($name: ident => $description: expr,)+) => { + ($($name: ident => $description: expr_2021,)+) => { /// Errors that can occur during parsing. #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub enum ParseError { diff --git a/tests/test_utils.rs b/tests/test_utils.rs index a4e3a3db..6cc27fbc 100644 --- a/tests/test_utils.rs +++ b/tests/test_utils.rs @@ -5,7 +5,7 @@ pub fn rules_from_lists( lists: impl IntoIterator>, ) -> impl Iterator { - fn read_file_lines(filename: &str) -> impl Iterator { + fn read_file_lines(filename: &str) -> impl Iterator + use<> { use std::fs::File; use std::io::{BufRead, BufReader}; diff --git a/tests/unit/flatbuffers/containers/test_containers_generated.rs b/tests/unit/flatbuffers/containers/test_containers_generated.rs index 75ee889d..423c4258 100644 --- a/tests/unit/flatbuffers/containers/test_containers_generated.rs +++ b/tests/unit/flatbuffers/containers/test_containers_generated.rs @@ -28,8 +28,10 @@ pub mod fb_test { type Inner = TestUIntMap<'a>; #[inline] unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { - _tab: flatbuffers::Table::new(buf, loc), + unsafe { + Self { + _tab: flatbuffers::Table::new(buf, loc), + } } } } @@ -223,8 +225,10 @@ pub mod fb_test { type Inner = TestStringMap<'a>; #[inline] unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { - _tab: flatbuffers::Table::new(buf, loc), + unsafe { + Self { + _tab: flatbuffers::Table::new(buf, loc), + } } } } @@ -428,8 +432,10 @@ pub mod fb_test { type Inner = TestRoot<'a>; #[inline] unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { - _tab: flatbuffers::Table::new(buf, loc), + unsafe { + Self { + _tab: flatbuffers::Table::new(buf, loc), + } } } } @@ -758,14 +764,14 @@ pub mod fb_test { /// # Safety /// Callers must trust the given bytes do indeed contain a valid `TestRoot`. pub unsafe fn root_as_test_root_unchecked(buf: &[u8]) -> TestRoot { - flatbuffers::root_unchecked::(buf) + unsafe { flatbuffers::root_unchecked::(buf) } } #[inline] /// Assumes, without verification, that a buffer of bytes contains a size prefixed TestRoot and returns it. /// # Safety /// Callers must trust the given bytes do indeed contain a valid size prefixed `TestRoot`. pub unsafe fn size_prefixed_root_as_test_root_unchecked(buf: &[u8]) -> TestRoot { - flatbuffers::size_prefixed_root_unchecked::(buf) + unsafe { flatbuffers::size_prefixed_root_unchecked::(buf) } } #[inline] pub fn finish_test_root_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( From f4e3b31efd28222c728bd52bc96b6f738a5e66c0 Mon Sep 17 00:00:00 2001 From: gvozdvmozgu Date: Mon, 27 Apr 2026 10:38:42 -0700 Subject: [PATCH 2/6] Switch workspace crates to Rust 2024 --- Cargo.toml | 2 +- fuzz/Cargo.toml | 2 +- js/Cargo.toml | 2 +- src/filters/cosmetic.rs | 11 ++++++++--- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ea19129c..555c9756 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "adblock" version = "0.12.2" authors = ["Anton Lazarev ", "Andrius Aucinas"] -edition = "2021" +edition = "2024" description = "Native Rust module for Adblock Plus syntax (e.g. EasyList, EasyPrivacy) filter parsing and matching." repository = "https://github.com/brave/adblock-rust/" diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index c17fa267..c462981b 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -3,7 +3,7 @@ name = "adblock-fuzz" version = "0.0.0" authors = ["Automatically generated"] publish = false -edition = "2021" +edition = "2024" [package.metadata] cargo-fuzz = true diff --git a/js/Cargo.toml b/js/Cargo.toml index 60fdf8d8..d41750a1 100644 --- a/js/Cargo.toml +++ b/js/Cargo.toml @@ -2,7 +2,7 @@ name = "adblock-rs" version = "0.12.2" authors = ["Anton Lazarev ", "Andrius Aucinas"] -edition = "2021" +edition = "2024" license = "MPL-2.0" exclude = ["artifacts.json", "index.node"] diff --git a/src/filters/cosmetic.rs b/src/filters/cosmetic.rs index 37ea8970..73d72c21 100644 --- a/src/filters/cosmetic.rs +++ b/src/filters/cosmetic.rs @@ -863,11 +863,16 @@ mod css_validation { arguments: &mut Parser<'i, '_>, ) -> Result>> { let mut inner = String::new(); - while let Ok(arg) = arguments.next_including_whitespace() { + loop { + let arg = match arguments.next_including_whitespace() { + Ok(arg) => arg, + Err(_) => break, + }; if arg.to_css(&mut inner).is_err() { return Err(arguments.new_custom_error(SelectorParseErrorKind::InvalidState)); }; - if let Some(closing_token) = nested_matching_close(arg) { + let closing_token = nested_matching_close(arg); + if let Some(closing_token) = closing_token { let nested = arguments.parse_nested_block(to_css_nested)?; inner.push_str(&nested); closing_token.to_css(&mut inner).map_err(|_| { @@ -962,7 +967,7 @@ mod css_validation { | "remove-attr" | "remove-class" => { return Err(arguments.new_custom_error( SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name), - )) + )); } _ => (), } From d0bc857d539d039970971fc20bdc8c8cec88aa2e Mon Sep 17 00:00:00 2001 From: gvozdvmozgu Date: Mon, 27 Apr 2026 10:39:00 -0700 Subject: [PATCH 3/6] Format Rust code with edition 2024 --- benches/bench_memory.rs | 2 +- benches/bench_redirect_performance.rs | 3 +- benches/bench_regex.rs | 2 +- examples/deserialization.rs | 4 +- examples/example.rs | 2 +- examples/generate-dat.rs | 2 +- examples/use-dat.rs | 2 +- fuzz/fuzz_targets/parse_filter_hosts.rs | 2 +- js/src/lib.rs | 4 +- src/blocker.rs | 2 +- src/content_blocking.rs | 8 +- src/cosmetic_filter_cache.rs | 2 +- src/cosmetic_filter_cache_builder.rs | 2 +- src/engine.rs | 2 +- src/filters/abstract_network.rs | 2 +- src/filters/fb_network_builder.rs | 2 +- src/filters/token_selector.rs | 2 +- src/network_filter_list.rs | 2 +- src/regex_manager.rs | 4 +- src/url_parser/parser.rs | 2 +- tests/legacy_harness.rs | 8 +- tests/live.rs | 12 +- tests/matching.rs | 4 +- tests/simple_use.rs | 2 +- tests/ublock-coverage.rs | 2 +- tests/unit/blocker.rs | 38 ++-- tests/unit/content_blocking.rs | 28 ++- tests/unit/engine.rs | 22 +- tests/unit/filters/cosmetic.rs | 45 ++-- tests/unit/filters/network.rs | 58 +++--- tests/unit/filters/network_matchers.rs | 230 +++++++++++++-------- tests/unit/optimizer.rs | 64 +++--- tests/unit/regex_manager.rs | 2 +- tests/unit/resources/resource_assembler.rs | 21 +- tests/unit/resources/resource_storage.rs | 82 +++++--- 35 files changed, 406 insertions(+), 265 deletions(-) diff --git a/benches/bench_memory.rs b/benches/bench_memory.rs index 84a795f7..866255a6 100644 --- a/benches/bench_memory.rs +++ b/benches/bench_memory.rs @@ -8,9 +8,9 @@ use serde::{Deserialize, Serialize}; use std::alloc::{GlobalAlloc, Layout, System}; use std::sync::atomic::{AtomicUsize, Ordering}; +use adblock::Engine; use adblock::request::Request; use adblock::resources::Resource; -use adblock::Engine; #[path = "../tests/test_utils.rs"] mod test_utils; diff --git a/benches/bench_redirect_performance.rs b/benches/bench_redirect_performance.rs index 1ef2dbc2..f4db2dcf 100644 --- a/benches/bench_redirect_performance.rs +++ b/benches/bench_redirect_performance.rs @@ -6,8 +6,7 @@ use adblock::filters::network::{NetworkFilter, NetworkFilterMask, NetworkFilterM use adblock::request::Request; use adblock::resources::Resource; -const DEFAULT_LISTS_URL: &str = - "https://raw.githubusercontent.com/brave/adblock-resources/master/filter_lists/list_catalog.json"; +const DEFAULT_LISTS_URL: &str = "https://raw.githubusercontent.com/brave/adblock-resources/master/filter_lists/list_catalog.json"; async fn get_all_filters() -> Vec { use futures::FutureExt; diff --git a/benches/bench_regex.rs b/benches/bench_regex.rs index b03c1531..54f6c871 100644 --- a/benches/bench_regex.rs +++ b/benches/bench_regex.rs @@ -1,6 +1,6 @@ use criterion::*; -use regex::{bytes::Regex as BytesRegex, Regex, RegexSet}; +use regex::{Regex, RegexSet, bytes::Regex as BytesRegex}; fn bench_simple_regexes(c: &mut Criterion) { let mut group = c.benchmark_group("regex"); diff --git a/examples/deserialization.rs b/examples/deserialization.rs index 3ef07a72..0dda6094 100644 --- a/examples/deserialization.rs +++ b/examples/deserialization.rs @@ -1,11 +1,11 @@ -use adblock::{request::Request, Engine}; +use adblock::{Engine, request::Request}; use serde::Deserialize; use std::collections::HashMap; use std::fs::File; -use std::io::prelude::*; use std::io::BufReader; +use std::io::prelude::*; #[allow(non_snake_case)] #[derive(Debug, Deserialize)] diff --git a/examples/example.rs b/examples/example.rs index 9f2f74ac..f6440982 100644 --- a/examples/example.rs +++ b/examples/example.rs @@ -1,7 +1,7 @@ use adblock::{ + Engine, lists::{FilterSet, ParseOptions}, request::Request, - Engine, }; fn main() { diff --git a/examples/generate-dat.rs b/examples/generate-dat.rs index 513db3f7..d52b8c99 100644 --- a/examples/generate-dat.rs +++ b/examples/generate-dat.rs @@ -1,4 +1,4 @@ -use adblock::{request::Request, Engine}; +use adblock::{Engine, request::Request}; use std::fs::File; use std::io::prelude::*; diff --git a/examples/use-dat.rs b/examples/use-dat.rs index bc662d71..101d8fab 100644 --- a/examples/use-dat.rs +++ b/examples/use-dat.rs @@ -1,4 +1,4 @@ -use adblock::{request::Request, Engine}; +use adblock::{Engine, request::Request}; use std::fs::File; use std::io::prelude::*; diff --git a/fuzz/fuzz_targets/parse_filter_hosts.rs b/fuzz/fuzz_targets/parse_filter_hosts.rs index 247fced4..9cb2e263 100644 --- a/fuzz/fuzz_targets/parse_filter_hosts.rs +++ b/fuzz/fuzz_targets/parse_filter_hosts.rs @@ -1,7 +1,7 @@ #![no_main] #![allow(unused_must_use)] // workaround for "error: unused `Result` that must be used" -use adblock::lists::{parse_filter, FilterFormat, ParseOptions}; +use adblock::lists::{FilterFormat, ParseOptions, parse_filter}; use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { diff --git a/js/src/lib.rs b/js/src/lib.rs index 392802ba..aa1fb5af 100644 --- a/js/src/lib.rs +++ b/js/src/lib.rs @@ -1,9 +1,9 @@ +use adblock::Engine as EngineInternal; use adblock::lists::{ FilterFormat, FilterListMetadata, FilterSet as FilterSetInternal, ParseOptions, RuleTypes, }; -use adblock::resources::resource_assembler::assemble_web_accessible_resources; use adblock::resources::Resource; -use adblock::Engine as EngineInternal; +use adblock::resources::resource_assembler::assemble_web_accessible_resources; use neon::prelude::*; use neon::types::buffer::TypedArray as _; use serde::{Deserialize, Serialize}; diff --git a/src/blocker.rs b/src/blocker.rs index da9f775e..4805fd87 100644 --- a/src/blocker.rs +++ b/src/blocker.rs @@ -456,8 +456,8 @@ impl Blocker { network_filters: Vec, options: &BlockerOptions, ) -> Self { - use crate::engine::Engine; use crate::FilterSet; + use crate::engine::Engine; let mut filter_set = FilterSet::new(true); filter_set.network_filters = network_filters; diff --git a/src/content_blocking.rs b/src/content_blocking.rs index 128d202f..2489aac1 100644 --- a/src/content_blocking.rs +++ b/src/content_blocking.rs @@ -241,11 +241,7 @@ impl TryFrom for CbRuleEquivalent { } fn non_empty(v: Vec) -> Option> { - if !v.is_empty() { - Some(v) - } else { - None - } + if !v.is_empty() { Some(v) } else { None } } /// Some adblock rules cannot be directly represented by a single content blocking rule. This enum @@ -347,7 +343,7 @@ impl TryFrom for CbRuleEquivalent { let url_filter = match (v.filter, v.hostname) { (crate::filters::network::FilterPart::AnyOf(_), _) => { - return Err(CbRuleCreationFailure::OptimizedRulesUnsupported) + return Err(CbRuleCreationFailure::OptimizedRulesUnsupported); } (crate::filters::network::FilterPart::Simple(part), Some(hostname)) => { let without_trailing_separator = TRAILING_SEPARATOR.replace_all(&part, ""); diff --git a/src/cosmetic_filter_cache.rs b/src/cosmetic_filter_cache.rs index d60b37a5..43c4209e 100644 --- a/src/cosmetic_filter_cache.rs +++ b/src/cosmetic_filter_cache.rs @@ -135,8 +135,8 @@ impl CosmeticFilterCache { #[cfg(test)] pub fn from_rules(rules: Vec) -> Self { - use crate::engine::Engine; use crate::FilterSet; + use crate::engine::Engine; let mut filter_set = FilterSet::new(true); filter_set.cosmetic_filters = rules; diff --git a/src/cosmetic_filter_cache_builder.rs b/src/cosmetic_filter_cache_builder.rs index 8ee3ed01..318c73fb 100644 --- a/src/cosmetic_filter_cache_builder.rs +++ b/src/cosmetic_filter_cache_builder.rs @@ -14,7 +14,7 @@ use crate::flatbuffers::containers::hash_map::HashMapBuilder; use crate::flatbuffers::containers::hash_set::HashSetBuilder; use crate::flatbuffers::containers::flat_serialize::{ - serialize_vec_opt, FlatBuilder, FlatSerialize, + FlatBuilder, FlatSerialize, serialize_vec_opt, }; use crate::utils::Hash; diff --git a/src/engine.rs b/src/engine.rs index 7867e0cd..1fad31d1 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -3,7 +3,7 @@ use crate::blocker::{Blocker, BlockerResult}; use crate::cosmetic_filter_cache::{CosmeticFilterCache, UrlSpecificResources}; use crate::cosmetic_filter_cache_builder::CosmeticFilterCacheBuilder; -use crate::data_format::{deserialize_dat_file, serialize_dat_file, DeserializationError}; +use crate::data_format::{DeserializationError, deserialize_dat_file, serialize_dat_file}; use crate::filters::cosmetic::CosmeticFilter; use crate::filters::fb_builder::EngineFlatBuilder; use crate::filters::fb_network_builder::NetworkRulesBuilder; diff --git a/src/filters/abstract_network.rs b/src/filters/abstract_network.rs index b97c9b33..290df5a0 100644 --- a/src/filters/abstract_network.rs +++ b/src/filters/abstract_network.rs @@ -229,7 +229,7 @@ fn parse_filter_options(raw_options: &str) -> Result, N NetworkFilterOption::Removeparam(String::from(value)) } ("generichide", true) | ("ghide", true) => { - return Err(NetworkFilterError::NegatedGenericHide) + return Err(NetworkFilterError::NegatedGenericHide); } ("generichide", false) | ("ghide", false) => NetworkFilterOption::Generichide, ("document", true) | ("doc", true) => return Err(NetworkFilterError::NegatedDocument), diff --git a/src/filters/fb_network_builder.rs b/src/filters/fb_network_builder.rs index 115bcbcc..6b4acc43 100644 --- a/src/filters/fb_network_builder.rs +++ b/src/filters/fb_network_builder.rs @@ -13,7 +13,7 @@ use crate::filters::network::NetworkFilterMaskHelper; use crate::flatbuffers::containers::flat_multimap::FlatMultiMapBuilder; use crate::flatbuffers::containers::flat_serialize::{FlatBuilder, FlatSerialize, WIPFlatVec}; use crate::optimizer; -use crate::utils::{to_short_hash, Hash, ShortHash}; +use crate::utils::{Hash, ShortHash, to_short_hash}; use super::flat::fb; diff --git a/src/filters/token_selector.rs b/src/filters/token_selector.rs index 980ca133..2b3555bc 100644 --- a/src/filters/token_selector.rs +++ b/src/filters/token_selector.rs @@ -1,6 +1,6 @@ //! Token selector for optimizing filter storage by choosing least-used tokens -use crate::utils::{to_short_hash, Hash, ShortHash}; +use crate::utils::{Hash, ShortHash, to_short_hash}; use seahash::SeaHasher; use std::collections::HashMap; use std::hash::BuildHasherDefault; diff --git a/src/network_filter_list.rs b/src/network_filter_list.rs index 4e642061..31f7f6ce 100644 --- a/src/network_filter_list.rs +++ b/src/network_filter_list.rs @@ -14,7 +14,7 @@ use crate::flatbuffers::containers::flat_multimap::FlatMultiMapView; use crate::flatbuffers::unsafe_tools::fb_vector_to_slice; use crate::regex_manager::RegexManager; use crate::request::Request; -use crate::utils::{to_short_hash, ShortHash}; +use crate::utils::{ShortHash, to_short_hash}; /// Holds relevant information from a single matchin gnetwork filter rule as a result of querying a /// [NetworkFilterList] for a given request. diff --git a/src/regex_manager.rs b/src/regex_manager.rs index c0c9a924..03d554f3 100644 --- a/src/regex_manager.rs +++ b/src/regex_manager.rs @@ -5,8 +5,8 @@ use crate::filters::network::{NetworkFilterMask, NetworkFilterMaskHelper}; use regex::{ - bytes::Regex as BytesRegex, bytes::RegexBuilder as BytesRegexBuilder, - bytes::RegexSet as BytesRegexSet, bytes::RegexSetBuilder as BytesRegexSetBuilder, Regex, + Regex, bytes::Regex as BytesRegex, bytes::RegexBuilder as BytesRegexBuilder, + bytes::RegexSet as BytesRegexSet, bytes::RegexSetBuilder as BytesRegexSetBuilder, }; use std::sync::LazyLock; diff --git a/src/url_parser/parser.rs b/src/url_parser/parser.rs index c623c2f5..c46e3648 100644 --- a/src/url_parser/parser.rs +++ b/src/url_parser/parser.rs @@ -9,7 +9,7 @@ use std::error::Error; use std::fmt::{self, Formatter, Write}; -use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; +use percent_encoding::{AsciiSet, CONTROLS, utf8_percent_encode}; use std::ops::{Range, RangeFrom, RangeTo}; /// https://url.spec.whatwg.org/#fragment-percent-encode-set diff --git a/tests/legacy_harness.rs b/tests/legacy_harness.rs index 1cb133d6..4e0e81c3 100644 --- a/tests/legacy_harness.rs +++ b/tests/legacy_harness.rs @@ -1,8 +1,8 @@ mod legacy_test_filters { + use adblock::Engine; use adblock::filters::network::NetworkFilter; use adblock::filters::network::NetworkFilterMask; use adblock::request::Request; - use adblock::Engine; fn test_filter<'a>( raw_filter: &str, @@ -315,8 +315,8 @@ mod legacy_test_filters { } mod legacy_check_match { - use adblock::request::Request; use adblock::Engine; + use adblock::request::Request; fn check_match<'a>( rules: &[&'a str], @@ -501,8 +501,8 @@ mod legacy_check_match { } mod legacy_check_options { - use adblock::request::Request; use adblock::Engine; + use adblock::request::Request; fn check_option_rule<'a>(rules: &[&'a str], tests: &[(&'a str, &'a str, &'a str, bool)]) { let engine = Engine::from_rules(rules, Default::default()); // first one with the provided rules @@ -844,9 +844,9 @@ mod legacy_check_options { } mod legacy_misc_tests { + use adblock::Engine; use adblock::filters::network::NetworkFilter; use adblock::request::Request; - use adblock::Engine; #[test] fn demo_app() { diff --git a/tests/live.rs b/tests/live.rs index 444a31dc..5c59b834 100644 --- a/tests/live.rs +++ b/tests/live.rs @@ -1,5 +1,5 @@ -use adblock::request::Request; use adblock::Engine; +use adblock::request::Request; use serde::Deserialize; use tokio::runtime::Runtime; @@ -253,7 +253,10 @@ fn check_live_redirects() { ); assert!(checked.redirect.is_some(), "{checked:#?}"); // Check for the specific expected return script value in base64 - assert_eq!(checked.redirect.unwrap(), "data:application/javascript;base64,LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICB1QmxvY2sgT3JpZ2luIC0gYSBicm93c2VyIGV4dGVuc2lvbiB0byBibG9jayByZXF1ZXN0cy4KICAgIENvcHlyaWdodCAoQykgMjAxOS1wcmVzZW50IFJheW1vbmQgSGlsbAoKICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IKICAgIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW0uICBJZiBub3QsIHNlZSB7aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL30uCgogICAgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL2dvcmhpbGwvdUJsb2NrCiovCgooZnVuY3Rpb24oKSB7CiAgICAndXNlIHN0cmljdCc7CiAgICBpZiAoIGFtem5hZHMgKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgdmFyIHcgPSB3aW5kb3c7CiAgICB2YXIgbm9vcGZuID0gZnVuY3Rpb24oKSB7CiAgICAgICAgOwogICAgfS5iaW5kKCk7CiAgICB2YXIgYW16bmFkcyA9IHsKICAgICAgICBhcHBlbmRTY3JpcHRUYWc6IG5vb3BmbiwKICAgICAgICBhcHBlbmRUYXJnZXRpbmdUb0FkU2VydmVyVXJsOiBub29wZm4sCiAgICAgICAgYXBwZW5kVGFyZ2V0aW5nVG9RdWVyeVN0cmluZzogbm9vcGZuLAogICAgICAgIGNsZWFyVGFyZ2V0aW5nRnJvbUdQVEFzeW5jOiBub29wZm4sCiAgICAgICAgZG9BbGxUYXNrczogbm9vcGZuLAogICAgICAgIGRvR2V0QWRzQXN5bmM6IG5vb3BmbiwKICAgICAgICBkb1Rhc2s6IG5vb3BmbiwKICAgICAgICBkZXRlY3RJZnJhbWVBbmRHZXRVUkw6IG5vb3BmbiwKICAgICAgICBnZXRBZHM6IG5vb3BmbiwKICAgICAgICBnZXRBZHNBc3luYzogbm9vcGZuLAogICAgICAgIGdldEFkRm9yU2xvdDogbm9vcGZuLAogICAgICAgIGdldEFkc0NhbGxiYWNrOiBub29wZm4sCiAgICAgICAgZ2V0RGlzcGxheUFkczogbm9vcGZuLAogICAgICAgIGdldERpc3BsYXlBZHNBc3luYzogbm9vcGZuLAogICAgICAgIGdldERpc3BsYXlBZHNDYWxsYmFjazogbm9vcGZuLAogICAgICAgIGdldEtleXM6IG5vb3BmbiwKICAgICAgICBnZXRSZWZlcnJlclVSTDogbm9vcGZuLAogICAgICAgIGdldFNjcmlwdFNvdXJjZTogbm9vcGZuLAogICAgICAgIGdldFRhcmdldGluZzogbm9vcGZuLAogICAgICAgIGdldFRva2Vuczogbm9vcGZuLAogICAgICAgIGdldFZhbGlkTWlsbGlzZWNvbmRzOiBub29wZm4sCiAgICAgICAgZ2V0VmlkZW9BZHM6IG5vb3BmbiwKICAgICAgICBnZXRWaWRlb0Fkc0FzeW5jOiBub29wZm4sCiAgICAgICAgZ2V0VmlkZW9BZHNDYWxsYmFjazogbm9vcGZuLAogICAgICAgIGhhbmRsZUNhbGxCYWNrOiBub29wZm4sCiAgICAgICAgaGFzQWRzOiBub29wZm4sCiAgICAgICAgcmVuZGVyQWQ6IG5vb3BmbiwKICAgICAgICBzYXZlQWRzOiBub29wZm4sCiAgICAgICAgc2V0VGFyZ2V0aW5nOiBub29wZm4sCiAgICAgICAgc2V0VGFyZ2V0aW5nRm9yR1BUQXN5bmM6IG5vb3BmbiwKICAgICAgICBzZXRUYXJnZXRpbmdGb3JHUFRTeW5jOiBub29wZm4sCiAgICAgICAgdHJ5R2V0QWRzQXN5bmM6IG5vb3BmbiwKICAgICAgICB1cGRhdGVBZHM6IG5vb3BmbgogICAgfTsKICAgIHcuYW16bmFkcyA9IGFtem5hZHM7CiAgICB3LmFtem5fYWRzID0gdy5hbXpuX2FkcyB8fCBub29wZm47CiAgICB3LmFheF93cml0ZSA9IHcuYWF4X3dyaXRlIHx8IG5vb3BmbjsKICAgIHcuYWF4X3JlbmRlcl9hZCA9IHcuYWF4X3JlbmRlcl9hZCB8fCBub29wZm47Cn0pKCk7Cg=="); + assert_eq!( + checked.redirect.unwrap(), + "data:application/javascript;base64,LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICB1QmxvY2sgT3JpZ2luIC0gYSBicm93c2VyIGV4dGVuc2lvbiB0byBibG9jayByZXF1ZXN0cy4KICAgIENvcHlyaWdodCAoQykgMjAxOS1wcmVzZW50IFJheW1vbmQgSGlsbAoKICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IKICAgIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW0uICBJZiBub3QsIHNlZSB7aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL30uCgogICAgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL2dvcmhpbGwvdUJsb2NrCiovCgooZnVuY3Rpb24oKSB7CiAgICAndXNlIHN0cmljdCc7CiAgICBpZiAoIGFtem5hZHMgKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgdmFyIHcgPSB3aW5kb3c7CiAgICB2YXIgbm9vcGZuID0gZnVuY3Rpb24oKSB7CiAgICAgICAgOwogICAgfS5iaW5kKCk7CiAgICB2YXIgYW16bmFkcyA9IHsKICAgICAgICBhcHBlbmRTY3JpcHRUYWc6IG5vb3BmbiwKICAgICAgICBhcHBlbmRUYXJnZXRpbmdUb0FkU2VydmVyVXJsOiBub29wZm4sCiAgICAgICAgYXBwZW5kVGFyZ2V0aW5nVG9RdWVyeVN0cmluZzogbm9vcGZuLAogICAgICAgIGNsZWFyVGFyZ2V0aW5nRnJvbUdQVEFzeW5jOiBub29wZm4sCiAgICAgICAgZG9BbGxUYXNrczogbm9vcGZuLAogICAgICAgIGRvR2V0QWRzQXN5bmM6IG5vb3BmbiwKICAgICAgICBkb1Rhc2s6IG5vb3BmbiwKICAgICAgICBkZXRlY3RJZnJhbWVBbmRHZXRVUkw6IG5vb3BmbiwKICAgICAgICBnZXRBZHM6IG5vb3BmbiwKICAgICAgICBnZXRBZHNBc3luYzogbm9vcGZuLAogICAgICAgIGdldEFkRm9yU2xvdDogbm9vcGZuLAogICAgICAgIGdldEFkc0NhbGxiYWNrOiBub29wZm4sCiAgICAgICAgZ2V0RGlzcGxheUFkczogbm9vcGZuLAogICAgICAgIGdldERpc3BsYXlBZHNBc3luYzogbm9vcGZuLAogICAgICAgIGdldERpc3BsYXlBZHNDYWxsYmFjazogbm9vcGZuLAogICAgICAgIGdldEtleXM6IG5vb3BmbiwKICAgICAgICBnZXRSZWZlcnJlclVSTDogbm9vcGZuLAogICAgICAgIGdldFNjcmlwdFNvdXJjZTogbm9vcGZuLAogICAgICAgIGdldFRhcmdldGluZzogbm9vcGZuLAogICAgICAgIGdldFRva2Vuczogbm9vcGZuLAogICAgICAgIGdldFZhbGlkTWlsbGlzZWNvbmRzOiBub29wZm4sCiAgICAgICAgZ2V0VmlkZW9BZHM6IG5vb3BmbiwKICAgICAgICBnZXRWaWRlb0Fkc0FzeW5jOiBub29wZm4sCiAgICAgICAgZ2V0VmlkZW9BZHNDYWxsYmFjazogbm9vcGZuLAogICAgICAgIGhhbmRsZUNhbGxCYWNrOiBub29wZm4sCiAgICAgICAgaGFzQWRzOiBub29wZm4sCiAgICAgICAgcmVuZGVyQWQ6IG5vb3BmbiwKICAgICAgICBzYXZlQWRzOiBub29wZm4sCiAgICAgICAgc2V0VGFyZ2V0aW5nOiBub29wZm4sCiAgICAgICAgc2V0VGFyZ2V0aW5nRm9yR1BUQXN5bmM6IG5vb3BmbiwKICAgICAgICBzZXRUYXJnZXRpbmdGb3JHUFRTeW5jOiBub29wZm4sCiAgICAgICAgdHJ5R2V0QWRzQXN5bmM6IG5vb3BmbiwKICAgICAgICB1cGRhdGVBZHM6IG5vb3BmbgogICAgfTsKICAgIHcuYW16bmFkcyA9IGFtem5hZHM7CiAgICB3LmFtem5fYWRzID0gdy5hbXpuX2FkcyB8fCBub29wZm47CiAgICB3LmFheF93cml0ZSA9IHcuYWF4X3dyaXRlIHx8IG5vb3BmbjsKICAgIHcuYWF4X3JlbmRlcl9hZCA9IHcuYWF4X3JlbmRlcl9hZCB8fCBub29wZm47Cn0pKCk7Cg==" + ); } { let checked = engine.check_network_request( @@ -270,7 +273,10 @@ fn check_live_redirects() { checked.filter, checked.exception ); assert!(checked.redirect.is_some(), "{checked:#?}"); - assert_eq!(checked.redirect.unwrap(), "data:application/javascript;base64,LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICB1QmxvY2sgT3JpZ2luIC0gYSBicm93c2VyIGV4dGVuc2lvbiB0byBibG9jayByZXF1ZXN0cy4KICAgIENvcHlyaWdodCAoQykgMjAxOS1wcmVzZW50IFJheW1vbmQgSGlsbAoKICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IKICAgIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW0uICBJZiBub3QsIHNlZSB7aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL30uCgogICAgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL2dvcmhpbGwvdUJsb2NrCiovCgooZnVuY3Rpb24oKSB7CiAgICAndXNlIHN0cmljdCc7CiAgICAvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9kb3VibGVjbGljay1ncHQvcmVmZXJlbmNlCiAgICBjb25zdCBub29wZm4gPSBmdW5jdGlvbigpIHsKICAgIH0uYmluZCgpOwogICAgY29uc3Qgbm9vcHRoaXNmbiA9IGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiB0aGlzOwogICAgfTsKICAgIGNvbnN0IG5vb3BudWxsZm4gPSBmdW5jdGlvbigpIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH07CiAgICBjb25zdCBub29wYXJyYXlmbiA9IGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBbXTsKICAgIH07CiAgICBjb25zdCBub29wc3RyZm4gPSBmdW5jdGlvbigpIHsKICAgICAgICByZXR1cm4gJyc7CiAgICB9OwogICAgLy8KICAgIGNvbnN0IGNvbXBhbmlvbkFkc1NlcnZpY2UgPSB7CiAgICAgICAgYWRkRXZlbnRMaXN0ZW5lcjogbm9vcHRoaXNmbiwKICAgICAgICBlbmFibGVTeW5jTG9hZGluZzogbm9vcGZuLAogICAgICAgIHNldFJlZnJlc2hVbmZpbGxlZFNsb3RzOiBub29wZm4KICAgIH07CiAgICBjb25zdCBjb250ZW50U2VydmljZSA9IHsKICAgICAgICBhZGRFdmVudExpc3RlbmVyOiBub29wdGhpc2ZuLAogICAgICAgIHNldENvbnRlbnQ6IG5vb3BmbgogICAgfTsKICAgIGNvbnN0IFBhc3NiYWNrU2xvdCA9IGZ1bmN0aW9uKCkgewogICAgfTsKICAgIGxldCBwID0gUGFzc2JhY2tTbG90LnByb3RvdHlwZTsKICAgIHAuZGlzcGxheSA9IG5vb3BmbjsKICAgIHAuZ2V0ID0gbm9vcG51bGxmbjsKICAgIHAuc2V0ID0gbm9vcHRoaXNmbjsKICAgIHAuc2V0Q2xpY2tVcmwgPSBub29wdGhpc2ZuOwogICAgcC5zZXRUYWdGb3JDaGlsZERpcmVjdGVkVHJlYXRtZW50ID0gbm9vcHRoaXNmbjsKICAgIHAuc2V0VGFyZ2V0aW5nID0gbm9vcHRoaXNmbjsKICAgIHAudXBkYXRlVGFyZ2V0aW5nRnJvbU1hcCA9IG5vb3B0aGlzZm47CiAgICBjb25zdCBwdWJBZHNTZXJ2aWNlID0gewogICAgICAgIGFkZEV2ZW50TGlzdGVuZXI6IG5vb3B0aGlzZm4sCiAgICAgICAgY2xlYXI6IG5vb3BmbiwKICAgICAgICBjbGVhckNhdGVnb3J5RXhjbHVzaW9uczogbm9vcHRoaXNmbiwKICAgICAgICBjbGVhclRhZ0ZvckNoaWxkRGlyZWN0ZWRUcmVhdG1lbnQ6IG5vb3B0aGlzZm4sCiAgICAgICAgY2xlYXJUYXJnZXRpbmc6IG5vb3B0aGlzZm4sCiAgICAgICAgY29sbGFwc2VFbXB0eURpdnM6IG5vb3BmbiwKICAgICAgICBkZWZpbmVPdXRPZlBhZ2VQYXNzYmFjazogZnVuY3Rpb24oKSB7IHJldHVybiBuZXcgUGFzc2JhY2tTbG90KCk7IH0sCiAgICAgICAgZGVmaW5lUGFzc2JhY2s6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbmV3IFBhc3NiYWNrU2xvdCgpOyB9LAogICAgICAgIGRpc2FibGVJbml0aWFsTG9hZDogbm9vcGZuLAogICAgICAgIGRpc3BsYXk6IG5vb3BmbiwKICAgICAgICBlbmFibGVBc3luY1JlbmRlcmluZzogbm9vcGZuLAogICAgICAgIGVuYWJsZVNpbmdsZVJlcXVlc3Q6IG5vb3BmbiwKICAgICAgICBlbmFibGVTeW5jUmVuZGVyaW5nOiBub29wZm4sCiAgICAgICAgZW5hYmxlVmlkZW9BZHM6IG5vb3BmbiwKICAgICAgICBnZXQ6IG5vb3BudWxsZm4sCiAgICAgICAgZ2V0QXR0cmlidXRlS2V5czogbm9vcGFycmF5Zm4sCiAgICAgICAgZ2V0VGFyZ2V0aW5nOiBub29wZm4sCiAgICAgICAgZ2V0VGFyZ2V0aW5nS2V5czogbm9vcGFycmF5Zm4sCiAgICAgICAgZ2V0U2xvdHM6IG5vb3BhcnJheWZuLAogICAgICAgIHJlZnJlc2g6IG5vb3BmbiwKICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyOiBub29wZm4sCiAgICAgICAgc2V0OiBub29wdGhpc2ZuLAogICAgICAgIHNldENhdGVnb3J5RXhjbHVzaW9uOiBub29wdGhpc2ZuLAogICAgICAgIHNldENlbnRlcmluZzogbm9vcGZuLAogICAgICAgIHNldENvb2tpZU9wdGlvbnM6IG5vb3B0aGlzZm4sCiAgICAgICAgc2V0Rm9yY2VTYWZlRnJhbWU6IG5vb3B0aGlzZm4sCiAgICAgICAgc2V0TG9jYXRpb246IG5vb3B0aGlzZm4sCiAgICAgICAgc2V0UHVibGlzaGVyUHJvdmlkZWRJZDogbm9vcHRoaXNmbiwKICAgICAgICBzZXRQcml2YWN5U2V0dGluZ3M6IG5vb3B0aGlzZm4sCiAgICAgICAgc2V0UmVxdWVzdE5vblBlcnNvbmFsaXplZEFkczogbm9vcHRoaXNmbiwKICAgICAgICBzZXRTYWZlRnJhbWVDb25maWc6IG5vb3B0aGlzZm4sCiAgICAgICAgc2V0VGFnRm9yQ2hpbGREaXJlY3RlZFRyZWF0bWVudDogbm9vcHRoaXNmbiwKICAgICAgICBzZXRUYXJnZXRpbmc6IG5vb3B0aGlzZm4sCiAgICAgICAgc2V0VmlkZW9Db250ZW50OiBub29wdGhpc2ZuLAogICAgICAgIHVwZGF0ZUNvcnJlbGF0b3I6IG5vb3BmbgogICAgfTsKICAgIGNvbnN0IFNpemVNYXBwaW5nQnVpbGRlciA9IGZ1bmN0aW9uKCkgewogICAgfTsKICAgIHAgPSBTaXplTWFwcGluZ0J1aWxkZXIucHJvdG90eXBlOwogICAgcC5hZGRTaXplID0gbm9vcHRoaXNmbjsKICAgIHAuYnVpbGQgPSBub29wbnVsbGZuOwogICAgY29uc3QgU2xvdCA9IGZ1bmN0aW9uKCkgewogICAgfTsKICAgIHAgPSBTbG90LnByb3RvdHlwZTsKICAgIHAuYWRkU2VydmljZSA9IG5vb3B0aGlzZm47CiAgICBwLmNsZWFyQ2F0ZWdvcnlFeGNsdXNpb25zID0gbm9vcHRoaXNmbjsKICAgIHAuY2xlYXJUYXJnZXRpbmcgPSBub29wdGhpc2ZuOwogICAgcC5kZWZpbmVTaXplTWFwcGluZyA9IG5vb3B0aGlzZm47CiAgICBwLmdldCA9IG5vb3BudWxsZm47CiAgICBwLmdldEFkVW5pdFBhdGggPSBub29wYXJyYXlmbjsKICAgIHAuZ2V0QXR0cmlidXRlS2V5cyA9IG5vb3BhcnJheWZuOwogICAgcC5nZXRDYXRlZ29yeUV4Y2x1c2lvbnMgPSBub29wYXJyYXlmbjsKICAgIHAuZ2V0RG9tSWQgPSBub29wc3RyZm47CiAgICBwLmdldFJlc3BvbnNlSW5mb3JtYXRpb24gPSBub29wbnVsbGZuOwogICAgcC5nZXRTbG90RWxlbWVudElkID0gbm9vcHN0cmZuOwogICAgcC5nZXRTbG90SWQgPSBub29wdGhpc2ZuOwogICAgcC5nZXRUYXJnZXRpbmcgPSBub29wYXJyYXlmbjsKICAgIHAuZ2V0VGFyZ2V0aW5nS2V5cyA9IG5vb3BhcnJheWZuOwogICAgcC5zZXQgPSBub29wdGhpc2ZuOwogICAgcC5zZXRDYXRlZ29yeUV4Y2x1c2lvbiA9IG5vb3B0aGlzZm47CiAgICBwLnNldENsaWNrVXJsID0gbm9vcHRoaXNmbjsKICAgIHAuc2V0Q29sbGFwc2VFbXB0eURpdiA9IG5vb3B0aGlzZm47CiAgICBwLnNldFRhcmdldGluZyA9IG5vb3B0aGlzZm47CiAgICBwLnVwZGF0ZVRhcmdldGluZ0Zyb21NYXAgPSBub29wdGhpc2ZuOwogICAgLy8KICAgIGNvbnN0IGdwdCA9IHdpbmRvdy5nb29nbGV0YWcgfHwge307CiAgICBjb25zdCBjbWQgPSBncHQuY21kIHx8IFtdOwogICAgZ3B0LmFwaVJlYWR5ID0gdHJ1ZTsKICAgIGdwdC5jbWQgPSBbXTsKICAgIGdwdC5jbWQucHVzaCA9IGZ1bmN0aW9uKGEpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBhKCk7CiAgICAgICAgfSBjYXRjaCAoZXgpIHsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDE7CiAgICB9OwogICAgZ3B0LmNvbXBhbmlvbkFkcyA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gY29tcGFuaW9uQWRzU2VydmljZTsgfTsKICAgIGdwdC5jb250ZW50ID0gZnVuY3Rpb24oKSB7IHJldHVybiBjb250ZW50U2VydmljZTsgfTsKICAgIGdwdC5kZWZpbmVPdXRPZlBhZ2VTbG90ID0gZnVuY3Rpb24oKSB7IHJldHVybiBuZXcgU2xvdCgpOyB9OwogICAgZ3B0LmRlZmluZVNsb3QgPSBmdW5jdGlvbigpIHsgcmV0dXJuIG5ldyBTbG90KCk7IH07CiAgICBncHQuZGVzdHJveVNsb3RzID0gbm9vcGZuOwogICAgZ3B0LmRpc2FibGVQdWJsaXNoZXJDb25zb2xlID0gbm9vcGZuOwogICAgZ3B0LmRpc3BsYXkgPSBub29wZm47CiAgICBncHQuZW5hYmxlU2VydmljZXMgPSBub29wZm47CiAgICBncHQuZ2V0VmVyc2lvbiA9IG5vb3BzdHJmbjsKICAgIGdwdC5wdWJhZHMgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHB1YkFkc1NlcnZpY2U7IH07CiAgICBncHQucHViYWRzUmVhZHkgPSB0cnVlOwogICAgZ3B0LnNldEFkSWZyYW1lVGl0bGUgPSBub29wZm47CiAgICBncHQuc2l6ZU1hcHBpbmcgPSBmdW5jdGlvbigpIHsgcmV0dXJuIG5ldyBTaXplTWFwcGluZ0J1aWxkZXIoKTsgfTsKICAgIHdpbmRvdy5nb29nbGV0YWcgPSBncHQ7CiAgICB3aGlsZSAoIGNtZC5sZW5ndGggIT09IDAgKSB7CiAgICAgICAgZ3B0LmNtZC5wdXNoKGNtZC5zaGlmdCgpKTsKICAgIH0KfSkoKTsK"); + assert_eq!( + checked.redirect.unwrap(), + "data:application/javascript;base64,LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICB1QmxvY2sgT3JpZ2luIC0gYSBicm93c2VyIGV4dGVuc2lvbiB0byBibG9jayByZXF1ZXN0cy4KICAgIENvcHlyaWdodCAoQykgMjAxOS1wcmVzZW50IFJheW1vbmQgSGlsbAoKICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IKICAgIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW0uICBJZiBub3QsIHNlZSB7aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL30uCgogICAgSG9tZTogaHR0cHM6Ly9naXRodWIuY29tL2dvcmhpbGwvdUJsb2NrCiovCgooZnVuY3Rpb24oKSB7CiAgICAndXNlIHN0cmljdCc7CiAgICAvLyBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9kb3VibGVjbGljay1ncHQvcmVmZXJlbmNlCiAgICBjb25zdCBub29wZm4gPSBmdW5jdGlvbigpIHsKICAgIH0uYmluZCgpOwogICAgY29uc3Qgbm9vcHRoaXNmbiA9IGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiB0aGlzOwogICAgfTsKICAgIGNvbnN0IG5vb3BudWxsZm4gPSBmdW5jdGlvbigpIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH07CiAgICBjb25zdCBub29wYXJyYXlmbiA9IGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBbXTsKICAgIH07CiAgICBjb25zdCBub29wc3RyZm4gPSBmdW5jdGlvbigpIHsKICAgICAgICByZXR1cm4gJyc7CiAgICB9OwogICAgLy8KICAgIGNvbnN0IGNvbXBhbmlvbkFkc1NlcnZpY2UgPSB7CiAgICAgICAgYWRkRXZlbnRMaXN0ZW5lcjogbm9vcHRoaXNmbiwKICAgICAgICBlbmFibGVTeW5jTG9hZGluZzogbm9vcGZuLAogICAgICAgIHNldFJlZnJlc2hVbmZpbGxlZFNsb3RzOiBub29wZm4KICAgIH07CiAgICBjb25zdCBjb250ZW50U2VydmljZSA9IHsKICAgICAgICBhZGRFdmVudExpc3RlbmVyOiBub29wdGhpc2ZuLAogICAgICAgIHNldENvbnRlbnQ6IG5vb3BmbgogICAgfTsKICAgIGNvbnN0IFBhc3NiYWNrU2xvdCA9IGZ1bmN0aW9uKCkgewogICAgfTsKICAgIGxldCBwID0gUGFzc2JhY2tTbG90LnByb3RvdHlwZTsKICAgIHAuZGlzcGxheSA9IG5vb3BmbjsKICAgIHAuZ2V0ID0gbm9vcG51bGxmbjsKICAgIHAuc2V0ID0gbm9vcHRoaXNmbjsKICAgIHAuc2V0Q2xpY2tVcmwgPSBub29wdGhpc2ZuOwogICAgcC5zZXRUYWdGb3JDaGlsZERpcmVjdGVkVHJlYXRtZW50ID0gbm9vcHRoaXNmbjsKICAgIHAuc2V0VGFyZ2V0aW5nID0gbm9vcHRoaXNmbjsKICAgIHAudXBkYXRlVGFyZ2V0aW5nRnJvbU1hcCA9IG5vb3B0aGlzZm47CiAgICBjb25zdCBwdWJBZHNTZXJ2aWNlID0gewogICAgICAgIGFkZEV2ZW50TGlzdGVuZXI6IG5vb3B0aGlzZm4sCiAgICAgICAgY2xlYXI6IG5vb3BmbiwKICAgICAgICBjbGVhckNhdGVnb3J5RXhjbHVzaW9uczogbm9vcHRoaXNmbiwKICAgICAgICBjbGVhclRhZ0ZvckNoaWxkRGlyZWN0ZWRUcmVhdG1lbnQ6IG5vb3B0aGlzZm4sCiAgICAgICAgY2xlYXJUYXJnZXRpbmc6IG5vb3B0aGlzZm4sCiAgICAgICAgY29sbGFwc2VFbXB0eURpdnM6IG5vb3BmbiwKICAgICAgICBkZWZpbmVPdXRPZlBhZ2VQYXNzYmFjazogZnVuY3Rpb24oKSB7IHJldHVybiBuZXcgUGFzc2JhY2tTbG90KCk7IH0sCiAgICAgICAgZGVmaW5lUGFzc2JhY2s6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbmV3IFBhc3NiYWNrU2xvdCgpOyB9LAogICAgICAgIGRpc2FibGVJbml0aWFsTG9hZDogbm9vcGZuLAogICAgICAgIGRpc3BsYXk6IG5vb3BmbiwKICAgICAgICBlbmFibGVBc3luY1JlbmRlcmluZzogbm9vcGZuLAogICAgICAgIGVuYWJsZVNpbmdsZVJlcXVlc3Q6IG5vb3BmbiwKICAgICAgICBlbmFibGVTeW5jUmVuZGVyaW5nOiBub29wZm4sCiAgICAgICAgZW5hYmxlVmlkZW9BZHM6IG5vb3BmbiwKICAgICAgICBnZXQ6IG5vb3BudWxsZm4sCiAgICAgICAgZ2V0QXR0cmlidXRlS2V5czogbm9vcGFycmF5Zm4sCiAgICAgICAgZ2V0VGFyZ2V0aW5nOiBub29wZm4sCiAgICAgICAgZ2V0VGFyZ2V0aW5nS2V5czogbm9vcGFycmF5Zm4sCiAgICAgICAgZ2V0U2xvdHM6IG5vb3BhcnJheWZuLAogICAgICAgIHJlZnJlc2g6IG5vb3BmbiwKICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyOiBub29wZm4sCiAgICAgICAgc2V0OiBub29wdGhpc2ZuLAogICAgICAgIHNldENhdGVnb3J5RXhjbHVzaW9uOiBub29wdGhpc2ZuLAogICAgICAgIHNldENlbnRlcmluZzogbm9vcGZuLAogICAgICAgIHNldENvb2tpZU9wdGlvbnM6IG5vb3B0aGlzZm4sCiAgICAgICAgc2V0Rm9yY2VTYWZlRnJhbWU6IG5vb3B0aGlzZm4sCiAgICAgICAgc2V0TG9jYXRpb246IG5vb3B0aGlzZm4sCiAgICAgICAgc2V0UHVibGlzaGVyUHJvdmlkZWRJZDogbm9vcHRoaXNmbiwKICAgICAgICBzZXRQcml2YWN5U2V0dGluZ3M6IG5vb3B0aGlzZm4sCiAgICAgICAgc2V0UmVxdWVzdE5vblBlcnNvbmFsaXplZEFkczogbm9vcHRoaXNmbiwKICAgICAgICBzZXRTYWZlRnJhbWVDb25maWc6IG5vb3B0aGlzZm4sCiAgICAgICAgc2V0VGFnRm9yQ2hpbGREaXJlY3RlZFRyZWF0bWVudDogbm9vcHRoaXNmbiwKICAgICAgICBzZXRUYXJnZXRpbmc6IG5vb3B0aGlzZm4sCiAgICAgICAgc2V0VmlkZW9Db250ZW50OiBub29wdGhpc2ZuLAogICAgICAgIHVwZGF0ZUNvcnJlbGF0b3I6IG5vb3BmbgogICAgfTsKICAgIGNvbnN0IFNpemVNYXBwaW5nQnVpbGRlciA9IGZ1bmN0aW9uKCkgewogICAgfTsKICAgIHAgPSBTaXplTWFwcGluZ0J1aWxkZXIucHJvdG90eXBlOwogICAgcC5hZGRTaXplID0gbm9vcHRoaXNmbjsKICAgIHAuYnVpbGQgPSBub29wbnVsbGZuOwogICAgY29uc3QgU2xvdCA9IGZ1bmN0aW9uKCkgewogICAgfTsKICAgIHAgPSBTbG90LnByb3RvdHlwZTsKICAgIHAuYWRkU2VydmljZSA9IG5vb3B0aGlzZm47CiAgICBwLmNsZWFyQ2F0ZWdvcnlFeGNsdXNpb25zID0gbm9vcHRoaXNmbjsKICAgIHAuY2xlYXJUYXJnZXRpbmcgPSBub29wdGhpc2ZuOwogICAgcC5kZWZpbmVTaXplTWFwcGluZyA9IG5vb3B0aGlzZm47CiAgICBwLmdldCA9IG5vb3BudWxsZm47CiAgICBwLmdldEFkVW5pdFBhdGggPSBub29wYXJyYXlmbjsKICAgIHAuZ2V0QXR0cmlidXRlS2V5cyA9IG5vb3BhcnJheWZuOwogICAgcC5nZXRDYXRlZ29yeUV4Y2x1c2lvbnMgPSBub29wYXJyYXlmbjsKICAgIHAuZ2V0RG9tSWQgPSBub29wc3RyZm47CiAgICBwLmdldFJlc3BvbnNlSW5mb3JtYXRpb24gPSBub29wbnVsbGZuOwogICAgcC5nZXRTbG90RWxlbWVudElkID0gbm9vcHN0cmZuOwogICAgcC5nZXRTbG90SWQgPSBub29wdGhpc2ZuOwogICAgcC5nZXRUYXJnZXRpbmcgPSBub29wYXJyYXlmbjsKICAgIHAuZ2V0VGFyZ2V0aW5nS2V5cyA9IG5vb3BhcnJheWZuOwogICAgcC5zZXQgPSBub29wdGhpc2ZuOwogICAgcC5zZXRDYXRlZ29yeUV4Y2x1c2lvbiA9IG5vb3B0aGlzZm47CiAgICBwLnNldENsaWNrVXJsID0gbm9vcHRoaXNmbjsKICAgIHAuc2V0Q29sbGFwc2VFbXB0eURpdiA9IG5vb3B0aGlzZm47CiAgICBwLnNldFRhcmdldGluZyA9IG5vb3B0aGlzZm47CiAgICBwLnVwZGF0ZVRhcmdldGluZ0Zyb21NYXAgPSBub29wdGhpc2ZuOwogICAgLy8KICAgIGNvbnN0IGdwdCA9IHdpbmRvdy5nb29nbGV0YWcgfHwge307CiAgICBjb25zdCBjbWQgPSBncHQuY21kIHx8IFtdOwogICAgZ3B0LmFwaVJlYWR5ID0gdHJ1ZTsKICAgIGdwdC5jbWQgPSBbXTsKICAgIGdwdC5jbWQucHVzaCA9IGZ1bmN0aW9uKGEpIHsKICAgICAgICB0cnkgewogICAgICAgICAgICBhKCk7CiAgICAgICAgfSBjYXRjaCAoZXgpIHsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDE7CiAgICB9OwogICAgZ3B0LmNvbXBhbmlvbkFkcyA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gY29tcGFuaW9uQWRzU2VydmljZTsgfTsKICAgIGdwdC5jb250ZW50ID0gZnVuY3Rpb24oKSB7IHJldHVybiBjb250ZW50U2VydmljZTsgfTsKICAgIGdwdC5kZWZpbmVPdXRPZlBhZ2VTbG90ID0gZnVuY3Rpb24oKSB7IHJldHVybiBuZXcgU2xvdCgpOyB9OwogICAgZ3B0LmRlZmluZVNsb3QgPSBmdW5jdGlvbigpIHsgcmV0dXJuIG5ldyBTbG90KCk7IH07CiAgICBncHQuZGVzdHJveVNsb3RzID0gbm9vcGZuOwogICAgZ3B0LmRpc2FibGVQdWJsaXNoZXJDb25zb2xlID0gbm9vcGZuOwogICAgZ3B0LmRpc3BsYXkgPSBub29wZm47CiAgICBncHQuZW5hYmxlU2VydmljZXMgPSBub29wZm47CiAgICBncHQuZ2V0VmVyc2lvbiA9IG5vb3BzdHJmbjsKICAgIGdwdC5wdWJhZHMgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHB1YkFkc1NlcnZpY2U7IH07CiAgICBncHQucHViYWRzUmVhZHkgPSB0cnVlOwogICAgZ3B0LnNldEFkSWZyYW1lVGl0bGUgPSBub29wZm47CiAgICBncHQuc2l6ZU1hcHBpbmcgPSBmdW5jdGlvbigpIHsgcmV0dXJuIG5ldyBTaXplTWFwcGluZ0J1aWxkZXIoKTsgfTsKICAgIHdpbmRvdy5nb29nbGV0YWcgPSBncHQ7CiAgICB3aGlsZSAoIGNtZC5sZW5ndGggIT09IDAgKSB7CiAgICAgICAgZ3B0LmNtZC5wdXNoKGNtZC5zaGlmdCgpKTsKICAgIH0KfSkoKTsK" + ); } } diff --git a/tests/matching.rs b/tests/matching.rs index 6a7da9ee..7cbd95fb 100644 --- a/tests/matching.rs +++ b/tests/matching.rs @@ -1,7 +1,7 @@ +use adblock::Engine; use adblock::filters::network::{NetworkFilter, NetworkFilterMask, NetworkFilterMaskHelper}; use adblock::request::Request; use adblock::resources::{MimeType, Resource, ResourceType}; -use adblock::Engine; use base64::{engine::Engine as _, prelude::BASE64_STANDARD}; use serde::{Deserialize, Serialize}; @@ -172,8 +172,8 @@ fn check_rule_matching_browserlike() { mod test_utils; use test_utils::rules_from_lists; - use adblock::request::Request; use adblock::Engine; + use adblock::request::Request; use serde::Deserialize; #[allow(non_snake_case)] diff --git a/tests/simple_use.rs b/tests/simple_use.rs index 4b4f9259..5f98674d 100644 --- a/tests/simple_use.rs +++ b/tests/simple_use.rs @@ -1,5 +1,5 @@ -use adblock::request::Request; use adblock::Engine; +use adblock::request::Request; #[test] fn check_simple_use() { diff --git a/tests/ublock-coverage.rs b/tests/ublock-coverage.rs index 94aa7aca..087d57ec 100644 --- a/tests/ublock-coverage.rs +++ b/tests/ublock-coverage.rs @@ -1,5 +1,5 @@ -use adblock::request::Request; use adblock::Engine; +use adblock::request::Request; #[allow(unused_imports)] use std::collections::HashMap; diff --git a/tests/unit/blocker.rs b/tests/unit/blocker.rs index 1cd0b962..1901f026 100644 --- a/tests/unit/blocker.rs +++ b/tests/unit/blocker.rs @@ -371,26 +371,30 @@ mod blocker_tests { "worker-src 'none',script-src 'self' * 'unsafe-inline'", )), ]; - assert!(possible_results.contains( - &blocker.get_csp_directives( - &Request::new( - "https://example.com", - "https://pirateproxy.live", - "document" + assert!( + possible_results.contains( + &blocker.get_csp_directives( + &Request::new( + "https://example.com", + "https://pirateproxy.live", + "document" + ) + .unwrap() ) - .unwrap() ) - )); - assert!(possible_results.contains( - &blocker.get_csp_directives( - &Request::new( - "https://example.com", - "https://pirateproxy.live", - "subdocument" + ); + assert!( + possible_results.contains( + &blocker.get_csp_directives( + &Request::new( + "https://example.com", + "https://pirateproxy.live", + "subdocument" + ) + .unwrap() ) - .unwrap() ) - )); + ); } { // A directive with an exception should not be returned @@ -1330,7 +1334,7 @@ mod placeholder_string_tests { mod legacy_rule_parsing_tests { use crate::blocker::{Blocker, BlockerOptions}; use crate::filters::network::NetworkFilterMaskHelper; - use crate::lists::{parse_filters, FilterFormat, ParseOptions}; + use crate::lists::{FilterFormat, ParseOptions, parse_filters}; use crate::test_utils::rules_from_lists; struct ListCounts { diff --git a/tests/unit/content_blocking.rs b/tests/unit/content_blocking.rs index a95d048b..35a18c98 100644 --- a/tests/unit/content_blocking.rs +++ b/tests/unit/content_blocking.rs @@ -108,7 +108,9 @@ mod ab2cb_tests { } }]"####, ); - test_from_abp("||com/banners/$image,object,subdocument,domain=~pingdom.com|~thetvdb.com|~tooltrucks.com", r####"[{ + test_from_abp( + "||com/banners/$image,object,subdocument,domain=~pingdom.com|~thetvdb.com|~tooltrucks.com", + r####"[{ "action": { "type": "block" }, @@ -141,7 +143,8 @@ mod ab2cb_tests { "action": { "type": "block" } - }]"####); + }]"####, + ); test_from_abp( "$image,third-party,xmlhttprequest,domain=rd.com", r####"[{ @@ -358,7 +361,9 @@ mod ab2cb_tests { } }]"####, ); - test_from_abp("||doubleclick.net^$third-party,domain=3news.co.nz|92q.com|abc-7.com|addictinggames.com|allbusiness.com|allthingsd.com|bizjournals.com|bloomberg.com|bnn.ca|boom92houston.com|boom945.com|boomphilly.com|break.com|cbc.ca|cbs19.tv|cbs3springfield.com|cbsatlanta.com|cbslocal.com|complex.com|dailymail.co.uk|darkhorizons.com|doubleviking.com|euronews.com|extratv.com|fandango.com|fox19.com|fox5vegas.com|gorillanation.com|hawaiinewsnow.com|hellobeautiful.com|hiphopnc.com|hot1041stl.com|hothiphopdetroit.com|hotspotatl.com|hulu.com|imdb.com|indiatimes.com|indyhiphop.com|ipowerrichmond.com|joblo.com|kcra.com|kctv5.com|ketv.com|koat.com|koco.com|kolotv.com|kpho.com|kptv.com|ksat.com|ksbw.com|ksfy.com|ksl.com|kypost.com|kysdc.com|live5news.com|livestation.com|livestream.com|metro.us|metronews.ca|miamiherald.com|my9nj.com|myboom1029.com|mycolumbusmagic.com|mycolumbuspower.com|myfoxdetroit.com|myfoxorlando.com|myfoxphilly.com|myfoxphoenix.com|myfoxtampabay.com|nbcrightnow.com|neatorama.com|necn.com|neopets.com|news.com.au|news4jax.com|newsone.com|nintendoeverything.com|oldschoolcincy.com|own3d.tv|pagesuite-professional.co.uk|pandora.com|player.theplatform.com|ps3news.com|radio.com|radionowindy.com|rottentomatoes.com|sbsun.com|shacknews.com|sk-gaming.com|ted.com|thebeatdfw.com|theboxhouston.com|theglobeandmail.com|timesnow.tv|tv2.no|twitch.tv|universalsports.com|ustream.tv|wapt.com|washingtonpost.com|wate.com|wbaltv.com|wcvb.com|wdrb.com|wdsu.com|wflx.com|wfmz.com|wfsb.com|wgal.com|whdh.com|wired.com|wisn.com|wiznation.com|wlky.com|wlns.com|wlwt.com|wmur.com|wnem.com|wowt.com|wral.com|wsj.com|wsmv.com|wsvn.com|wtae.com|wthr.com|wxii12.com|wyff4.com|yahoo.com|youtube.com|zhiphopcleveland.com", r####"[{ + test_from_abp( + "||doubleclick.net^$third-party,domain=3news.co.nz|92q.com|abc-7.com|addictinggames.com|allbusiness.com|allthingsd.com|bizjournals.com|bloomberg.com|bnn.ca|boom92houston.com|boom945.com|boomphilly.com|break.com|cbc.ca|cbs19.tv|cbs3springfield.com|cbsatlanta.com|cbslocal.com|complex.com|dailymail.co.uk|darkhorizons.com|doubleviking.com|euronews.com|extratv.com|fandango.com|fox19.com|fox5vegas.com|gorillanation.com|hawaiinewsnow.com|hellobeautiful.com|hiphopnc.com|hot1041stl.com|hothiphopdetroit.com|hotspotatl.com|hulu.com|imdb.com|indiatimes.com|indyhiphop.com|ipowerrichmond.com|joblo.com|kcra.com|kctv5.com|ketv.com|koat.com|koco.com|kolotv.com|kpho.com|kptv.com|ksat.com|ksbw.com|ksfy.com|ksl.com|kypost.com|kysdc.com|live5news.com|livestation.com|livestream.com|metro.us|metronews.ca|miamiherald.com|my9nj.com|myboom1029.com|mycolumbusmagic.com|mycolumbuspower.com|myfoxdetroit.com|myfoxorlando.com|myfoxphilly.com|myfoxphoenix.com|myfoxtampabay.com|nbcrightnow.com|neatorama.com|necn.com|neopets.com|news.com.au|news4jax.com|newsone.com|nintendoeverything.com|oldschoolcincy.com|own3d.tv|pagesuite-professional.co.uk|pandora.com|player.theplatform.com|ps3news.com|radio.com|radionowindy.com|rottentomatoes.com|sbsun.com|shacknews.com|sk-gaming.com|ted.com|thebeatdfw.com|theboxhouston.com|theglobeandmail.com|timesnow.tv|tv2.no|twitch.tv|universalsports.com|ustream.tv|wapt.com|washingtonpost.com|wate.com|wbaltv.com|wcvb.com|wdrb.com|wdsu.com|wflx.com|wfmz.com|wfsb.com|wgal.com|whdh.com|wired.com|wisn.com|wiznation.com|wlky.com|wlns.com|wlwt.com|wmur.com|wnem.com|wowt.com|wral.com|wsj.com|wsmv.com|wsvn.com|wtae.com|wthr.com|wxii12.com|wyff4.com|yahoo.com|youtube.com|zhiphopcleveland.com", + r####"[{ "action": { "type": "block" }, @@ -500,8 +505,11 @@ mod ab2cb_tests { "*zhiphopcleveland.com" ] } - }]"####); - test_from_abp("||dt00.net^$third-party,domain=~marketgid.com|~marketgid.ru|~marketgid.ua|~mgid.com|~thechive.com", r####"[{ + }]"####, + ); + test_from_abp( + "||dt00.net^$third-party,domain=~marketgid.com|~marketgid.ru|~marketgid.ua|~mgid.com|~thechive.com", + r####"[{ "action": { "type": "block" }, @@ -518,8 +526,11 @@ mod ab2cb_tests { "*thechive.com" ] } - }]"####); - test_from_abp("||amazonaws.com/newscloud-production/*/backgrounds/$domain=crescent-news.com|daily-jeff.com|recordpub.com|state-journal.com|the-daily-record.com|the-review.com|times-gazette.com", r####"[{ + }]"####, + ); + test_from_abp( + "||amazonaws.com/newscloud-production/*/backgrounds/$domain=crescent-news.com|daily-jeff.com|recordpub.com|state-journal.com|the-daily-record.com|the-review.com|times-gazette.com", + r####"[{ "action": { "type": "block" }, @@ -535,7 +546,8 @@ mod ab2cb_tests { "*times-gazette.com" ] } - }]"####); + }]"####, + ); test_from_abp( "||d1noellhv8fksc.cloudfront.net^", r####"[{ diff --git a/tests/unit/engine.rs b/tests/unit/engine.rs index 0c741371..cdf1b72e 100644 --- a/tests/unit/engine.rs +++ b/tests/unit/engine.rs @@ -312,17 +312,19 @@ mod tests { ) .matched ); - assert!(engine - .check_network_request( - &Request::new( - "https://sub.example.com", - "https://sub.example.com", - "document" + assert!( + engine + .check_network_request( + &Request::new( + "https://sub.example.com", + "https://sub.example.com", + "document" + ) + .unwrap() ) - .unwrap() - ) - .exception - .is_some()); + .exception + .is_some() + ); } #[test] diff --git a/tests/unit/filters/cosmetic.rs b/tests/unit/filters/cosmetic.rs index d9e2b813..d71ca0be 100644 --- a/tests/unit/filters/cosmetic.rs +++ b/tests/unit/filters/cosmetic.rs @@ -1213,33 +1213,38 @@ mod css_validation_tests { #[test] fn bad_selector_inputs() { assert!(validate_css_selector(r#"rm -rf ./*"#, false).is_err()); - assert!(validate_css_selector( - r#"javascript:alert("All pseudo-classes are valid")"#, - false - ) - .is_ok()); - assert!(validate_css_selector( - r#"javascript:alert("But opening comments are still forbidden" /*)"#, - false - ) - .is_err()); + assert!( + validate_css_selector(r#"javascript:alert("All pseudo-classes are valid")"#, false) + .is_ok() + ); + assert!( + validate_css_selector( + r#"javascript:alert("But opening comments are still forbidden" /*)"#, + false + ) + .is_err() + ); assert!(validate_css_selector(r#"This is not a CSS selector."#, false).is_err()); assert!(validate_css_selector(r#"./malware.sh"#, false).is_err()); assert!(validate_css_selector(r#"https://safesite.ru"#, false).is_err()); - assert!(validate_css_selector( - r#"(function(){var e=60;return String.fromCharCode(e.charCodeAt(0))})();"#, - false - ) - .is_err()); + assert!( + validate_css_selector( + r#"(function(){var e=60;return String.fromCharCode(e.charCodeAt(0))})();"#, + false + ) + .is_err() + ); assert!(validate_css_selector(r#"#!/usr/bin/sh"#, false).is_err()); assert!(validate_css_selector(r#"input,input/*"#, false).is_err()); // Accept a closing comment within a string. It should still be impossible to create an // opening comment to match it. - assert!(validate_css_selector( - r#"input[x="*/{}*{background:url(https://hackvertor.co.uk/images/logo.gif)}"]"#, - false - ) - .is_ok()); + assert!( + validate_css_selector( + r#"input[x="*/{}*{background:url(https://hackvertor.co.uk/images/logo.gif)}"]"#, + false + ) + .is_ok() + ); } #[test] diff --git a/tests/unit/filters/network.rs b/tests/unit/filters/network.rs index af9a5e35..51a37012 100644 --- a/tests/unit/filters/network.rs +++ b/tests/unit/filters/network.rs @@ -813,12 +813,10 @@ mod parse_tests { ); } { - assert!(NetworkFilter::parse( - "||foo.com$media,match-case,image", - true, - Default::default() - ) - .is_err()); + assert!( + NetworkFilter::parse("||foo.com$media,match-case,image", true, Default::default()) + .is_err() + ); } // match-case on regex rules is ok { @@ -876,17 +874,21 @@ mod parse_tests { .unwrap() .first_party() ); - assert!(!NetworkFilter::parse( - "||foo.com$first-party,~first-party", - true, - Default::default() - ) - .unwrap() - .first_party()); - // defaults to true - assert!(NetworkFilter::parse("||foo.com", true, Default::default()) + assert!( + !NetworkFilter::parse( + "||foo.com$first-party,~first-party", + true, + Default::default() + ) .unwrap() - .first_party()); + .first_party() + ); + // defaults to true + assert!( + NetworkFilter::parse("||foo.com", true, Default::default()) + .unwrap() + .first_party() + ); } #[test] @@ -918,17 +920,21 @@ mod parse_tests { .unwrap() .third_party() ); - assert!(!NetworkFilter::parse( - "||foo.com$first-party,~third-party", - true, - Default::default() - ) - .unwrap() - .third_party()); - // defaults to true - assert!(NetworkFilter::parse("||foo.com", true, Default::default()) + assert!( + !NetworkFilter::parse( + "||foo.com$first-party,~third-party", + true, + Default::default() + ) .unwrap() - .third_party()); + .third_party() + ); + // defaults to true + assert!( + NetworkFilter::parse("||foo.com", true, Default::default()) + .unwrap() + .third_party() + ); } #[test] diff --git a/tests/unit/filters/network_matchers.rs b/tests/unit/filters/network_matchers.rs index 2a000f46..223f7e94 100644 --- a/tests/unit/filters/network_matchers.rs +++ b/tests/unit/filters/network_matchers.rs @@ -265,7 +265,11 @@ mod match_tests { "https://www1.swatchseries.to/sw.js", true, ); - filter_match_url("||imp*.tradedoubler.com^", "https://impde.tradedoubler.com/imp?type(js)g(22608602)a(1725113)epi(30148500144427100033372010772028)preurl(https://pixel.mathtag.com/event/js?mt_id=1160537&mt_adid=166882&mt_exem=&mt_excl=&v1=&v2=&v3=&s1=&s2=&s3=&mt_nsync=1&redirect=https%3A%2F%2Fad28.ad-srv.net%2Fc%2Fczqwm6dm6kagr2j%3Ftprde%3D)768489806", true); + filter_match_url( + "||imp*.tradedoubler.com^", + "https://impde.tradedoubler.com/imp?type(js)g(22608602)a(1725113)epi(30148500144427100033372010772028)preurl(https://pixel.mathtag.com/event/js?mt_id=1160537&mt_adid=166882&mt_exem=&mt_excl=&v1=&v2=&v3=&s1=&s2=&s3=&mt_nsync=1&redirect=https%3A%2F%2Fad28.ad-srv.net%2Fc%2Fczqwm6dm6kagr2j%3Ftprde%3D)768489806", + true, + ); } #[test] @@ -321,10 +325,12 @@ mod match_tests { assert!(network_filter.matches_test( &request::Request::new("ws://example.com", "https://4shared.com", "websocket").unwrap() )); - assert!(network_filter.matches_test( - &request::Request::new("wss://example.com", "https://4shared.com", "websocket") - .unwrap() - )); + assert!( + network_filter.matches_test( + &request::Request::new("wss://example.com", "https://4shared.com", "websocket") + .unwrap() + ) + ); assert!(!network_filter.matches_test( &request::Request::new("http://example.com", "https://4shared.com", "script").unwrap() )); @@ -339,14 +345,18 @@ mod match_tests { assert!(network_filter.matches_test( &request::Request::new("wss://example.com", "https://4shared.com", "script").unwrap() )); - assert!(!network_filter.matches_test( - &request::Request::new("http://example.com", "https://4shared.com", "websocket") - .unwrap() - )); - assert!(!network_filter.matches_test( - &request::Request::new("https://example.com", "https://4shared.com", "websocket") - .unwrap() - )); + assert!( + !network_filter.matches_test( + &request::Request::new("http://example.com", "https://4shared.com", "websocket") + .unwrap() + ) + ); + assert!( + !network_filter.matches_test( + &request::Request::new("https://example.com", "https://4shared.com", "websocket") + .unwrap() + ) + ); } fn check_options(filter: &NetworkFilter, request: &request::Request) -> bool { @@ -484,26 +494,38 @@ mod match_tests { assert!(network_filter.matches_test( &request::Request::new("http://example.net/adv", "http://example.com", "").unwrap() )); - assert!(!network_filter.matches_test( - &request::Request::new("http://example.net/adv", "http://foo.example.com", "") - .unwrap() - )); - assert!(!network_filter.matches_test( - &request::Request::new( - "http://example.net/adv", - "http://subfoo.foo.example.com", - "" + assert!( + !network_filter.matches_test( + &request::Request::new("http://example.net/adv", "http://foo.example.com", "") + .unwrap() ) - .unwrap() - )); - assert!(network_filter.matches_test( - &request::Request::new("http://example.net/adv", "http://bar.example.com", "") + ); + assert!( + !network_filter.matches_test( + &request::Request::new( + "http://example.net/adv", + "http://subfoo.foo.example.com", + "" + ) .unwrap() - )); - assert!(!network_filter.matches_test( - &request::Request::new("http://example.net/adv", "http://anotherexample.com", "") + ) + ); + assert!( + network_filter.matches_test( + &request::Request::new("http://example.net/adv", "http://bar.example.com", "") + .unwrap() + ) + ); + assert!( + !network_filter.matches_test( + &request::Request::new( + "http://example.net/adv", + "http://anotherexample.com", + "" + ) .unwrap() - )); + ) + ); } { let network_filter = NetworkFilter::parse( @@ -515,26 +537,38 @@ mod match_tests { assert!(!network_filter.matches_test( &request::Request::new("http://example.net/adv", "http://example.com", "").unwrap() )); - assert!(!network_filter.matches_test( - &request::Request::new("http://example.net/adv", "http://foo.example.com", "") - .unwrap() - )); - assert!(!network_filter.matches_test( - &request::Request::new( - "http://example.net/adv", - "http://subfoo.foo.example.com", - "" + assert!( + !network_filter.matches_test( + &request::Request::new("http://example.net/adv", "http://foo.example.com", "") + .unwrap() ) - .unwrap() - )); - assert!(!network_filter.matches_test( - &request::Request::new("http://example.net/adv", "http://bar.example.com", "") + ); + assert!( + !network_filter.matches_test( + &request::Request::new( + "http://example.net/adv", + "http://subfoo.foo.example.com", + "" + ) .unwrap() - )); - assert!(network_filter.matches_test( - &request::Request::new("http://example.net/adv", "http://anotherexample.com", "") + ) + ); + assert!( + !network_filter.matches_test( + &request::Request::new("http://example.net/adv", "http://bar.example.com", "") + .unwrap() + ) + ); + assert!( + network_filter.matches_test( + &request::Request::new( + "http://example.net/adv", + "http://anotherexample.com", + "" + ) .unwrap() - )); + ) + ); } { let network_filter = NetworkFilter::parse( @@ -546,26 +580,38 @@ mod match_tests { assert!(network_filter.matches_test( &request::Request::new("http://example.net/adv", "http://example.com", "").unwrap() )); - assert!(network_filter.matches_test( - &request::Request::new("http://example.net/adv", "http://foo.example.com", "") - .unwrap() - )); - assert!(network_filter.matches_test( - &request::Request::new( - "http://example.net/adv", - "http://subfoo.foo.example.com", - "" + assert!( + network_filter.matches_test( + &request::Request::new("http://example.net/adv", "http://foo.example.com", "") + .unwrap() ) - .unwrap() - )); - assert!(network_filter.matches_test( - &request::Request::new("http://example.net/adv", "http://bar.example.com", "") + ); + assert!( + network_filter.matches_test( + &request::Request::new( + "http://example.net/adv", + "http://subfoo.foo.example.com", + "" + ) .unwrap() - )); - assert!(!network_filter.matches_test( - &request::Request::new("http://example.net/adv", "http://anotherexample.com", "") + ) + ); + assert!( + network_filter.matches_test( + &request::Request::new("http://example.net/adv", "http://bar.example.com", "") + .unwrap() + ) + ); + assert!( + !network_filter.matches_test( + &request::Request::new( + "http://example.net/adv", + "http://anotherexample.com", + "" + ) .unwrap() - )); + ) + ); } { let network_filter = NetworkFilter::parse( @@ -577,26 +623,38 @@ mod match_tests { assert!(!network_filter.matches_test( &request::Request::new("http://example.net/adv", "http://example.com", "").unwrap() )); - assert!(!network_filter.matches_test( - &request::Request::new("http://example.net/adv", "http://foo.example.com", "") - .unwrap() - )); - assert!(!network_filter.matches_test( - &request::Request::new( - "http://example.net/adv", - "http://subfoo.foo.example.com", - "" + assert!( + !network_filter.matches_test( + &request::Request::new("http://example.net/adv", "http://foo.example.com", "") + .unwrap() ) - .unwrap() - )); - assert!(!network_filter.matches_test( - &request::Request::new("http://example.net/adv", "http://bar.example.com", "") + ); + assert!( + !network_filter.matches_test( + &request::Request::new( + "http://example.net/adv", + "http://subfoo.foo.example.com", + "" + ) .unwrap() - )); - assert!(!network_filter.matches_test( - &request::Request::new("http://example.net/adv", "http://anotherexample.com", "") + ) + ); + assert!( + !network_filter.matches_test( + &request::Request::new("http://example.net/adv", "http://bar.example.com", "") + .unwrap() + ) + ); + assert!( + !network_filter.matches_test( + &request::Request::new( + "http://example.net/adv", + "http://anotherexample.com", + "" + ) .unwrap() - )); + ) + ); } { let network_filter = @@ -607,10 +665,12 @@ mod match_tests { assert!(!network_filter.matches_test( &request::Request::new("http://example.net/adv", "http://foo.com", "").unwrap() )); - assert!(!network_filter.matches_test( - &request::Request::new("http://example.net/adv", "http://subfoo.foo.com", "") - .unwrap() - )); + assert!( + !network_filter.matches_test( + &request::Request::new("http://example.net/adv", "http://subfoo.foo.com", "") + .unwrap() + ) + ); assert!(network_filter.matches_test( &request::Request::new("http://example.net/adv", "http://bar.com", "").unwrap() )); diff --git a/tests/unit/optimizer.rs b/tests/unit/optimizer.rs index d4779d20..ce1238c9 100644 --- a/tests/unit/optimizer.rs +++ b/tests/unit/optimizer.rs @@ -128,14 +128,16 @@ mod optimization_tests_pattern_group { "/analytics-v1. <+> /v1/pixel? <+> /api/v1/stat? <+> /v1/ads/*" ); - assert!(filter.matches_test( - &Request::new( - "https://example.com/v1/pixel?", - "https://my.leadpages.net", - "" + assert!( + filter.matches_test( + &Request::new( + "https://example.com/v1/pixel?", + "https://my.leadpages.net", + "" + ) + .unwrap() ) - .unwrap() - )); + ); assert_eq!(skipped.len(), 1); let filter = skipped.first().unwrap(); @@ -144,14 +146,16 @@ mod optimization_tests_pattern_group { "/analytics/v1/*$domain=~my.leadpages.net" ); - assert!(filter.matches_test( - &Request::new( - "https://example.com/analytics/v1/foobar", - "https://foo.leadpages.net", - "" + assert!( + filter.matches_test( + &Request::new( + "https://example.com/analytics/v1/foobar", + "https://foo.leadpages.net", + "" + ) + .unwrap() ) - .unwrap() - )) + ) } } @@ -426,14 +430,16 @@ mod optimization_tests_pattern_group { "/analytics-v1. <+> /v1/pixel? <+> /api/v1/stat? <+> /v1/ads/*" ); - assert!(filter.matches_test( - &Request::new( - "https://example.com/v1/pixel?", - "https://my.leadpages.net", - "" + assert!( + filter.matches_test( + &Request::new( + "https://example.com/v1/pixel?", + "https://my.leadpages.net", + "" + ) + .unwrap() ) - .unwrap() - )); + ); assert_eq!(skipped.len(), 1); let filter = skipped.first().unwrap(); @@ -442,14 +448,16 @@ mod optimization_tests_pattern_group { "/analytics/v1/*$domain=~my.leadpages.net" ); - assert!(filter.matches_test( - &Request::new( - "https://example.com/analytics/v1/foobar", - "https://foo.leadpages.net", - "" + assert!( + filter.matches_test( + &Request::new( + "https://example.com/analytics/v1/foobar", + "https://foo.leadpages.net", + "" + ) + .unwrap() ) - .unwrap() - )) + ) } } diff --git a/tests/unit/regex_manager.rs b/tests/unit/regex_manager.rs index 739781dd..c8ae41a9 100644 --- a/tests/unit/regex_manager.rs +++ b/tests/unit/regex_manager.rs @@ -2,7 +2,7 @@ mod tests { use super::super::*; - use crate::{request, Engine}; + use crate::{Engine, request}; use mock_instant::thread_local::MockClock; diff --git a/tests/unit/resources/resource_assembler.rs b/tests/unit/resources/resource_assembler.rs index f4d6c497..78d9be3f 100644 --- a/tests/unit/resources/resource_assembler.rs +++ b/tests/unit/resources/resource_assembler.rs @@ -185,8 +185,11 @@ mod tests { ); assert_eq!( std::str::from_utf8( - &BASE64_STANDARD.decode(&reserialized[20].content).expect("decode base64 content") - ).expect("convert to utf8 string"), + &BASE64_STANDARD + .decode(&reserialized[20].content) + .expect("decode base64 content") + ) + .expect("convert to utf8 string"), "(function() {\nif ( window !== window.top ) {\nreturn;\n}\nvar tstart;\nvar ttl = 30000;\nvar delay = 0;\nvar delayStep = 50;\nvar buster = function() {\nvar docEl = document.documentElement,\nbodyEl = document.body,\nvw = Math.min(docEl.clientWidth, window.innerWidth),\nvh = Math.min(docEl.clientHeight, window.innerHeight),\ntol = Math.min(vw, vh) * 0.05,\nel = document.elementFromPoint(vw/2, vh/2),\nstyle, rect;\nfor (;;) {\nif ( el === null || el.parentNode === null || el === bodyEl ) {\nbreak;\n}\nstyle = window.getComputedStyle(el);\nif ( parseInt(style.zIndex, 10) >= 1000 || style.position === 'fixed' ) {\nrect = el.getBoundingClientRect();\nif ( rect.left <= tol && rect.top <= tol && (vw - rect.right) <= tol && (vh - rect.bottom) < tol ) {\nel.parentNode.removeChild(el);\ntstart = Date.now();\nel = document.elementFromPoint(vw/2, vh/2);\nbodyEl.style.setProperty('overflow', 'auto', 'important');\ndocEl.style.setProperty('overflow', 'auto', 'important');\ncontinue;\n}\n}\nel = el.parentNode;\n}\nif ( (Date.now() - tstart) < ttl ) {\ndelay = Math.min(delay + delayStep, 1000);\nsetTimeout(buster, delay);\n}\n};\nvar domReady = function(ev) {\nif ( ev ) {\ndocument.removeEventListener(ev.type, domReady);\n}\ntstart = Date.now();\nsetTimeout(buster, delay);\n};\nif ( document.readyState === 'loading' ) {\ndocument.addEventListener('DOMContentLoaded', domReady);\n} else {\ndomReady();\n}\n})();\n", ); @@ -195,8 +198,11 @@ mod tests { assert_eq!(reserialized[6].kind, ResourceType::Template); assert_eq!( std::str::from_utf8( - &BASE64_STANDARD.decode(&reserialized[6].content).expect("decode base64 content") - ).expect("convert to utf8 string"), + &BASE64_STANDARD + .decode(&reserialized[6].content) + .expect("decode base64 content") + ) + .expect("convert to utf8 string"), "(function() {\nconst rawPrunePaths = '{{1}}';\nconst rawNeedlePaths = '{{2}}';\nconst prunePaths = rawPrunePaths !== '{{1}}' && rawPrunePaths !== ''\n? rawPrunePaths.split(/ +/)\n: [];\nlet needlePaths;\nlet log, reLogNeedle;\nif ( prunePaths.length !== 0 ) {\nneedlePaths = prunePaths.length !== 0 &&\nrawNeedlePaths !== '{{2}}' && rawNeedlePaths !== ''\n? rawNeedlePaths.split(/ +/)\n: [];\n} else {\nlog = console.log.bind(console);\nlet needle;\nif ( rawNeedlePaths === '' || rawNeedlePaths === '{{2}}' ) {\nneedle = '.?';\n} else if ( rawNeedlePaths.charAt(0) === '/' && rawNeedlePaths.slice(-1) === '/' ) {\nneedle = rawNeedlePaths.slice(1, -1);\n} else {\nneedle = rawNeedlePaths.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\nreLogNeedle = new RegExp(needle);\n}\nconst findOwner = function(root, path, prune = false) {\nlet owner = root;\nlet chain = path;\nfor (;;) {\nif ( typeof owner !== 'object' || owner === null ) {\nreturn false;\n}\nconst pos = chain.indexOf('.');\nif ( pos === -1 ) {\nif ( prune === false ) {\nreturn owner.hasOwnProperty(chain);\n}\nif ( chain === '*' ) {\nfor ( const key in owner ) {\nif ( owner.hasOwnProperty(key) === false ) { continue; }\ndelete owner[key];\n}\n} else if ( owner.hasOwnProperty(chain) ) {\ndelete owner[chain];\n}\nreturn true;\n}\nconst prop = chain.slice(0, pos);\nif (\nprop === '[]' && Array.isArray(owner) ||\nprop === '*' && owner instanceof Object\n) {\nconst next = chain.slice(pos + 1);\nlet found = false;\nfor ( const key of Object.keys(owner) ) {\nfound = findOwner(owner[key], next, prune) || found;\n}\nreturn found;\n}\nif ( owner.hasOwnProperty(prop) === false ) { return false; }\nowner = owner[prop];\nchain = chain.slice(pos + 1);\n}\n};\nconst mustProcess = function(root) {\nfor ( const needlePath of needlePaths ) {\nif ( findOwner(root, needlePath) === false ) {\nreturn false;\n}\n}\nreturn true;\n};\nconst pruner = function(o) {\nif ( log !== undefined ) {\nconst json = JSON.stringify(o, null, 2);\nif ( reLogNeedle.test(json) ) {\nlog('uBO:', location.hostname, json);\n}\nreturn o;\n}\nif ( mustProcess(o) === false ) { return o; }\nfor ( const path of prunePaths ) {\nfindOwner(o, path, true);\n}\nreturn o;\n};\nJSON.parse = new Proxy(JSON.parse, {\napply: function() {\nreturn pruner(Reflect.apply(...arguments));\n},\n});\nResponse.prototype.json = new Proxy(Response.prototype.json, {\napply: function() {\nreturn Reflect.apply(...arguments).then(o => pruner(o));\n},\n});\n})();\n", ); } @@ -273,8 +279,11 @@ mod tests { ); assert_eq!( std::str::from_utf8( - &BASE64_STANDARD.decode(&reserialized[18].content).expect("decode base64 content") - ).expect("convert to utf8 string"), + &BASE64_STANDARD + .decode(&reserialized[18].content) + .expect("decode base64 content") + ) + .expect("convert to utf8 string"), "(function() {\nif ( window !== window.top ) {\nreturn;\n}\nvar tstart;\nvar ttl = 30000;\nvar delay = 0;\nvar delayStep = 50;\nvar buster = function() {\nvar docEl = document.documentElement,\nbodyEl = document.body,\nvw = Math.min(docEl.clientWidth, window.innerWidth),\nvh = Math.min(docEl.clientHeight, window.innerHeight),\ntol = Math.min(vw, vh) * 0.05,\nel = document.elementFromPoint(vw/2, vh/2),\nstyle, rect;\nfor (;;) {\nif ( el === null || el.parentNode === null || el === bodyEl ) {\nbreak;\n}\nstyle = window.getComputedStyle(el);\nif ( parseInt(style.zIndex, 10) >= 1000 || style.position === 'fixed' ) {\nrect = el.getBoundingClientRect();\nif ( rect.left <= tol && rect.top <= tol && (vw - rect.right) <= tol && (vh - rect.bottom) < tol ) {\nel.parentNode.removeChild(el);\ntstart = Date.now();\nel = document.elementFromPoint(vw/2, vh/2);\nbodyEl.style.setProperty('overflow', 'auto', 'important');\ndocEl.style.setProperty('overflow', 'auto', 'important');\ncontinue;\n}\n}\nel = el.parentNode;\n}\nif ( (Date.now() - tstart) < ttl ) {\ndelay = Math.min(delay + delayStep, 1000);\nsetTimeout(buster, delay);\n}\n};\nvar domReady = function(ev) {\nif ( ev ) {\ndocument.removeEventListener(ev.type, domReady);\n}\ntstart = Date.now();\nsetTimeout(buster, delay);\n};\nif ( document.readyState === 'loading' ) {\ndocument.addEventListener('DOMContentLoaded', domReady);\n} else {\ndomReady();\n}\n})();\n", ); } diff --git a/tests/unit/resources/resource_storage.rs b/tests/unit/resources/resource_storage.rs index 2052705e..26b0ce33 100644 --- a/tests/unit/resources/resource_storage.rs +++ b/tests/unit/resources/resource_storage.rs @@ -389,12 +389,18 @@ mod scriptlet_storage_tests { ); assert_eq!( - resources.get_scriptlet_resources([("abort-on-property-read, write tests", Default::default())]), + resources.get_scriptlet_resources([( + "abort-on-property-read, write tests", + Default::default() + )]), "try {\n(function() {confirm(\"Do you want to write tests?\");})();\n} catch ( e ) { }\n", ); assert_eq!( - resources.get_scriptlet_resources([("abort-on-property-read.js, block advertisements", Default::default())]), + resources.get_scriptlet_resources([( + "abort-on-property-read.js, block advertisements", + Default::default() + )]), "try {\n(function() {confirm(\"Do you want to block advertisements?\");})();\n} catch ( e ) { }\n", ); @@ -414,12 +420,16 @@ mod scriptlet_storage_tests { ); assert_eq!( - resources.get_scriptlet_resources([("googletagservices_gpt, test1", Default::default())]), + resources + .get_scriptlet_resources([("googletagservices_gpt, test1", Default::default())]), "function gpt(a1 = '', a2 = '') {console.log(a1, a2)}\ntry {\ngpt(\"test1\")\n} catch ( e ) { }\n", ); assert_eq!( - resources.get_scriptlet_resources([("googletagservices.com/gpt, test1, test2", Default::default())]), + resources.get_scriptlet_resources([( + "googletagservices.com/gpt, test1, test2", + Default::default() + )]), "function gpt(a1 = '', a2 = '') {console.log(a1, a2)}\ntry {\ngpt(\"test1\", \"test2\")\n} catch ( e ) { }\n", ); @@ -786,7 +796,10 @@ mod scriptlet_storage_tests { "" ); - assert_eq!(resources.get_scriptlet_resources([("test, arg1, arg2", PERM01)]), "permissioned\na\ncommon\nb\nfunction test() {}\ntry {\ntest(\"arg1\", \"arg2\")\n} catch ( e ) { }\n"); + assert_eq!( + resources.get_scriptlet_resources([("test, arg1, arg2", PERM01)]), + "permissioned\na\ncommon\nb\nfunction test() {}\ntry {\ntest(\"arg1\", \"arg2\")\n} catch ( e ) { }\n" + ); // Note: `test` still gets inserted as a dependency before it becomes apparent that // `permissioned` is not authorized. However, this shouldn't have much detrimental effect. @@ -794,15 +807,28 @@ mod scriptlet_storage_tests { resources.get_scriptlet_resources([("test-wrapper", Default::default())]), "function test() {}\n" ); - assert_eq!(resources.get_scriptlet_resources([("test-wrapper", PERM01)]), "function test() {}\npermissioned\na\ncommon\nb\nfunction testWrapper() { test(arguments) }\ntry {\ntestWrapper()\n} catch ( e ) { }\n"); + assert_eq!( + resources.get_scriptlet_resources([("test-wrapper", PERM01)]), + "function test() {}\npermissioned\na\ncommon\nb\nfunction testWrapper() { test(arguments) }\ntry {\ntestWrapper()\n} catch ( e ) { }\n" + ); - assert_eq!(resources.get_scriptlet_resources([("test", PERM01), ("test-wrapper", PERM01)]), "permissioned\na\ncommon\nb\nfunction test() {}\nfunction testWrapper() { test(arguments) }\ntry {\ntest()\n} catch ( e ) { }\ntry {\ntestWrapper()\n} catch ( e ) { }\n"); + assert_eq!( + resources.get_scriptlet_resources([("test", PERM01), ("test-wrapper", PERM01)]), + "permissioned\na\ncommon\nb\nfunction test() {}\nfunction testWrapper() { test(arguments) }\ntry {\ntest()\n} catch ( e ) { }\ntry {\ntestWrapper()\n} catch ( e ) { }\n" + ); assert_eq!( resources.get_scriptlet_resources([("shared, argument", Default::default())]), "a\ncommon\nb\nfunction shared() { }\ntry {\nshared(\"argument\")\n} catch ( e ) { }\n" ); - assert_eq!(resources.get_scriptlet_resources([("test, 1", PERM01), ("test-wrapper, 2", PERM01), ("shared, 3", Default::default())]), "permissioned\na\ncommon\nb\nfunction test() {}\nfunction testWrapper() { test(arguments) }\nfunction shared() { }\ntry {\ntest(\"1\")\n} catch ( e ) { }\ntry {\ntestWrapper(\"2\")\n} catch ( e ) { }\ntry {\nshared(\"3\")\n} catch ( e ) { }\n"); + assert_eq!( + resources.get_scriptlet_resources([ + ("test, 1", PERM01), + ("test-wrapper, 2", PERM01), + ("shared, 3", Default::default()) + ]), + "permissioned\na\ncommon\nb\nfunction test() {}\nfunction testWrapper() { test(arguments) }\nfunction shared() { }\ntry {\ntest(\"1\")\n} catch ( e ) { }\ntry {\ntestWrapper(\"2\")\n} catch ( e ) { }\ntry {\nshared(\"3\")\n} catch ( e ) { }\n" + ); } } @@ -846,21 +872,29 @@ mod shared_storage_tests { shared_storage: Rc::clone(&shared_storage), }); - assert!(engine1 - .url_cosmetic_resources("https://example1.com") - .injected_script - .contains("success!")); - assert!(!engine1 - .url_cosmetic_resources("https://example2.com") - .injected_script - .contains("success!")); - assert!(!engine2 - .url_cosmetic_resources("https://example1.com") - .injected_script - .contains("success!")); - assert!(engine2 - .url_cosmetic_resources("https://example2.com") - .injected_script - .contains("success!")); + assert!( + engine1 + .url_cosmetic_resources("https://example1.com") + .injected_script + .contains("success!") + ); + assert!( + !engine1 + .url_cosmetic_resources("https://example2.com") + .injected_script + .contains("success!") + ); + assert!( + !engine2 + .url_cosmetic_resources("https://example1.com") + .injected_script + .contains("success!") + ); + assert!( + engine2 + .url_cosmetic_resources("https://example2.com") + .injected_script + .contains("success!") + ); } } From c152adbb4250d12578dd39e09a1beaf61dc8a050 Mon Sep 17 00:00:00 2001 From: gvozdvmozgu Date: Mon, 27 Apr 2026 10:42:10 -0700 Subject: [PATCH 4/6] Address Clippy warnings --- js/src/lib.rs | 14 +++---- src/blocker.rs | 68 +++++++++++++++---------------- src/content_blocking.rs | 55 ++++++++++++------------- src/filters/fb_network_builder.rs | 6 +-- src/filters/network.rs | 28 ++++++------- src/lists.rs | 26 +++++------- tests/unit/filters/cosmetic.rs | 36 ++++++++-------- 7 files changed, 110 insertions(+), 123 deletions(-) diff --git a/js/src/lib.rs b/js/src/lib.rs index aa1fb5af..6f18af41 100644 --- a/js/src/lib.rs +++ b/js/src/lib.rs @@ -74,7 +74,7 @@ impl FilterSet { ) -> Result<(), adblock::lists::FilterParseError> { self.0.borrow_mut().add_filter(filter, opts) } - fn into_content_blocking( + fn content_blocking_rules( &self, ) -> Result<(Vec, Vec), ()> { self.0.borrow().clone().into_content_blocking() @@ -139,7 +139,7 @@ struct ContentBlockingConversionResult { fn filter_set_into_content_blocking(mut cx: FunctionContext) -> JsResult { let this = cx.argument::>(0)?; - match this.into_content_blocking() { + match this.content_blocking_rules() { Ok((cb_rules, filters_used)) => { let r = ContentBlockingConversionResult { content_blocking_rules: cb_rules, @@ -147,7 +147,7 @@ fn filter_set_into_content_blocking(mut cx: FunctionContext) -> JsResult return Ok(JsUndefined::new(&mut cx).upcast()), + Err(_) => Ok(JsUndefined::new(&mut cx).upcast()), } } @@ -262,7 +262,7 @@ fn engine_deserialize(mut cx: FunctionContext) -> JsResult { let serialized_handle = cx.argument::(1)?; if let Ok(mut engine) = this.0.lock() { - let _result = engine.deserialize(&serialized_handle.as_slice(&mut cx)); + let _result = engine.deserialize(serialized_handle.as_slice(&cx)); } Ok(JsNull::new(&mut cx)) @@ -340,13 +340,13 @@ fn ublock_resources(mut cx: FunctionContext) -> JsResult { }; let mut resources = assemble_web_accessible_resources( - &Path::new(&web_accessible_resource_dir), - &Path::new(&redirect_resources_path), + Path::new(&web_accessible_resource_dir), + Path::new(&redirect_resources_path), ); if let Some(scriptlets_path) = scriptlets_path { #[allow(deprecated)] resources.extend( - adblock::resources::resource_assembler::assemble_scriptlet_resources(&Path::new( + adblock::resources::resource_assembler::assemble_scriptlet_resources(Path::new( &scriptlets_path, )), ); diff --git a/src/blocker.rs b/src/blocker.rs index 4805fd87..2856519a 100644 --- a/src/blocker.rs +++ b/src/blocker.rs @@ -227,38 +227,37 @@ impl Blocker { let redirect_resource = { let mut exceptions = vec![]; for redirect_filter in redirect_filters.iter() { - if redirect_filter.is_exception() { - if let Some(redirect) = redirect_filter.modifier_option.as_ref() { - exceptions.push(redirect); - } + if redirect_filter.is_exception() + && let Some(redirect) = redirect_filter.modifier_option.as_ref() + { + exceptions.push(redirect); } } let mut resource_and_priority = None; for redirect_filter in redirect_filters.iter() { - if !redirect_filter.is_exception() { - if let Some(redirect) = redirect_filter.modifier_option.as_ref() { - if !exceptions.contains(&redirect) { - // parse redirect + priority - let (resource, priority) = - if let Some(idx) = find_char_reverse(b':', redirect.as_bytes()) { - let priority_str = &redirect[idx + 1..]; - let resource = &redirect[..idx]; - if let Ok(priority) = priority_str.parse::() { - (resource, priority) - } else { - (&redirect[..], 0) - } - } else { - (&redirect[..], 0) - }; - if let Some((_, p1)) = resource_and_priority { - if priority > p1 { - resource_and_priority = Some((resource, priority)); - } + if !redirect_filter.is_exception() + && let Some(redirect) = redirect_filter.modifier_option.as_ref() + && !exceptions.contains(&redirect) + { + // parse redirect + priority + let (resource, priority) = + if let Some(idx) = find_char_reverse(b':', redirect.as_bytes()) { + let priority_str = &redirect[idx + 1..]; + let resource = &redirect[..idx]; + if let Ok(priority) = priority_str.parse::() { + (resource, priority) } else { - resource_and_priority = Some((resource, priority)); + (&redirect[..], 0) } + } else { + (&redirect[..], 0) + }; + if let Some((_, p1)) = resource_and_priority { + if priority > p1 { + resource_and_priority = Some((resource, priority)); } + } else { + resource_and_priority = Some((resource, priority)); } } } @@ -350,11 +349,12 @@ impl Blocker { for removeparam_filter in filters { if let Some(removeparam) = &removeparam_filter.modifier_option { params.iter_mut().for_each(|(param, include)| { - if let QParam::KeyValue(k, v) = param { - if !v.is_empty() && k == removeparam { - *include = false; - rewrite = true; - } + if let QParam::KeyValue(k, v) = param + && !v.is_empty() + && k == removeparam + { + *include = false; + rewrite = true; } }); } @@ -420,10 +420,10 @@ impl Blocker { return None; } } - } else if filter.is_csp() { - if let Some(csp_directive) = &filter.modifier_option { - enabled_directives.insert(csp_directive); - } + } else if filter.is_csp() + && let Some(csp_directive) = &filter.modifier_option + { + enabled_directives.insert(csp_directive); } } diff --git a/src/content_blocking.rs b/src/content_blocking.rs index 2489aac1..c9de517b 100644 --- a/src/content_blocking.rs +++ b/src/content_blocking.rs @@ -546,34 +546,33 @@ impl TryFrom for CbRuleEquivalent { return Err(CbRuleCreationFailure::RuleContainsNonASCII); } - if let Some(resource_types) = &single_rule.trigger.resource_type { - if resource_types.len() > 1 - && resource_types.contains(&CbResourceType::Document) - && single_rule.trigger.load_type.is_empty() - { - let mut non_doc_types = resource_types.clone(); - non_doc_types.remove(&CbResourceType::Document); - let rule_clone = single_rule.clone(); - let non_doc_rule = CbRule { - trigger: CbTrigger { - resource_type: Some(non_doc_types), - ..rule_clone.trigger - }, - ..rule_clone - }; - let mut doc_type = HashSet::new(); - doc_type.insert(CbResourceType::Document); - let just_doc_rule = CbRule { - trigger: CbTrigger { - resource_type: Some(doc_type), - load_type: vec![CbLoadType::ThirdParty], - ..single_rule.trigger - }, - ..single_rule - }; - - return Ok(Self::SplitDocument(non_doc_rule, just_doc_rule)); - } + if let Some(resource_types) = &single_rule.trigger.resource_type + && resource_types.len() > 1 + && resource_types.contains(&CbResourceType::Document) + && single_rule.trigger.load_type.is_empty() + { + let mut non_doc_types = resource_types.clone(); + non_doc_types.remove(&CbResourceType::Document); + let rule_clone = single_rule.clone(); + let non_doc_rule = CbRule { + trigger: CbTrigger { + resource_type: Some(non_doc_types), + ..rule_clone.trigger + }, + ..rule_clone + }; + let mut doc_type = HashSet::new(); + doc_type.insert(CbResourceType::Document); + let just_doc_rule = CbRule { + trigger: CbTrigger { + resource_type: Some(doc_type), + load_type: vec![CbLoadType::ThirdParty], + ..single_rule.trigger + }, + ..single_rule + }; + + return Ok(Self::SplitDocument(non_doc_rule, just_doc_rule)); } Ok(Self::SingleRule(single_rule)) diff --git a/src/filters/fb_network_builder.rs b/src/filters/fb_network_builder.rs index 6b4acc43..0f7489b7 100644 --- a/src/filters/fb_network_builder.rs +++ b/src/filters/fb_network_builder.rs @@ -97,7 +97,7 @@ impl<'a> FlatSerialize<'a, EngineFlatBuilder<'a>> for &NetworkFilter { .as_ref() .map(|v| builder.create_string(v.as_str())); - let network_filter = fb::NetworkFilter::create( + fb::NetworkFilter::create( builder.raw_builder(), &fb::NetworkFilterArgs { mask: network_filter.mask.bits(), @@ -109,9 +109,7 @@ impl<'a> FlatSerialize<'a, EngineFlatBuilder<'a>> for &NetworkFilter { tag, raw_line, }, - ); - - network_filter + ) } } diff --git a/src/filters/network.rs b/src/filters/network.rs index 4e23ca58..523fb025 100644 --- a/src/filters/network.rs +++ b/src/filters/network.rs @@ -869,12 +869,10 @@ impl NetworkFilter { if self.opt_domains.is_some() && self.opt_not_domains.is_none() && self.opt_domains.as_ref().map(|d| d.len()) == Some(1) + && let Some(domains) = self.opt_domains.as_ref() + && let Some(domain) = domains.first() { - if let Some(domains) = self.opt_domains.as_ref() { - if let Some(domain) = domains.first() { - tokens_buffer.push(*domain); - } - } + tokens_buffer.push(*domain); } // Get tokens from filter @@ -905,22 +903,22 @@ impl NetworkFilter { } } - if tokens_buffer.is_empty() && self.mask.contains(NetworkFilterMask::IS_REMOVEPARAM) { - if let Some(removeparam) = &self.modifier_option { - if VALID_PARAM.is_match(removeparam) { - utils::tokenize_to(&removeparam.to_ascii_lowercase(), tokens_buffer); - } - } + if tokens_buffer.is_empty() + && self.mask.contains(NetworkFilterMask::IS_REMOVEPARAM) + && let Some(removeparam) = &self.modifier_option + && VALID_PARAM.is_match(removeparam) + { + utils::tokenize_to(&removeparam.to_ascii_lowercase(), tokens_buffer); } // If we got no tokens for the filter/hostname part, then we will dispatch // this filter in multiple buckets based on the domains option. if tokens_buffer.is_empty() && self.opt_domains.is_some() && self.opt_not_domains.is_none() { - if let Some(opt_domains) = self.opt_domains.as_ref() { - if !opt_domains.is_empty() { - return FilterTokens::OptDomains(opt_domains); - } + if let Some(opt_domains) = self.opt_domains.as_ref() + && !opt_domains.is_empty() + { + return FilterTokens::OptDomains(opt_domains); } FilterTokens::Empty } else { diff --git a/src/lists.rs b/src/lists.rs index 857b41e8..2a431aed 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -192,23 +192,19 @@ impl FilterListMetadata { /// with valid metadata content will be added. Previously added information will not be /// rewritten. fn try_add(&mut self, line: &str) { - if let Some(kv) = line.strip_prefix("! ") { - if let Some((key, value)) = kv.split_once(": ") { - match key { - "Homepage" if self.homepage.is_none() => { - self.homepage = Some(value.to_string()) - } - "Title" if self.title.is_none() => self.title = Some(value.to_string()), - "Expires" if self.expires.is_none() => { - if let Ok(expires) = ExpiresInterval::try_from(value) { - self.expires = Some(expires); - } - } - "Redirect" if self.redirect.is_none() => { - self.redirect = Some(value.to_string()) + if let Some(kv) = line.strip_prefix("! ") + && let Some((key, value)) = kv.split_once(": ") + { + match key { + "Homepage" if self.homepage.is_none() => self.homepage = Some(value.to_string()), + "Title" if self.title.is_none() => self.title = Some(value.to_string()), + "Expires" if self.expires.is_none() => { + if let Ok(expires) = ExpiresInterval::try_from(value) { + self.expires = Some(expires); } - _ => (), } + "Redirect" if self.redirect.is_none() => self.redirect = Some(value.to_string()), + _ => (), } } } diff --git a/tests/unit/filters/cosmetic.rs b/tests/unit/filters/cosmetic.rs index d71ca0be..02fb0e0f 100644 --- a/tests/unit/filters/cosmetic.rs +++ b/tests/unit/filters/cosmetic.rs @@ -960,41 +960,37 @@ mod matching_tests { return false; } - if let Some(ref filter_not_hostnames) = self.not_hostnames { - if request_hostnames + if let Some(ref filter_not_hostnames) = self.not_hostnames + && request_hostnames .iter() .any(|hash| bin_lookup(filter_not_hostnames, *hash)) - { - return false; - } + { + return false; } - if let Some(ref filter_not_entities) = self.not_entities { - if request_entities + if let Some(ref filter_not_entities) = self.not_entities + && request_entities .iter() .any(|hash| bin_lookup(filter_not_entities, *hash)) - { - return false; - } + { + return false; } if self.hostnames.is_some() || self.entities.is_some() { - if let Some(ref filter_hostnames) = self.hostnames { - if request_hostnames + if let Some(ref filter_hostnames) = self.hostnames + && request_hostnames .iter() .any(|hash| bin_lookup(filter_hostnames, *hash)) - { - return true; - } + { + return true; } - if let Some(ref filter_entities) = self.entities { - if request_entities + if let Some(ref filter_entities) = self.entities + && request_entities .iter() .any(|hash| bin_lookup(filter_entities, *hash)) - { - return true; - } + { + return true; } return false; From 3cd37a6953d37bb8efa6bc886d3a73246da26180 Mon Sep 17 00:00:00 2001 From: gvozdvmozgu Date: Mon, 27 Apr 2026 10:45:33 -0700 Subject: [PATCH 5/6] Simplify host parsing borrow lifetime --- src/url_parser/parser.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/url_parser/parser.rs b/src/url_parser/parser.rs index c46e3648..45224dc0 100644 --- a/src/url_parser/parser.rs +++ b/src/url_parser/parser.rs @@ -515,18 +515,13 @@ impl Parser { remaining.next(); bytes += c.len_utf8(); } - let replaced: String; - let host_str; - { - let host_input = input.by_ref().take(non_ignored_chars); - if has_ignored_chars { - replaced = host_input.collect(); - host_str = &*replaced - } else { - for _ in host_input {} - host_str = &input_str[..bytes] - } - } + let host_input = input.by_ref().take(non_ignored_chars); + let host_str: &str = if has_ignored_chars { + &host_input.collect::() + } else { + for _ in host_input {} + &input_str[..bytes] + }; if host_str.is_ascii() { write!(&mut self.serialization, "{host_str}").unwrap(); From c05ec2e496818bf17fecc1e87cf91770cd2ba138 Mon Sep 17 00:00:00 2001 From: gvozdvmozgu Date: Mon, 27 Apr 2026 10:46:36 -0700 Subject: [PATCH 6/6] Clarify host input consumption --- src/url_parser/parser.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/url_parser/parser.rs b/src/url_parser/parser.rs index 45224dc0..25537d87 100644 --- a/src/url_parser/parser.rs +++ b/src/url_parser/parser.rs @@ -519,7 +519,7 @@ impl Parser { let host_str: &str = if has_ignored_chars { &host_input.collect::() } else { - for _ in host_input {} + host_input.for_each(drop); &input_str[..bytes] };