From 458969cfab950ef6cd4dbfd3ce44801d617d8082 Mon Sep 17 00:00:00 2001 From: Anton Lazarev Date: Thu, 4 Aug 2022 11:56:07 -0700 Subject: [PATCH 1/6] add content blocking conversion method --- components/adblock_rust_ffi/Cargo.toml | 1 + components/adblock_rust_ffi/cbindgen.toml | 1 + components/adblock_rust_ffi/src/lib.h | 4 ++++ components/adblock_rust_ffi/src/lib.rs | 17 +++++++++++++++++ 4 files changed, 23 insertions(+) diff --git a/components/adblock_rust_ffi/Cargo.toml b/components/adblock_rust_ffi/Cargo.toml index 954e535bd74..ad4b7f5b366 100644 --- a/components/adblock_rust_ffi/Cargo.toml +++ b/components/adblock_rust_ffi/Cargo.toml @@ -17,6 +17,7 @@ name = "adblock" [features] cbindgen = [] +ios = ["adblock/content-blocking"] [profile.dev] panic = "abort" diff --git a/components/adblock_rust_ffi/cbindgen.toml b/components/adblock_rust_ffi/cbindgen.toml index d17ea2a6bcb..f517c8fdf2b 100644 --- a/components/adblock_rust_ffi/cbindgen.toml +++ b/components/adblock_rust_ffi/cbindgen.toml @@ -30,3 +30,4 @@ features = ["cbindgen"] prefix = "C_" [defines] +"feature = ios" = "IS_IOS" diff --git a/components/adblock_rust_ffi/src/lib.h b/components/adblock_rust_ffi/src/lib.h index d3d9ed78666..11c7b3cc9da 100644 --- a/components/adblock_rust_ffi/src/lib.h +++ b/components/adblock_rust_ffi/src/lib.h @@ -184,4 +184,8 @@ char* engine_hidden_class_id_selectors(struct C_Engine* engine, const char* const* exceptions, size_t exceptions_size); +#if defined(IS_IOS) +char* convert_rules_to_content_blocking(const char* rules); +#endif + #endif /* BRAVE_COMPONENTS_ADBLOCK_RUST_FFI_SRC_LIB_H_ */ diff --git a/components/adblock_rust_ffi/src/lib.rs b/components/adblock_rust_ffi/src/lib.rs index 853e1ac0dd5..66ab02d0b09 100644 --- a/components/adblock_rust_ffi/src/lib.rs +++ b/components/adblock_rust_ffi/src/lib.rs @@ -373,3 +373,20 @@ pub unsafe extern "C" fn engine_hidden_class_id_selectors( .expect("Error: CString::new()") .into_raw() } + +#[cfg(feature = "ios")] +#[no_mangle] +pub unsafe extern "C" fn convert_rules_to_content_blocking(rules: *const c_char) -> *mut c_char { + let rules = CStr::from_ptr(rules).to_str().unwrap_or_else(|_| { + eprintln!("Failed to parse filter list with invalid UTF-8 content"); + "" + }); + let mut filter_set = adblock::lists::FilterSet::new(true); + let metadata = filter_set.add_filter_list(&rules, Default::default()); + // `unwrap` is safe here because `into_content_blocking` only panics if the `FilterSet` was not + // created in debug mode + let (cb_rules, _) = filter_set.into_content_blocking().unwrap(); + CString::new(serde_json::to_string(cb_rules).unwrap_or_else(|_| "".into())) + .expect("Error: CString::new()") + .into_raw() +} From 5fe358256c134511f89129ea14fc42f839124965 Mon Sep 17 00:00:00 2001 From: Kyle Hickinson Date: Thu, 4 Aug 2022 16:11:58 -0400 Subject: [PATCH 2/6] [iOS] Add wrapper to call convert_rules_to_content_blocking --- components/adblock_rust_ffi/cbindgen.toml | 2 +- components/adblock_rust_ffi/src/lib.h | 2 +- ios/browser/api/brave_shields/adblock_engine.h | 4 ++++ ios/browser/api/brave_shields/adblock_engine.mm | 6 ++++++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/components/adblock_rust_ffi/cbindgen.toml b/components/adblock_rust_ffi/cbindgen.toml index f517c8fdf2b..d976009c16e 100644 --- a/components/adblock_rust_ffi/cbindgen.toml +++ b/components/adblock_rust_ffi/cbindgen.toml @@ -30,4 +30,4 @@ features = ["cbindgen"] prefix = "C_" [defines] -"feature = ios" = "IS_IOS" +"feature = ios" = "BUILDFLAG(IS_IOS)" diff --git a/components/adblock_rust_ffi/src/lib.h b/components/adblock_rust_ffi/src/lib.h index 11c7b3cc9da..958088f0658 100644 --- a/components/adblock_rust_ffi/src/lib.h +++ b/components/adblock_rust_ffi/src/lib.h @@ -184,7 +184,7 @@ char* engine_hidden_class_id_selectors(struct C_Engine* engine, const char* const* exceptions, size_t exceptions_size); -#if defined(IS_IOS) +#if BUILDFLAG(IS_IOS) char* convert_rules_to_content_blocking(const char* rules); #endif diff --git a/ios/browser/api/brave_shields/adblock_engine.h b/ios/browser/api/brave_shields/adblock_engine.h index 0e304408e98..1be1bc5bb9a 100644 --- a/ios/browser/api/brave_shields/adblock_engine.h +++ b/ios/browser/api/brave_shields/adblock_engine.h @@ -100,6 +100,10 @@ OBJC_EXPORT /// The default domain resolver. @property(class, readonly) DomainResolverCallback defaultDomainResolver; +/// Converts ABP rules/filter sets into Content Blocker rules that can be used +/// with ``WKWebView`` ++ (NSString*)contentBlockerRulesFromFilterSet:(NSString*)filterSet; + @end NS_ASSUME_NONNULL_END diff --git a/ios/browser/api/brave_shields/adblock_engine.mm b/ios/browser/api/brave_shields/adblock_engine.mm index c5bc7d2f86a..da87e06c3d1 100644 --- a/ios/browser/api/brave_shields/adblock_engine.mm +++ b/ios/browser/api/brave_shields/adblock_engine.mm @@ -7,6 +7,7 @@ #include "base/strings/sys_string_conversions.h" #include "brave/base/mac/conversions.h" +#include "brave/components/adblock_rust_ffi/src/lib.h" #include "brave/components/adblock_rust_ffi/src/wrapper.h" #include "brave/components/brave_shields/common/adblock_domain_resolver.h" @@ -131,4 +132,9 @@ return brave_shields::AdBlockServiceDomainResolver; } ++ (NSString*)contentBlockerRulesFromFilterSet:(NSString*)filterSet { + return base::SysUTF8ToNSString(convert_rules_to_content_blocking( + base::SysNSStringToUTF8(filterSet).c_str())); +} + @end From ea596b16a3734d8b786ff4004781da14b5d47358 Mon Sep 17 00:00:00 2001 From: Anton Lazarev Date: Thu, 4 Aug 2022 14:15:11 -0700 Subject: [PATCH 3/6] pass ios feature to cargo build --- build/cargo.gni | 1 + build/rust/Cargo.lock | 1 + build/rust/Cargo.toml | 3 +++ script/cargo.py | 3 +++ 4 files changed, 8 insertions(+) diff --git a/build/cargo.gni b/build/cargo.gni index 0ef653b2cb1..062f707887f 100644 --- a/build/cargo.gni +++ b/build/cargo.gni @@ -127,6 +127,7 @@ template("cargo_build") { args += [ "--mac_deployment_target=" + mac_deployment_target ] } else if (is_ios) { args += [ "--ios_deployment_target=" + ios_deployment_target ] + args += [ "--features=" + "ios" ] } if (defined(_rustflags)) { diff --git a/build/rust/Cargo.lock b/build/rust/Cargo.lock index 9c75198050a..61cb851d1ee 100644 --- a/build/rust/Cargo.lock +++ b/build/rust/Cargo.lock @@ -21,6 +21,7 @@ dependencies = [ "rmp-serde 0.15.5", "seahash", "serde", + "serde_json", "twoway", "url", ] diff --git a/build/rust/Cargo.toml b/build/rust/Cargo.toml index 29c84b6c9a7..c7ab2088eaf 100644 --- a/build/rust/Cargo.toml +++ b/build/rust/Cargo.toml @@ -18,6 +18,9 @@ crate-type = [ "staticlib" ] name = "brave_rust" path = "lib.rs" +[features] +ios = ["adblock-ffi/ios"] + [profile.dev] panic = "abort" diff --git a/script/cargo.py b/script/cargo.py index d7d872ef5b3..fef49d7ff7c 100755 --- a/script/cargo.py +++ b/script/cargo.py @@ -63,6 +63,8 @@ def run_cargo(command, args): cargo_args.append("--manifest-path=" + args.manifest_path) cargo_args.append("--target-dir=" + args.build_path) cargo_args.append("--target=" + args.target) + if command == "build" and args.features is not None: + cargo_args.append("--features=" + args.features) subprocess.check_call(cargo_args, env=env) except subprocess.CalledProcessError as e: @@ -111,6 +113,7 @@ def parse_args(): parser.add_option("--rust_flag", action="append", dest="rust_flags", default=[]) + parser.add_option('--features') options, _ = parser.parse_args() From 53cf707ce6441d09673ceb109bb3c133acd9a8be Mon Sep 17 00:00:00 2001 From: Anton Lazarev Date: Thu, 4 Aug 2022 14:26:09 -0700 Subject: [PATCH 4/6] serde_json requires reference --- components/adblock_rust_ffi/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/adblock_rust_ffi/src/lib.rs b/components/adblock_rust_ffi/src/lib.rs index 66ab02d0b09..a481f6319ce 100644 --- a/components/adblock_rust_ffi/src/lib.rs +++ b/components/adblock_rust_ffi/src/lib.rs @@ -386,7 +386,7 @@ pub unsafe extern "C" fn convert_rules_to_content_blocking(rules: *const c_char) // `unwrap` is safe here because `into_content_blocking` only panics if the `FilterSet` was not // created in debug mode let (cb_rules, _) = filter_set.into_content_blocking().unwrap(); - CString::new(serde_json::to_string(cb_rules).unwrap_or_else(|_| "".into())) + CString::new(serde_json::to_string(&cb_rules).unwrap_or_else(|_| "".into())) .expect("Error: CString::new()") .into_raw() } From 6d8f189cdb942911278757a789b5a306a321288b Mon Sep 17 00:00:00 2001 From: Anton Lazarev Date: Thu, 4 Aug 2022 15:30:41 -0700 Subject: [PATCH 5/6] silence unused variable warning --- components/adblock_rust_ffi/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/adblock_rust_ffi/src/lib.rs b/components/adblock_rust_ffi/src/lib.rs index a481f6319ce..cab23b29421 100644 --- a/components/adblock_rust_ffi/src/lib.rs +++ b/components/adblock_rust_ffi/src/lib.rs @@ -382,7 +382,7 @@ pub unsafe extern "C" fn convert_rules_to_content_blocking(rules: *const c_char) "" }); let mut filter_set = adblock::lists::FilterSet::new(true); - let metadata = filter_set.add_filter_list(&rules, Default::default()); + filter_set.add_filter_list(&rules, Default::default()); // `unwrap` is safe here because `into_content_blocking` only panics if the `FilterSet` was not // created in debug mode let (cb_rules, _) = filter_set.into_content_blocking().unwrap(); From d57670938b8576b19beef1c795a11fdd72cf477e Mon Sep 17 00:00:00 2001 From: Kyle Hickinson Date: Fri, 5 Aug 2022 12:17:24 -0400 Subject: [PATCH 6/6] [iOS] Fix linker error and add wrapper function --- components/adblock_rust_ffi/src/wrapper.cc | 10 ++++++++++ components/adblock_rust_ffi/src/wrapper.h | 5 +++++ ios/browser/api/brave_shields/adblock_engine.mm | 5 ++--- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/components/adblock_rust_ffi/src/wrapper.cc b/components/adblock_rust_ffi/src/wrapper.cc index aa371d81aa5..ca83795b7e9 100644 --- a/components/adblock_rust_ffi/src/wrapper.cc +++ b/components/adblock_rust_ffi/src/wrapper.cc @@ -16,6 +16,16 @@ bool SetDomainResolver(DomainResolverCallback resolver) { return set_domain_resolver(resolver); } +#if BUILDFLAG(IS_IOS) +const std::string ConvertRulesToContentBlockingRules(const std::string& rules) { + char* content_blocking_json = + convert_rules_to_content_blocking(rules.c_str()); + const std::string result = std::string(content_blocking_json); + c_char_buffer_destroy(content_blocking_json); + return result; +} +#endif + FilterListMetadata::FilterListMetadata() = default; FilterListMetadata::FilterListMetadata(C_FilterListMetadata* metadata) { diff --git a/components/adblock_rust_ffi/src/wrapper.h b/components/adblock_rust_ffi/src/wrapper.h index 466e1f61956..48efd4af008 100644 --- a/components/adblock_rust_ffi/src/wrapper.h +++ b/components/adblock_rust_ffi/src/wrapper.h @@ -42,6 +42,11 @@ typedef C_DomainResolverCallback DomainResolverCallback; bool ADBLOCK_EXPORT SetDomainResolver(DomainResolverCallback resolver); +#if BUILDFLAG(IS_IOS) +const std::string ADBLOCK_EXPORT +ConvertRulesToContentBlockingRules(const std::string& rules); +#endif + typedef ADBLOCK_EXPORT struct FilterListMetadata { FilterListMetadata(); explicit FilterListMetadata(C_FilterListMetadata* metadata); diff --git a/ios/browser/api/brave_shields/adblock_engine.mm b/ios/browser/api/brave_shields/adblock_engine.mm index da87e06c3d1..a42bb255ecb 100644 --- a/ios/browser/api/brave_shields/adblock_engine.mm +++ b/ios/browser/api/brave_shields/adblock_engine.mm @@ -7,7 +7,6 @@ #include "base/strings/sys_string_conversions.h" #include "brave/base/mac/conversions.h" -#include "brave/components/adblock_rust_ffi/src/lib.h" #include "brave/components/adblock_rust_ffi/src/wrapper.h" #include "brave/components/brave_shields/common/adblock_domain_resolver.h" @@ -133,8 +132,8 @@ } + (NSString*)contentBlockerRulesFromFilterSet:(NSString*)filterSet { - return base::SysUTF8ToNSString(convert_rules_to_content_blocking( - base::SysNSStringToUTF8(filterSet).c_str())); + return base::SysUTF8ToNSString(adblock::ConvertRulesToContentBlockingRules( + base::SysNSStringToUTF8(filterSet))); } @end