From 9d633192d6c1395c3fd61bf604ac23b7e70cd896 Mon Sep 17 00:00:00 2001 From: Mikhail Date: Wed, 17 Sep 2025 22:51:47 +0400 Subject: [PATCH] Update adblock crate to 0.10.3 (#31247) The adblock-rust changes to publish: https://github.com/brave/adblock-rust/pull/517 This should partially address the perf issue related to the resource memory usage. --- .../core/browser/adblock/rs/Cargo.toml | 2 +- third_party/rust/adblock/v0_10/BUILD.gn | 2 +- .../rust/adblock/v0_10/README.chromium | 4 +- .../rust/chromium_crates_io/Cargo.lock | 2 +- .../supply-chain/config.toml | 2 +- .../vendor/adblock-v0_10/.cargo_vcs_info.json | 2 +- .../vendor/adblock-v0_10/Cargo.lock | 2 +- .../vendor/adblock-v0_10/Cargo.toml | 2 +- .../vendor/adblock-v0_10/Cargo.toml.orig | 2 +- .../src/resources/resource_storage.rs | 85 +++++++++++++++---- 10 files changed, 79 insertions(+), 26 deletions(-) diff --git a/components/brave_shields/core/browser/adblock/rs/Cargo.toml b/components/brave_shields/core/browser/adblock/rs/Cargo.toml index 3adac3ebbee..0d69c08ba8c 100644 --- a/components/brave_shields/core/browser/adblock/rs/Cargo.toml +++ b/components/brave_shields/core/browser/adblock/rs/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" license = "MPL-2.0" [dependencies] -adblock = { version = "0.10.2", default-features = false, features = ["full-regex-handling", "regex-debug-info", "css-validation"] } +adblock = { version = "0.10.3", default-features = false, features = ["full-regex-handling", "regex-debug-info", "css-validation"] } cxx = "1.0" serde_json = "1.0" thiserror = "1.0" diff --git a/third_party/rust/adblock/v0_10/BUILD.gn b/third_party/rust/adblock/v0_10/BUILD.gn index 6eb0a86e16d..83252e7cc1e 100644 --- a/third_party/rust/adblock/v0_10/BUILD.gn +++ b/third_party/rust/adblock/v0_10/BUILD.gn @@ -51,7 +51,7 @@ cargo_crate("lib") { cargo_pkg_name = "adblock" cargo_pkg_description = "Native Rust module for Adblock Plus syntax (e.g. EasyList, EasyPrivacy) filter parsing and matching." cargo_pkg_repository = "https://github.com/brave/adblock-rust/" - cargo_pkg_version = "0.10.2" + cargo_pkg_version = "0.10.3" deps = [ "//brave/third_party/rust/base64/v0_22:lib", diff --git a/third_party/rust/adblock/v0_10/README.chromium b/third_party/rust/adblock/v0_10/README.chromium index e192f839b98..9855b338581 100644 --- a/third_party/rust/adblock/v0_10/README.chromium +++ b/third_party/rust/adblock/v0_10/README.chromium @@ -1,7 +1,7 @@ Name: adblock URL: https://crates.io/crates/adblock -Version: 0.10.2 -Revision: 082f2d61c940caf09e1d73ce88712ef038642bbe +Version: 0.10.3 +Revision: 3652b04666ebdf082d029f775d01fa1a575c1918 License: Mozilla-Public-License-2.0 License File: //brave/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/LICENSE Shipped: yes diff --git a/third_party/rust/chromium_crates_io/Cargo.lock b/third_party/rust/chromium_crates_io/Cargo.lock index 6ab4533a588..e47f5085faf 100644 --- a/third_party/rust/chromium_crates_io/Cargo.lock +++ b/third_party/rust/chromium_crates_io/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "adblock" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64", diff --git a/third_party/rust/chromium_crates_io/supply-chain/config.toml b/third_party/rust/chromium_crates_io/supply-chain/config.toml index 588068612a0..91e7c896872 100644 --- a/third_party/rust/chromium_crates_io/supply-chain/config.toml +++ b/third_party/rust/chromium_crates_io/supply-chain/config.toml @@ -65,7 +65,7 @@ ub-risk-4 = "ub-risk-4" [policy."adblock-cxx:1.0.0"] criteria = ["crypto-safe", "safe-to-deploy", "ub-risk-2"] -[policy."adblock:0.10.2"] +[policy."adblock:0.10.3"] criteria = ["crypto-safe", "safe-to-deploy", "ub-risk-2"] [policy."addchain:0.2.0"] criteria = ["crypto-safe", "safe-to-deploy", "ub-risk-2"] diff --git a/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/.cargo_vcs_info.json b/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/.cargo_vcs_info.json index 2f718fa7e67..cba6334900e 100644 --- a/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/.cargo_vcs_info.json +++ b/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/.cargo_vcs_info.json @@ -1,6 +1,6 @@ { "git": { - "sha1": "082f2d61c940caf09e1d73ce88712ef038642bbe" + "sha1": "3652b04666ebdf082d029f775d01fa1a575c1918" }, "path_in_vcs": "" } \ No newline at end of file diff --git a/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/Cargo.lock b/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/Cargo.lock index dbcb626ecd2..cd294e79248 100644 --- a/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/Cargo.lock +++ b/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "adblock" -version = "0.10.2" +version = "0.10.3" dependencies = [ "addr", "base64", diff --git a/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/Cargo.toml b/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/Cargo.toml index 9574852b0f6..8596bd48da7 100644 --- a/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/Cargo.toml +++ b/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/Cargo.toml @@ -12,7 +12,7 @@ [package] edition = "2021" name = "adblock" -version = "0.10.2" +version = "0.10.3" authors = [ "Anton Lazarev ", "Andrius Aucinas", diff --git a/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/Cargo.toml.orig b/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/Cargo.toml.orig index fb79ae10a5f..f468f38a8fd 100644 --- a/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/Cargo.toml.orig +++ b/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "adblock" -version = "0.10.2" +version = "0.10.3" authors = ["Anton Lazarev ", "Andrius Aucinas"] edition = "2021" diff --git a/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/src/resources/resource_storage.rs b/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/src/resources/resource_storage.rs index 39150000c61..9109d88463d 100644 --- a/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/src/resources/resource_storage.rs +++ b/third_party/rust/chromium_crates_io/vendor/adblock-v0_10/src/resources/resource_storage.rs @@ -9,11 +9,45 @@ use thiserror::Error; use super::{PermissionMask, Resource, ResourceType}; +#[derive(Clone)] +enum ResourceContent { + /// A valid utf8 string. Used for text/* mime types or for ResourceType:Template + Text(String), + + /// Raw content in the form of a byte array. Used for other mime types like + /// "image/gif" or "audio/mp3" + Raw(Vec), +} + +impl ResourceContent { + fn text_from_base64(base64: &str) -> Result { + let decoded = BASE64_STANDARD.decode(base64)?; + Ok(Self::Text(String::from_utf8(decoded)?)) + } + + fn raw_from_base64(base64: &str) -> Result { + let decoded = BASE64_STANDARD.decode(base64)?; + Ok(Self::Raw(decoded)) + } +} + +#[derive(Clone)] +/// A internal representation of a Resource to store. Stores the content +/// in the decoded form to use less memory. +/// See [Resource] for details +struct ResourceImpl { + name: String, + kind: ResourceType, + content: ResourceContent, + dependencies: Vec, + permission: PermissionMask, +} + /// Unified resource storage for both redirects and scriptlets. #[derive(Default)] pub struct ResourceStorage { /// Stores each resource by its canonical name - resources: HashMap, + resources: HashMap, /// Stores mappings from aliases to their canonical resource names aliases: HashMap, } @@ -130,16 +164,20 @@ impl ResourceStorage { /// Adds a resource to storage so that it can be retrieved later. pub fn add_resource(&mut self, resource: Resource) -> Result<(), AddResourceError> { + let resource_content: ResourceContent; + if let ResourceType::Mime(content_type) = &resource.kind { if !resource.dependencies.is_empty() && !content_type.supports_dependencies() { return Err(AddResourceError::ContentTypeDoesNotSupportDependencies); } - // Ensure the resource contents are valid base64 (and utf8 if applicable) - let decoded = BASE64_STANDARD.decode(&resource.content)?; if content_type.is_textual() { - let _ = String::from_utf8(decoded)?; + resource_content = ResourceContent::text_from_base64(&resource.content)?; + } else { + resource_content = ResourceContent::raw_from_base64(&resource.content)?; } + } else { + resource_content = ResourceContent::text_from_base64(&resource.content)?; } for ident in std::iter::once(&resource.name).chain(resource.aliases.iter()) { @@ -151,7 +189,14 @@ impl ResourceStorage { resource.aliases.iter().for_each(|alias| { self.aliases.insert(alias.clone(), resource.name.clone()); }); - self.resources.insert(resource.name.clone(), resource); + let resource_impl = ResourceImpl { + name: resource.name.clone(), + kind: resource.kind, + content: resource_content, + dependencies: resource.dependencies, + permission: resource.permission, + }; + self.resources.insert(resource.name, resource_impl); Ok(()) } @@ -176,11 +221,9 @@ impl ResourceStorage { let mut result = String::new(); for dep in deps.iter() { - if let Ok(decoded) = BASE64_STANDARD.decode(&dep.content) { - if let Ok(dep) = core::str::from_utf8(&decoded) { - result += dep; - result += "\n"; - } + if let ResourceContent::Text(content) = &dep.content { + result += content; + result += "\n"; } } @@ -197,7 +240,7 @@ impl ResourceStorage { fn recursive_dependencies<'a: 'b, 'b>( &'a self, new_dep: &str, - prev_deps: &mut Vec<&'b Resource>, + prev_deps: &mut Vec<&'b ResourceImpl>, filter_permission: PermissionMask, ) -> Result<(), ScriptletResourceError> { if prev_deps.iter().any(|dep| dep.name == new_dep) { @@ -221,7 +264,7 @@ impl ResourceStorage { &'a self, scriptlet_args: &str, filter_permission: PermissionMask, - required_deps: &mut Vec<&'b Resource>, + required_deps: &mut Vec<&'b ResourceImpl>, ) -> Result { // `unwrap` is safe because these are guaranteed valid at filter parsing. let scriptlet_args = parse_scriptlet_args(scriptlet_args).unwrap(); @@ -247,7 +290,12 @@ impl ResourceStorage { self.recursive_dependencies(dep, required_deps, filter_permission)?; } - let template = String::from_utf8(BASE64_STANDARD.decode(&resource.content)?)?; + let template = match &resource.content { + ResourceContent::Raw(_content) => { + return Err(ScriptletResourceError::ContentTypeNotInjectable); + } + ResourceContent::Text(content) => content.clone(), + }; if let Some(function_name) = extract_function_name(&template) { // newer function-style resource: pass args using function call syntax @@ -284,7 +332,12 @@ impl ResourceStorage { return None; } if let ResourceType::Mime(mime) = &resource.kind { - Some(format!("data:{};base64,{}", mime, &resource.content)) + let bytes = match &resource.content { + ResourceContent::Raw(content) => content, + ResourceContent::Text(content) => content.as_bytes(), + }; + let encoded = BASE64_STANDARD.encode(bytes); + Some(format!("data:{};base64,{}", mime, encoded)) } else { None } @@ -292,7 +345,7 @@ impl ResourceStorage { } /// Gets the resource associated with `resource_ident`, respecting aliases if necessary. - fn get_internal_resource(&self, resource_ident: &str) -> Option<&Resource> { + fn get_internal_resource(&self, resource_ident: &str) -> Option<&ResourceImpl> { let resource = if let Some(resource) = self.resources.get(resource_ident) { Some(resource) } else if let Some(canonical_name) = self.aliases.get(resource_ident) { @@ -308,7 +361,7 @@ impl ResourceStorage { &self, scriptlet_name: &str, filter_permission: PermissionMask, - ) -> Result<&Resource, ScriptletResourceError> { + ) -> Result<&ResourceImpl, ScriptletResourceError> { let resource = self .get_internal_resource(scriptlet_name) .ok_or(ScriptletResourceError::NoMatchingScriptlet)?;