From ba6526cb29a0ed2cfa87f8a2f6391284870fb351 Mon Sep 17 00:00:00 2001 From: Anton Lazarev Date: Sun, 17 May 2020 00:48:22 -0400 Subject: [PATCH] expose support for generichide --- Cargo.lock | 8 ++-- Cargo.toml | 2 +- examples/cpp/main.cpp | 87 +++++++++++++++++++++++++++++-------------- src/lib.h | 10 ++--- src/lib.rs | 10 ++--- src/wrapper.cpp | 4 +- src/wrapper.hpp | 2 +- 7 files changed, 78 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2be9ffa..84e201f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,8 +2,8 @@ # It is not intended for manual editing. [[package]] name = "adblock" -version = "0.2.6" -source = "git+https://github.com/brave/adblock-rust?rev=abd51752fab1f7aafb09d0fc410809b2b65abbf6#abd51752fab1f7aafb09d0fc410809b2b65abbf6" +version = "0.2.10" +source = "git+https://github.com/brave/adblock-rust?rev=27409e39687adfa68f883153c878a0d8f2d655e9#27409e39687adfa68f883153c878a0d8f2d655e9" dependencies = [ "addr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -30,7 +30,7 @@ dependencies = [ name = "adblock-ffi" version = "0.1.0" dependencies = [ - "adblock 0.2.6 (git+https://github.com/brave/adblock-rust?rev=abd51752fab1f7aafb09d0fc410809b2b65abbf6)", + "adblock 0.2.10 (git+https://github.com/brave/adblock-rust?rev=27409e39687adfa68f883153c878a0d8f2d655e9)", "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -817,7 +817,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] -"checksum adblock 0.2.6 (git+https://github.com/brave/adblock-rust?rev=abd51752fab1f7aafb09d0fc410809b2b65abbf6)" = "" +"checksum adblock 0.2.10 (git+https://github.com/brave/adblock-rust?rev=27409e39687adfa68f883153c878a0d8f2d655e9)" = "" "checksum addr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "22199dd03e5cff19ede8c2b835c93460f998b4716e225d06d740d925ceac5d75" "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" "checksum ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3" diff --git a/Cargo.toml b/Cargo.toml index 2dd1f3f..643a3ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Brian R. Bondy "] edition = "2018" [dependencies] -adblock = { version = "~0.2.6", git = "https://github.com/brave/adblock-rust", rev = "abd51752fab1f7aafb09d0fc410809b2b65abbf6" } +adblock = { version = "~0.2.10", git = "https://github.com/brave/adblock-rust", rev = "27409e39687adfa68f883153c878a0d8f2d655e9" } serde_json = "1.0" libc = "0.2" diff --git a/examples/cpp/main.cpp b/examples/cpp/main.cpp index 874c2da..53e0fae 100644 --- a/examples/cpp/main.cpp +++ b/examples/cpp/main.cpp @@ -267,7 +267,7 @@ void TestClassId() { assert(stylesheet == "[]"); } -void TestHostnameCosmetics() { +void TestUrlCosmetics() { Engine engine( "a.com###element\n" "b.com##.ads\n" @@ -277,42 +277,46 @@ void TestHostnameCosmetics() { "b.*##div:style(background: #fff)\n" ); - std::string a_resources = engine.hostnameCosmeticResources("a.com"); - std::string a_order1(R"({"hide_selectors":["a[href=\"b.com\"]","#element"],"style_selectors":{},"exceptions":[".block"],"injected_script":""})"); - std::string a_order2(R"({"hide_selectors":["#element","a[href=\"b.com\"]"],"style_selectors":{},"exceptions":[".block"],"injected_script":""})"); + std::string a_resources = engine.urlCosmeticResources("https://a.com"); + std::string a_order1(R"({"hide_selectors":["a[href=\"b.com\"]","#element"],"style_selectors":{},"exceptions":[".block"],"injected_script":"","generichide":false})"); + std::string a_order2(R"({"hide_selectors":["#element","a[href=\"b.com\"]"],"style_selectors":{},"exceptions":[".block"],"injected_script":"","generichide":false})"); assert(a_resources == a_order1 || a_resources == a_order2); - std::string b_resources = engine.hostnameCosmeticResources("b.com"); - std::string b_order1(R"({"hide_selectors":["a[href=\"b.com\"]",".ads"],"style_selectors":{"div":["background: #fff"]},"exceptions":[],"injected_script":""})"); - std::string b_order2(R"({"hide_selectors":[".ads","a[href=\"b.com\"]"],"style_selectors":{"div":["background: #fff"]},"exceptions":[],"injected_script":""})"); + std::string b_resources = engine.urlCosmeticResources("https://b.com"); + std::string b_order1(R"({"hide_selectors":["a[href=\"b.com\"]",".ads"],"style_selectors":{"div":["background: #fff"]},"exceptions":[],"injected_script":"","generichide":false})"); + std::string b_order2(R"({"hide_selectors":[".ads","a[href=\"b.com\"]"],"style_selectors":{"div":["background: #fff"]},"exceptions":[],"injected_script":"","generichide":false})"); assert(b_resources == b_order1 || b_resources == b_order2); - // The hostname should not include a URL path - std::string bad_b_resources = engine.hostnameCosmeticResources("b.com/index.html"); - std::string bad_b_result(R"({"hide_selectors":["a[href=\"b.com\"]"],"style_selectors":{},"exceptions":[],"injected_script":""})"); + // The URL may include a path + std::string path_b_resources = engine.urlCosmeticResources("https://b.com/index.html"); + assert(path_b_resources == b_order1 || path_b_resources == b_order2); + + // However, it must be a full URL, including scheme + std::string bad_b_resources = engine.urlCosmeticResources("b.com"); + std::string bad_b_result(R"({"hide_selectors":[],"style_selectors":{},"exceptions":[],"injected_script":"","generichide":false})"); assert(bad_b_resources == bad_b_result); } -void TestSubdomainHostnameCosmetics() { +void TestSubdomainUrlCosmetics() { Engine engine( "a.co.uk##.element\n" "good.a.*#@#.element\n" ); - std::string a_resources = engine.hostnameCosmeticResources("a.co.uk"); - std::string a_result(R"({"hide_selectors":[".element"],"style_selectors":{},"exceptions":[],"injected_script":""})"); + std::string a_resources = engine.urlCosmeticResources("http://a.co.uk"); + std::string a_result(R"({"hide_selectors":[".element"],"style_selectors":{},"exceptions":[],"injected_script":"","generichide":false})"); assert(a_resources == a_result); - std::string bad_a_resources = engine.hostnameCosmeticResources("bad.a.co.uk"); - std::string bad_a_result(R"({"hide_selectors":[".element"],"style_selectors":{},"exceptions":[],"injected_script":""})"); + std::string bad_a_resources = engine.urlCosmeticResources("https://bad.a.co.uk"); + std::string bad_a_result(R"({"hide_selectors":[".element"],"style_selectors":{},"exceptions":[],"injected_script":"","generichide":false})"); assert(bad_a_resources == bad_a_result); - std::string good_a_resources = engine.hostnameCosmeticResources("good.a.co.uk"); - std::string good_a_result(R"({"hide_selectors":[],"style_selectors":{},"exceptions":[".element"],"injected_script":""})"); + std::string good_a_resources = engine.urlCosmeticResources("https://good.a.co.uk"); + std::string good_a_result(R"({"hide_selectors":[],"style_selectors":{},"exceptions":[".element"],"injected_script":"","generichide":false})"); assert(good_a_resources == good_a_result); - std::string still_good_a_resources = engine.hostnameCosmeticResources("still.good.a.co.uk"); - std::string still_good_a_result(R"({"hide_selectors":[],"style_selectors":{},"exceptions":[".element"],"injected_script":""})"); + std::string still_good_a_resources = engine.urlCosmeticResources("http://still.good.a.co.uk"); + std::string still_good_a_result(R"({"hide_selectors":[],"style_selectors":{},"exceptions":[".element"],"injected_script":"","generichide":false})"); assert(still_good_a_resources == still_good_a_result); } @@ -322,8 +326,8 @@ void TestCosmeticScriptletResources() { "2.a.com##+js(scriptlet2.js, argument)\n" ); - std::string a_unloaded = engine.hostnameCosmeticResources("a.com"); - std::string a_unloaded_result(R"({"hide_selectors":[],"style_selectors":{},"exceptions":[],"injected_script":""})"); + std::string a_unloaded = engine.urlCosmeticResources("https://a.com"); + std::string a_unloaded_result(R"({"hide_selectors":[],"style_selectors":{},"exceptions":[],"injected_script":"","generichide":false})"); assert(a_unloaded == a_unloaded_result); engine.addResources(R"([ @@ -331,15 +335,43 @@ void TestCosmeticScriptletResources() { {"name": "scriptlet2", "aliases": [], "kind": "template", "content": "d2luZG93LmxvY2F0aW9uLmhyZWYgPSAie3sxfX0i" }] )"); - std::string a_loaded = engine.hostnameCosmeticResources("a.com"); - std::string a_loaded_result(R"({"hide_selectors":[],"style_selectors":{},"exceptions":[],"injected_script":"console.log(\"Hi\");\n"})"); + std::string a_loaded = engine.urlCosmeticResources("https://a.com"); + std::string a_loaded_result(R"({"hide_selectors":[],"style_selectors":{},"exceptions":[],"injected_script":"console.log(\"Hi\");\n","generichide":false})"); assert(a_loaded == a_loaded_result); - std::string a2_loaded = engine.hostnameCosmeticResources("2.a.com"); - std::string a2_loaded_result(R"({"hide_selectors":[],"style_selectors":{},"exceptions":[],"injected_script":"console.log(\"Hi\");\nwindow.location.href = \"argument\"\n"})"); + std::string a2_loaded = engine.urlCosmeticResources("https://2.a.com"); + std::string a2_loaded_result(R"({"hide_selectors":[],"style_selectors":{},"exceptions":[],"injected_script":"console.log(\"Hi\");\nwindow.location.href = \"argument\"\n","generichide":false})"); assert(a2_loaded == a2_loaded_result); } +void TestGenerichide() { + Engine engine( + "##a[href=\"generic.com\"]\n" + "@@||b.com$generichide\n" + "b.com##.block\n" + "##.block\n" + "@@||a.com/test.html$generichide\n" + "a.com##.block\n" + ); + + std::string b_resources = engine.urlCosmeticResources("https://b.com"); + std::string b_result(R"({"hide_selectors":[".block"],"style_selectors":{},"exceptions":[],"injected_script":"","generichide":true})"); + assert(b_resources == b_result); + + std::string b_path_resources = engine.urlCosmeticResources("https://b.com/test.html"); + std::string b_path_result(R"({"hide_selectors":[".block"],"style_selectors":{},"exceptions":[],"injected_script":"","generichide":true})"); + assert(b_path_resources == b_path_result); + + std::string a_resources = engine.urlCosmeticResources("https://a.com"); + std::string a_order1(R"({"hide_selectors":[".block","a[href=\"generic.com\"]"],"style_selectors":{},"exceptions":[],"injected_script":"","generichide":false})"); + std::string a_order2(R"({"hide_selectors":["a[href=\"generic.com\"]",".block"],"style_selectors":{},"exceptions":[],"injected_script":"","generichide":false})"); + assert(a_resources == a_order1 || a_resources == a_order2); + + std::string a_path_resources = engine.urlCosmeticResources("https://a.com/test.html"); + std::string a_path_result(R"({"hide_selectors":[".block"],"style_selectors":{},"exceptions":[],"injected_script":"","generichide":true})"); + assert(a_path_resources == a_path_result); +} + void TestDefaultLists() { std::vector& default_lists = FilterList::GetDefaultLists(); assert(default_lists.size() == 9); @@ -390,8 +422,9 @@ int main() { TestDefaultLists(); TestRegionalLists(); TestClassId(); - TestHostnameCosmetics(); - TestSubdomainHostnameCosmetics(); + TestUrlCosmetics(); + TestSubdomainUrlCosmetics(); + TestGenerichide(); TestCosmeticScriptletResources(); cout << num_passed << " passed, " << num_failed << " failed" << endl; diff --git a/src/lib.h b/src/lib.h index 50a06aa..a3c6287 100644 --- a/src/lib.h +++ b/src/lib.h @@ -74,11 +74,6 @@ char *engine_hidden_class_id_selectors(C_Engine *engine, const char *const *exceptions, size_t exceptions_size); -/** - * Returns a set of cosmetic filtering resources specific to the given hostname, in JSON format - */ -char *engine_hostname_cosmetic_resources(C_Engine *engine, const char *hostname); - /** * Checks if a `url` matches for the specified `Engine` within the context. */ @@ -102,6 +97,11 @@ void engine_remove_tag(C_Engine *engine, const char *tag); */ bool engine_tag_exists(C_Engine *engine, const char *tag); +/** + * Returns a set of cosmetic filtering resources specific to the given url, in JSON format + */ +char *engine_url_cosmetic_resources(C_Engine *engine, const char *url); + /** * Get the specific default list size */ diff --git a/src/lib.rs b/src/lib.rs index 034fb23..339e714 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -232,16 +232,16 @@ pub unsafe extern "C" fn filter_list_get(category: *const c_char, i: size_t) -> new_list } -/// Returns a set of cosmetic filtering resources specific to the given hostname, in JSON format +/// Returns a set of cosmetic filtering resources specific to the given url, in JSON format #[no_mangle] -pub unsafe extern "C" fn engine_hostname_cosmetic_resources( +pub unsafe extern "C" fn engine_url_cosmetic_resources( engine: *mut Engine, - hostname: *const c_char, + url: *const c_char, ) -> *mut c_char { - let hostname = CStr::from_ptr(hostname).to_str().unwrap(); + let url = CStr::from_ptr(url).to_str().unwrap(); assert!(!engine.is_null()); let engine = Box::leak(Box::from_raw(engine)); - let ptr = CString::new(serde_json::to_string(&engine.hostname_cosmetic_resources(hostname)) + let ptr = CString::new(serde_json::to_string(&engine.url_cosmetic_resources(url)) .unwrap_or_else(|_| "".into())) .expect("Error: CString::new()") .into_raw(); diff --git a/src/wrapper.cpp b/src/wrapper.cpp index f13a777..604f9e7 100644 --- a/src/wrapper.cpp +++ b/src/wrapper.cpp @@ -125,8 +125,8 @@ void Engine::addResources(const std::string& resources) { engine_add_resources(raw, resources.c_str()); } -const std::string Engine::hostnameCosmeticResources(const std::string& hostname) { - char* resources_raw = engine_hostname_cosmetic_resources(raw, hostname.c_str()); +const std::string Engine::urlCosmeticResources(const std::string& url) { + char* resources_raw = engine_url_cosmetic_resources(raw, url.c_str()); const std::string resources_json = std::string(resources_raw); c_char_buffer_destroy(resources_raw); diff --git a/src/wrapper.hpp b/src/wrapper.hpp index a6ef692..3c4c103 100644 --- a/src/wrapper.hpp +++ b/src/wrapper.hpp @@ -59,7 +59,7 @@ class Engine { void addResources(const std::string& resources); void removeTag(const std::string& tag); bool tagExists(const std::string& tag); - const std::string hostnameCosmeticResources(const std::string& hostname); + const std::string urlCosmeticResources(const std::string& url); const std::string hiddenClassIdSelectors( const std::vector& classes, const std::vector& ids,