summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock139
-rw-r--r--Cargo.toml2
-rw-r--r--adblock/__init__.py2
-rw-r--r--adblock/adblock.pyi11
-rw-r--r--src/lib.rs107
-rw-r--r--tests/test_exceptions.py13
-rw-r--r--tests/test_redirect.py68
7 files changed, 261 insertions, 81 deletions
diff --git a/Cargo.lock b/Cargo.lock
index df7e282..d6438cd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,9 +4,9 @@ version = 3
4 4
5[[package]] 5[[package]]
6name = "adblock" 6name = "adblock"
7version = "0.3.13" 7version = "0.4.3"
8source = "registry+https://github.com/rust-lang/crates.io-index" 8source = "registry+https://github.com/rust-lang/crates.io-index"
9checksum = "13df3d8a7e24ea2cc711b82a047ef2b9f743aa6580bea2552fcec68f0289603c" 9checksum = "52bdd00675903fd86d5d3109bb7899387c85cab52f990d14481546cb9a7102bf"
10dependencies = [ 10dependencies = [
11 "addr", 11 "addr",
12 "base64", 12 "base64",
@@ -17,7 +17,8 @@ dependencies = [
17 "once_cell", 17 "once_cell",
18 "percent-encoding", 18 "percent-encoding",
19 "regex", 19 "regex",
20 "rmp-serde", 20 "rmp-serde 0.13.7",
21 "rmp-serde 0.15.5",
21 "seahash", 22 "seahash",
22 "serde", 23 "serde",
23 "twoway", 24 "twoway",
@@ -28,7 +29,7 @@ dependencies = [
28name = "adblock" 29name = "adblock"
29version = "0.5.1" 30version = "0.5.1"
30dependencies = [ 31dependencies = [
31 "adblock 0.3.13", 32 "adblock 0.4.3",
32 "pyo3", 33 "pyo3",
33] 34]
34 35
@@ -59,9 +60,9 @@ dependencies = [
59 60
60[[package]] 61[[package]]
61name = "autocfg" 62name = "autocfg"
62version = "1.0.1" 63version = "1.1.0"
63source = "registry+https://github.com/rust-lang/crates.io-index" 64source = "registry+https://github.com/rust-lang/crates.io-index"
64checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 65checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
65 66
66[[package]] 67[[package]]
67name = "base64" 68name = "base64"
@@ -71,9 +72,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
71 72
72[[package]] 73[[package]]
73name = "bitflags" 74name = "bitflags"
74version = "1.2.1" 75version = "1.3.2"
75source = "registry+https://github.com/rust-lang/crates.io-index" 76source = "registry+https://github.com/rust-lang/crates.io-index"
76checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 77checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
77 78
78[[package]] 79[[package]]
79name = "byteorder" 80name = "byteorder"
@@ -89,9 +90,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
89 90
90[[package]] 91[[package]]
91name = "crc32fast" 92name = "crc32fast"
92version = "1.2.1" 93version = "1.3.2"
93source = "registry+https://github.com/rust-lang/crates.io-index" 94source = "registry+https://github.com/rust-lang/crates.io-index"
94checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" 95checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
95dependencies = [ 96dependencies = [
96 "cfg-if", 97 "cfg-if",
97] 98]
@@ -104,9 +105,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
104 105
105[[package]] 106[[package]]
106name = "flate2" 107name = "flate2"
107version = "1.0.20" 108version = "1.0.22"
108source = "registry+https://github.com/rust-lang/crates.io-index" 109source = "registry+https://github.com/rust-lang/crates.io-index"
109checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" 110checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
110dependencies = [ 111dependencies = [
111 "cfg-if", 112 "cfg-if",
112 "crc32fast", 113 "crc32fast",
@@ -126,9 +127,9 @@ dependencies = [
126 127
127[[package]] 128[[package]]
128name = "idna" 129name = "idna"
129version = "0.2.2" 130version = "0.2.3"
130source = "registry+https://github.com/rust-lang/crates.io-index" 131source = "registry+https://github.com/rust-lang/crates.io-index"
131checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21" 132checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
132dependencies = [ 133dependencies = [
133 "matches", 134 "matches",
134 "unicode-bidi", 135 "unicode-bidi",
@@ -160,48 +161,48 @@ dependencies = [
160 161
161[[package]] 162[[package]]
162name = "instant" 163name = "instant"
163version = "0.1.9" 164version = "0.1.12"
164source = "registry+https://github.com/rust-lang/crates.io-index" 165source = "registry+https://github.com/rust-lang/crates.io-index"
165checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" 166checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
166dependencies = [ 167dependencies = [
167 "cfg-if", 168 "cfg-if",
168] 169]
169 170
170[[package]] 171[[package]]
171name = "itertools" 172name = "itertools"
172version = "0.9.0" 173version = "0.10.3"
173source = "registry+https://github.com/rust-lang/crates.io-index" 174source = "registry+https://github.com/rust-lang/crates.io-index"
174checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" 175checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
175dependencies = [ 176dependencies = [
176 "either", 177 "either",
177] 178]
178 179
179[[package]] 180[[package]]
180name = "libc" 181name = "libc"
181version = "0.2.93" 182version = "0.2.118"
182source = "registry+https://github.com/rust-lang/crates.io-index" 183source = "registry+https://github.com/rust-lang/crates.io-index"
183checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41" 184checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94"
184 185
185[[package]] 186[[package]]
186name = "lock_api" 187name = "lock_api"
187version = "0.4.3" 188version = "0.4.6"
188source = "registry+https://github.com/rust-lang/crates.io-index" 189source = "registry+https://github.com/rust-lang/crates.io-index"
189checksum = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176" 190checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b"
190dependencies = [ 191dependencies = [
191 "scopeguard", 192 "scopeguard",
192] 193]
193 194
194[[package]] 195[[package]]
195name = "matches" 196name = "matches"
196version = "0.1.8" 197version = "0.1.9"
197source = "registry+https://github.com/rust-lang/crates.io-index" 198source = "registry+https://github.com/rust-lang/crates.io-index"
198checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 199checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
199 200
200[[package]] 201[[package]]
201name = "memchr" 202name = "memchr"
202version = "2.4.0" 203version = "2.4.1"
203source = "registry+https://github.com/rust-lang/crates.io-index" 204source = "registry+https://github.com/rust-lang/crates.io-index"
204checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" 205checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
205 206
206[[package]] 207[[package]]
207name = "miniz_oxide" 208name = "miniz_oxide"
@@ -224,15 +225,15 @@ dependencies = [
224 225
225[[package]] 226[[package]]
226name = "once_cell" 227name = "once_cell"
227version = "1.8.0" 228version = "1.9.0"
228source = "registry+https://github.com/rust-lang/crates.io-index" 229source = "registry+https://github.com/rust-lang/crates.io-index"
229checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" 230checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
230 231
231[[package]] 232[[package]]
232name = "parking_lot" 233name = "parking_lot"
233version = "0.11.1" 234version = "0.11.2"
234source = "registry+https://github.com/rust-lang/crates.io-index" 235source = "registry+https://github.com/rust-lang/crates.io-index"
235checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" 236checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
236dependencies = [ 237dependencies = [
237 "instant", 238 "instant",
238 "lock_api", 239 "lock_api",
@@ -241,9 +242,9 @@ dependencies = [
241 242
242[[package]] 243[[package]]
243name = "parking_lot_core" 244name = "parking_lot_core"
244version = "0.8.3" 245version = "0.8.5"
245source = "registry+https://github.com/rust-lang/crates.io-index" 246source = "registry+https://github.com/rust-lang/crates.io-index"
246checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" 247checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
247dependencies = [ 248dependencies = [
248 "cfg-if", 249 "cfg-if",
249 "instant", 250 "instant",
@@ -286,27 +287,27 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
286 287
287[[package]] 288[[package]]
288name = "proc-macro2" 289name = "proc-macro2"
289version = "1.0.26" 290version = "1.0.36"
290source = "registry+https://github.com/rust-lang/crates.io-index" 291source = "registry+https://github.com/rust-lang/crates.io-index"
291checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" 292checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
292dependencies = [ 293dependencies = [
293 "unicode-xid", 294 "unicode-xid",
294] 295]
295 296
296[[package]] 297[[package]]
297name = "psl" 298name = "psl"
298version = "2.0.18" 299version = "2.0.71"
299source = "registry+https://github.com/rust-lang/crates.io-index" 300source = "registry+https://github.com/rust-lang/crates.io-index"
300checksum = "b0cbbbcd909251c04efa3c0dda636f26a9e5b91734d5ce119212528b8ba32d55" 301checksum = "2f51974f40b58fd94008d3c88fa47cf1c7a58bd4e85deb0d4390bc156b0a9625"
301dependencies = [ 302dependencies = [
302 "psl-types", 303 "psl-types",
303] 304]
304 305
305[[package]] 306[[package]]
306name = "psl-types" 307name = "psl-types"
307version = "2.0.7" 308version = "2.0.10"
308source = "registry+https://github.com/rust-lang/crates.io-index" 309source = "registry+https://github.com/rust-lang/crates.io-index"
309checksum = "66b398073e7cdd6f05934389a8f5961e3aabfa66675b6f440df4e2c793d51a4f" 310checksum = "e8eda7c62d9ecaafdf8b62374c006de0adf61666ae96a96ba74a37134aa4e470"
310 311
311[[package]] 312[[package]]
312name = "pyo3" 313name = "pyo3"
@@ -358,18 +359,18 @@ dependencies = [
358 359
359[[package]] 360[[package]]
360name = "quote" 361name = "quote"
361version = "1.0.9" 362version = "1.0.15"
362source = "registry+https://github.com/rust-lang/crates.io-index" 363source = "registry+https://github.com/rust-lang/crates.io-index"
363checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" 364checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
364dependencies = [ 365dependencies = [
365 "proc-macro2", 366 "proc-macro2",
366] 367]
367 368
368[[package]] 369[[package]]
369name = "redox_syscall" 370name = "redox_syscall"
370version = "0.2.5" 371version = "0.2.10"
371source = "registry+https://github.com/rust-lang/crates.io-index" 372source = "registry+https://github.com/rust-lang/crates.io-index"
372checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" 373checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
373dependencies = [ 374dependencies = [
374 "bitflags", 375 "bitflags",
375] 376]
@@ -413,6 +414,17 @@ dependencies = [
413] 414]
414 415
415[[package]] 416[[package]]
417name = "rmp-serde"
418version = "0.15.5"
419source = "registry+https://github.com/rust-lang/crates.io-index"
420checksum = "723ecff9ad04f4ad92fe1c8ca6c20d2196d9286e9c60727c4cb5511629260e9d"
421dependencies = [
422 "byteorder",
423 "rmp",
424 "serde",
425]
426
427[[package]]
416name = "scopeguard" 428name = "scopeguard"
417version = "1.1.0" 429version = "1.1.0"
418source = "registry+https://github.com/rust-lang/crates.io-index" 430source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -426,18 +438,18 @@ checksum = "58f57ca1d128a43733fd71d583e837b1f22239a37ebea09cde11d8d9a9080f47"
426 438
427[[package]] 439[[package]]
428name = "serde" 440name = "serde"
429version = "1.0.125" 441version = "1.0.136"
430source = "registry+https://github.com/rust-lang/crates.io-index" 442source = "registry+https://github.com/rust-lang/crates.io-index"
431checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" 443checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
432dependencies = [ 444dependencies = [
433 "serde_derive", 445 "serde_derive",
434] 446]
435 447
436[[package]] 448[[package]]
437name = "serde_derive" 449name = "serde_derive"
438version = "1.0.125" 450version = "1.0.136"
439source = "registry+https://github.com/rust-lang/crates.io-index" 451source = "registry+https://github.com/rust-lang/crates.io-index"
440checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" 452checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
441dependencies = [ 453dependencies = [
442 "proc-macro2", 454 "proc-macro2",
443 "quote", 455 "quote",
@@ -446,15 +458,15 @@ dependencies = [
446 458
447[[package]] 459[[package]]
448name = "smallvec" 460name = "smallvec"
449version = "1.6.1" 461version = "1.8.0"
450source = "registry+https://github.com/rust-lang/crates.io-index" 462source = "registry+https://github.com/rust-lang/crates.io-index"
451checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" 463checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
452 464
453[[package]] 465[[package]]
454name = "syn" 466name = "syn"
455version = "1.0.69" 467version = "1.0.86"
456source = "registry+https://github.com/rust-lang/crates.io-index" 468source = "registry+https://github.com/rust-lang/crates.io-index"
457checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb" 469checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
458dependencies = [ 470dependencies = [
459 "proc-macro2", 471 "proc-macro2",
460 "quote", 472 "quote",
@@ -463,9 +475,9 @@ dependencies = [
463 475
464[[package]] 476[[package]]
465name = "tinyvec" 477name = "tinyvec"
466version = "1.2.0" 478version = "1.5.1"
467source = "registry+https://github.com/rust-lang/crates.io-index" 479source = "registry+https://github.com/rust-lang/crates.io-index"
468checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" 480checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
469dependencies = [ 481dependencies = [
470 "tinyvec_macros", 482 "tinyvec_macros",
471] 483]
@@ -478,9 +490,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
478 490
479[[package]] 491[[package]]
480name = "twoway" 492name = "twoway"
481version = "0.2.1" 493version = "0.2.2"
482source = "registry+https://github.com/rust-lang/crates.io-index" 494source = "registry+https://github.com/rust-lang/crates.io-index"
483checksum = "6b40075910de3a912adbd80b5d8bad6ad10a23eeb1f5bf9d4006839e899ba5bc" 495checksum = "c57ffb460d7c24cd6eda43694110189030a3d1dfe418416d9468fd1c1d290b47"
484dependencies = [ 496dependencies = [
485 "memchr", 497 "memchr",
486 "unchecked-index", 498 "unchecked-index",
@@ -494,27 +506,24 @@ checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c"
494 506
495[[package]] 507[[package]]
496name = "unicode-bidi" 508name = "unicode-bidi"
497version = "0.3.5" 509version = "0.3.7"
498source = "registry+https://github.com/rust-lang/crates.io-index" 510source = "registry+https://github.com/rust-lang/crates.io-index"
499checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0" 511checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
500dependencies = [
501 "matches",
502]
503 512
504[[package]] 513[[package]]
505name = "unicode-normalization" 514name = "unicode-normalization"
506version = "0.1.17" 515version = "0.1.19"
507source = "registry+https://github.com/rust-lang/crates.io-index" 516source = "registry+https://github.com/rust-lang/crates.io-index"
508checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef" 517checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
509dependencies = [ 518dependencies = [
510 "tinyvec", 519 "tinyvec",
511] 520]
512 521
513[[package]] 522[[package]]
514name = "unicode-xid" 523name = "unicode-xid"
515version = "0.2.1" 524version = "0.2.2"
516source = "registry+https://github.com/rust-lang/crates.io-index" 525source = "registry+https://github.com/rust-lang/crates.io-index"
517checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" 526checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
518 527
519[[package]] 528[[package]]
520name = "unindent" 529name = "unindent"
@@ -524,9 +533,9 @@ checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7"
524 533
525[[package]] 534[[package]]
526name = "url" 535name = "url"
527version = "2.2.1" 536version = "2.2.2"
528source = "registry+https://github.com/rust-lang/crates.io-index" 537source = "registry+https://github.com/rust-lang/crates.io-index"
529checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b" 538checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
530dependencies = [ 539dependencies = [
531 "form_urlencoded", 540 "form_urlencoded",
532 "idna", 541 "idna",
diff --git a/Cargo.toml b/Cargo.toml
index 6ac767b..858d4f6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,7 +22,7 @@ requires-python = ">=3.6"
22debug = true 22debug = true
23 23
24[dependencies] 24[dependencies]
25adblock = { version = "=0.3.13", default-features = false, features = ["full-regex-handling", "embedded-domain-resolver"] } 25adblock = { version = "=0.4.3", default-features = false, features = ["full-regex-handling", "embedded-domain-resolver"] }
26pyo3 = { version = "0.15", features = ["abi3-py36", "extension-module"] } 26pyo3 = { version = "0.15", features = ["abi3-py36", "extension-module"] }
27 27
28[lib] 28[lib]
diff --git a/adblock/__init__.py b/adblock/__init__.py
index 85d3614..4ba4c4b 100644
--- a/adblock/__init__.py
+++ b/adblock/__init__.py
@@ -11,6 +11,7 @@ from adblock.adblock import (
11 OptimizedFilterExistence, 11 OptimizedFilterExistence,
12 BadFilterAddUnsupported, 12 BadFilterAddUnsupported,
13 FilterExists, 13 FilterExists,
14 AddResourceError,
14) 15)
15 16
16 17
@@ -26,4 +27,5 @@ __all__ = (
26 "OptimizedFilterExistence", 27 "OptimizedFilterExistence",
27 "BadFilterAddUnsupported", 28 "BadFilterAddUnsupported",
28 "FilterExists", 29 "FilterExists",
30 "AddResourceError",
29) 31)
diff --git a/adblock/adblock.pyi b/adblock/adblock.pyi
index 0515674..83d2492 100644
--- a/adblock/adblock.pyi
+++ b/adblock/adblock.pyi
@@ -21,10 +21,14 @@ class BadFilterAddUnsupported(BlockerException):
21class FilterExists(BlockerException): 21class FilterExists(BlockerException):
22 pass 22 pass
23 23
24class AddResourceError(BlockerException):
25 pass
26
24class BlockerResult: 27class BlockerResult:
25 matched: bool 28 matched: bool
26 explicit_cancel: bool 29 explicit_cancel: bool
27 important: bool 30 important: bool
31 redirect_type: Optional[str]
28 redirect: Optional[str] 32 redirect: Optional[str]
29 exception: Optional[str] 33 exception: Optional[str]
30 filter: Optional[str] 34 filter: Optional[str]
@@ -43,14 +47,15 @@ class UrlSpecificResources:
43class FilterSet: 47class FilterSet:
44 def __init__(self, debug: bool = False) -> None: 48 def __init__(self, debug: bool = False) -> None:
45 pass 49 pass
46 def add_filter_list(self, filter_list: str, format: str = "standard") -> None: 50 def add_filter_list(self, filter_list: str, format: str = "standard", include_redirect_urls: bool = False) -> None:
47 pass 51 pass
48 def add_filters(self, filters: List[str], format: str = "standard") -> None: 52 def add_filters(self, filters: List[str], format: str = "standard", include_redirect_urls: bool = False) -> None:
49 pass 53 pass
50 54
51class Engine: 55class Engine:
52 def __init__(self, filter_set: FilterSet, optimize: bool = True) -> None: 56 def __init__(self, filter_set: FilterSet, optimize: bool = True) -> None:
53 pass 57 pass
58
54 def check_network_urls( 59 def check_network_urls(
55 self, url: str, source_url: str, request_type: str 60 self, url: str, source_url: str, request_type: str
56 ) -> BlockerResult: 61 ) -> BlockerResult:
@@ -93,6 +98,8 @@ class Engine:
93 pass 98 pass
94 def tag_exists(self, tag: str) -> bool: 99 def tag_exists(self, tag: str) -> bool:
95 pass 100 pass
101 def add_resource(self, name: str, content_type: str, content: str) -> bool:
102 pass
96 def url_cosmetic_resources(self, url: str) -> UrlSpecificResources: 103 def url_cosmetic_resources(self, url: str) -> UrlSpecificResources:
97 pass 104 pass
98 def hidden_class_id_selectors( 105 def hidden_class_id_selectors(
diff --git a/src/lib.rs b/src/lib.rs
index 01b105c..ca763bc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -11,11 +11,11 @@
11 deprecated 11 deprecated
12)] 12)]
13 13
14use adblock::blocker::BlockerError as RustBlockerError; 14use adblock::blocker::{BlockerError as RustBlockerError, Redirection};
15use adblock::blocker::BlockerResult as RustBlockerResult; 15use adblock::blocker::BlockerResult as RustBlockerResult;
16use adblock::cosmetic_filter_cache::UrlSpecificResources as RustUrlSpecificResources; 16use adblock::cosmetic_filter_cache::UrlSpecificResources as RustUrlSpecificResources;
17use adblock::engine::Engine as RustEngine; 17use adblock::engine::Engine as RustEngine;
18use adblock::lists::FilterFormat; 18use adblock::lists::{FilterFormat, ParseOptions};
19use adblock::lists::FilterSet as RustFilterSet; 19use adblock::lists::FilterSet as RustFilterSet;
20use pyo3::class::PyObjectProtocol; 20use pyo3::class::PyObjectProtocol;
21use pyo3::create_exception; 21use pyo3::create_exception;
@@ -30,6 +30,10 @@ use std::error::Error;
30use std::fmt::{self, Display}; 30use std::fmt::{self, Display};
31use std::fs; 31use std::fs;
32use std::io::{Read, Write}; 32use std::io::{Read, Write};
33use adblock::resources::{
34 AddResourceError as RustAddResourceError, MimeType, Resource, ResourceType,
35};
36
33 37
34/// Brave's adblocking library in Python! 38/// Brave's adblocking library in Python!
35#[pymodule] 39#[pymodule]
@@ -55,6 +59,7 @@ fn adblock(py: Python<'_>, m: &PyModule) -> PyResult<()> {
55 py.get_type::<BadFilterAddUnsupported>(), 59 py.get_type::<BadFilterAddUnsupported>(),
56 )?; 60 )?;
57 m.add("FilterExists", py.get_type::<FilterExists>())?; 61 m.add("FilterExists", py.get_type::<FilterExists>())?;
62 m.add("AddResourceError", py.get_type::<AddResourceError>())?;
58 Ok(()) 63 Ok(())
59} 64}
60 65
@@ -80,6 +85,13 @@ pub struct BlockerResult {
80 /// 85 ///
81 /// [1]: https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#redirect 86 /// [1]: https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#redirect
82 #[pyo3(get)] 87 #[pyo3(get)]
88 pub redirect_type: Option<String>,
89 /// Exception is not `None` when the blocker matched on an exception rule.
90 /// Effectively this means that there was a match, but the request should
91 /// not be blocked. It is a non-empty string if the blocker was initialized
92 /// from a list of rules with debugging enabled, otherwise the original
93 /// string representation is discarded to reduce memory use.
94 #[pyo3(get)]
83 pub redirect: Option<String>, 95 pub redirect: Option<String>,
84 /// Exception is not `None` when the blocker matched on an exception rule. 96 /// Exception is not `None` when the blocker matched on an exception rule.
85 /// Effectively this means that there was a match, but the request should 97 /// Effectively this means that there was a match, but the request should
@@ -102,13 +114,30 @@ pub struct BlockerResult {
102 114
103impl From<RustBlockerResult> for BlockerResult { 115impl From<RustBlockerResult> for BlockerResult {
104 fn from(br: RustBlockerResult) -> Self { 116 fn from(br: RustBlockerResult) -> Self {
117 let mut redirect: Option<String> = None;
118 let mut redirect_type: Option<String> = None;
119 if br.redirect.is_some() {
120 let resource = br.redirect.unwrap();
121 redirect = Option::from(match resource {
122 Redirection::Resource(resource) => {
123 redirect_type = Some("resource".to_string());
124 resource
125 }
126 Redirection::Url(url) => {
127 redirect_type = Some("url".to_string());
128 url
129 }
130 });
131 }
132
105 Self { 133 Self {
106 matched: br.matched, 134 matched: br.matched,
107 important: br.important, 135 important: br.important,
108 redirect: br.redirect,
109 exception: br.exception, 136 exception: br.exception,
110 filter: br.filter, 137 filter: br.filter,
111 error: br.error, 138 error: br.error,
139 redirect_type: redirect_type,
140 redirect: redirect,
112 } 141 }
113 } 142 }
114} 143}
@@ -166,6 +195,8 @@ create_exception!(adblock, DeserializationError, BlockerException);
166create_exception!(adblock, OptimizedFilterExistence, BlockerException); 195create_exception!(adblock, OptimizedFilterExistence, BlockerException);
167create_exception!(adblock, BadFilterAddUnsupported, BlockerException); 196create_exception!(adblock, BadFilterAddUnsupported, BlockerException);
168create_exception!(adblock, FilterExists, BlockerException); 197create_exception!(adblock, FilterExists, BlockerException);
198create_exception!(adblock, AddResourceError, BlockerException);
199
169 200
170impl From<BlockerError> for PyErr { 201impl From<BlockerError> for PyErr {
171 fn from(err: BlockerError) -> Self { 202 fn from(err: BlockerError) -> Self {
@@ -234,11 +265,22 @@ impl FilterSet {
234 /// 265 ///
235 /// The format is a string containing either "standard" (ABP/uBO-style) 266 /// The format is a string containing either "standard" (ABP/uBO-style)
236 /// or "hosts". 267 /// or "hosts".
237 #[pyo3(text_signature = "($self, filter_list, format)")] 268 #[pyo3(text_signature = "($self, filter_list, format, include_redirect_urls)")]
238 #[args(filter_list, format = "\"standard\"")] 269 #[args(filter_list, format = "\"standard\"", include_redirect_urls = "false")]
239 pub fn add_filter_list(&mut self, filter_list: &str, format: &str) -> PyResult<()> { 270 pub fn add_filter_list(
271 &mut self,
272 filter_list: &str,
273 format: &str,
274 include_redirect_urls: bool,
275 ) -> PyResult<()> {
240 let filter_format = filter_format_from_string(format)?; 276 let filter_format = filter_format_from_string(format)?;
241 self.filter_set.add_filter_list(filter_list, filter_format); 277 self.filter_set.add_filter_list(
278 filter_list,
279 ParseOptions {
280 format: filter_format,
281 include_redirect_urls,
282 },
283 );
242 Ok(()) 284 Ok(())
243 } 285 }
244 286
@@ -247,11 +289,22 @@ impl FilterSet {
247 /// 289 ///
248 /// The format is a string containing either "standard" (ABP/uBO-style) 290 /// The format is a string containing either "standard" (ABP/uBO-style)
249 /// or "hosts". 291 /// or "hosts".
250 #[pyo3(text_signature = "($self, filters, format)")] 292 #[pyo3(text_signature = "($self, filters, format, include_redirect_urls)")]
251 #[args(filters, format = "\"standard\"")] 293 #[args(filters, format = "\"standard\"", include_redirect_urls = "false")]
252 pub fn add_filters(&mut self, filters: Vec<String>, format: &str) -> PyResult<()> { 294 pub fn add_filters(
295 &mut self,
296 filters: Vec<String>,
297 format: &str,
298 include_redirect_urls: bool,
299 ) -> PyResult<()> {
253 let filter_format = filter_format_from_string(format)?; 300 let filter_format = filter_format_from_string(format)?;
254 self.filter_set.add_filters(&filters, filter_format); 301 self.filter_set.add_filters(
302 &filters,
303 ParseOptions {
304 format: filter_format,
305 include_redirect_urls,
306 },
307 );
255 Ok(()) 308 Ok(())
256 } 309 }
257} 310}
@@ -446,6 +499,36 @@ impl Engine {
446 blocker_result.into() 499 blocker_result.into()
447 } 500 }
448 501
502 /// Sets this engine's resources to additionally include `resource`.
503 ///
504 /// # Arguments
505 /// * `name`: Represents the primary name of the resource, often a filename
506 /// * `content_type`: How to interpret the resource data within `content`
507 /// * `content`: The resource data, encoded using standard base64 configuration
508 #[pyo3(text_signature = "($self, name, content_type, content)")]
509 pub fn add_resource(&mut self, name: &str, content_type: &str, content: &str) -> PyResult<()> {
510 let result = self.engine.add_resource(Resource {
511 name: name.to_string(),
512 aliases: vec![],
513 kind: ResourceType::Mime(MimeType::from(std::borrow::Cow::from(
514 content_type.to_string(),
515 ))),
516 content: content.to_string(),
517 });
518
519 match result {
520 Ok(_) => Ok(()),
521 Err(err) => match err {
522 RustAddResourceError::InvalidBase64Content => Err(AddResourceError::new_err(
523 "invalid base64 content".to_string(),
524 )),
525 RustAddResourceError::InvalidUtf8Content => {
526 Err(AddResourceError::new_err("invalid utf content".to_string()))
527 }
528 },
529 }
530 }
531
449 /// Serialize this blocking engine to bytes. They can then be deserialized 532 /// Serialize this blocking engine to bytes. They can then be deserialized
450 /// using `deserialize()` to get the same engine again. 533 /// using `deserialize()` to get the same engine again.
451 #[pyo3(text_signature = "($self)")] 534 #[pyo3(text_signature = "($self)")]
@@ -456,7 +539,7 @@ impl Engine {
456 } 539 }
457 540
458 fn serialize_inner(&mut self) -> PyResult<Vec<u8>> { 541 fn serialize_inner(&mut self) -> PyResult<Vec<u8>> {
459 let result = self.engine.serialize(); 542 let result = self.engine.serialize_raw();
460 match result { 543 match result {
461 Ok(x) => Ok(x), 544 Ok(x) => Ok(x),
462 Err(error) => { 545 Err(error) => {
diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py
index becf107..3e3dc9f 100644
--- a/tests/test_exceptions.py
+++ b/tests/test_exceptions.py
@@ -1,5 +1,5 @@
1import adblock 1import adblock
2 2import pytest
3 3
4def test_correct_baseclasses(): 4def test_correct_baseclasses():
5 assert issubclass(adblock.AdblockException, Exception) 5 assert issubclass(adblock.AdblockException, Exception)
@@ -9,3 +9,14 @@ def test_correct_baseclasses():
9 assert issubclass(adblock.OptimizedFilterExistence, adblock.BlockerException) 9 assert issubclass(adblock.OptimizedFilterExistence, adblock.BlockerException)
10 assert issubclass(adblock.BadFilterAddUnsupported, adblock.BlockerException) 10 assert issubclass(adblock.BadFilterAddUnsupported, adblock.BlockerException)
11 assert issubclass(adblock.FilterExists, adblock.BlockerException) 11 assert issubclass(adblock.FilterExists, adblock.BlockerException)
12 assert issubclass(adblock.AddResourceError, adblock.BlockerException)
13
14
15def test_add_resource_error():
16 filter_set = adblock.FilterSet()
17 engine = adblock.Engine(filter_set=filter_set)
18
19 with pytest.raises(adblock.AddResourceError) as exc:
20 engine.add_resource(name='aa', content_type="image/jpeg", content="111")
21
22 assert "invalid base64 content" in str(exc.value)
diff --git a/tests/test_redirect.py b/tests/test_redirect.py
new file mode 100644
index 0000000..a99a728
--- /dev/null
+++ b/tests/test_redirect.py
@@ -0,0 +1,68 @@
1import adblock
2
3
4def test_redirect_worked_as_excepted_with_include_redirect_urls():
5 # https://github.com/brave/adblock-rust/blob/b7f29af8c0a0d000201d8d769b6a0b25a9dd4e89/src/blocker.rs#L1242
6 filter_set = adblock.FilterSet()
7 filter_set.add_filter_list("||foo.com$important,redirect-url=http://xyz.com", include_redirect_urls=True)
8
9 engine = adblock.Engine(filter_set=filter_set)
10
11 res = engine.check_network_urls("https://foo.com", "https://foo.com", "script")
12 assert res.matched is True
13 assert res.important is True
14 assert res.redirect_type == "url"
15 assert res.redirect == "http://xyz.com"
16
17
18def test_redirect_url_is_not_recognized_without_include_redirect_urls():
19 # https://github.com/brave/adblock-rust/blob/b7f29af8c0a0d000201d8d769b6a0b25a9dd4e89/src/blocker.rs#L1267
20 filter_set2 = adblock.FilterSet()
21 filter_set2.add_filter_list("||foo.com$important,redirect-url=http://xyz.com", include_redirect_urls=False)
22
23 engine2 = adblock.Engine(filter_set=filter_set2)
24
25 res = engine2.check_network_urls("https://foo.com", "https://foo.com", "script")
26 assert res.matched is False
27 assert res.redirect is None
28 assert res.redirect_type is None
29
30
31def test_redirect_url_exception():
32 # https://github.com/brave/adblock-rust/blob/b7f29af8c0a0d000201d8d769b6a0b25a9dd4e89/src/blocker.rs#L1314
33 filter_set = adblock.FilterSet(debug=True)
34 filter_set.add_filter_list(
35 """
36 ||imdb-video.media-imdb.com$media,redirect-url=http://xyz.com
37 @@||imdb-video.media-imdb.com^$domain=imdb.com
38 """,
39 include_redirect_urls=True
40 )
41
42 engine2 = adblock.Engine(filter_set=filter_set, optimize=False)
43
44 res = engine2.check_network_urls(
45 "https://imdb-video.media-imdb.com/kBOeI88k1o23eNAi", "https://www.imdb.com/video/13", "media"
46 )
47 assert res.matched is False
48 assert res.redirect == "http://xyz.com"
49 assert res.redirect_type == "url"
50 assert res.exception == "@@||imdb-video.media-imdb.com^$domain=imdb.com"
51
52
53def test_redirect_with_custom_resource():
54 filters = adblock.FilterSet()
55 filters.add_filter_list("-advertisement-$redirect=test\n")
56
57 engine = adblock.Engine(filter_set=filters)
58 engine.add_resource(name="test", content_type="application/javascript", content="YWxlcnQoMSk=")
59
60 result = engine.check_network_urls(
61 url="http://example.com/-advertisement-icon.", source_url="example.com", request_type="image",
62 )
63
64 assert result.matched
65 assert not result.exception
66 assert not result.important
67 assert result.redirect == "data:application/javascript;base64,YWxlcnQoMSk="
68