File tree Expand file tree Collapse file tree 3 files changed +61
-3
lines changed Expand file tree Collapse file tree 3 files changed +61
-3
lines changed Original file line number Diff line number Diff line change @@ -316,9 +316,10 @@ impl TryFrom<NetworkFilter> for CbRuleEquivalent {
316316 if v. mask . contains ( NetworkFilterMask :: GENERIC_HIDE ) {
317317 return Err ( CbRuleCreationFailure :: NetworkGenerichideUnsupported ) ;
318318 }
319- if v. mask . contains ( NetworkFilterMask :: BAD_FILTER ) {
320- return Err ( CbRuleCreationFailure :: NetworkBadFilterUnsupported ) ;
321- }
319+ debug_assert ! (
320+ !v. mask. contains( NetworkFilterMask :: BAD_FILTER ) ,
321+ "BAD_FILTER should be filtered out"
322+ ) ;
322323 if v. is_csp ( ) {
323324 return Err ( CbRuleCreationFailure :: NetworkCspUnsupported ) ;
324325 }
Original file line number Diff line number Diff line change @@ -285,17 +285,31 @@ impl FilterSet {
285285 self ,
286286 ) -> Result < ( Vec < crate :: content_blocking:: CbRule > , Vec < String > ) , ( ) > {
287287 use crate :: content_blocking;
288+ use crate :: filters:: network:: NetworkFilterMaskHelper ;
289+ use std:: collections:: HashSet ;
288290
289291 if !self . debug {
290292 return Err ( ( ) ) ;
291293 }
292294
295+ // Store bad filter id to skip them later.
296+ let mut bad_filter_ids = HashSet :: new ( ) ;
297+ for filter in self . network_filters . iter ( ) {
298+ if filter. is_badfilter ( ) {
299+ bad_filter_ids. insert ( filter. get_id_without_badfilter ( ) ) ;
300+ }
301+ }
302+
293303 let mut ignore_previous_rules = vec ! [ ] ;
294304 let mut other_rules = vec ! [ ] ;
295305
296306 let mut filters_used = vec ! [ ] ;
297307
298308 self . network_filters . into_iter ( ) . for_each ( |filter| {
309+ // Don't process bad filter rules or matching bad filter rules.
310+ if bad_filter_ids. contains ( & filter. get_id ( ) ) || filter. is_badfilter ( ) {
311+ return ;
312+ }
299313 let original_rule = * filter
300314 . raw_line
301315 . clone ( )
Original file line number Diff line number Diff line change @@ -15,6 +15,17 @@ mod ab2cb_tests {
1515 ) ;
1616 }
1717
18+ fn test_from_abp_multi ( abp_rules : & [ & str ] , cb : & str ) {
19+ let mut filter_set = crate :: lists:: FilterSet :: new ( true ) ;
20+ filter_set. add_filters ( abp_rules, Default :: default ( ) ) ;
21+ let ( cb_rules, _) = filter_set. into_content_blocking ( ) . unwrap ( ) ;
22+ assert_eq ! (
23+ cb_rules,
24+ serde_json:: from_str:: <Vec <CbRule >>( cb)
25+ . expect( "content blocking rules under test could not be deserialized" )
26+ ) ;
27+ }
28+
1829 #[ test]
1930 fn ad_tests ( ) {
2031 test_from_abp (
@@ -653,6 +664,38 @@ mod ab2cb_tests {
653664 }]"#### ,
654665 ) ;
655666 }
667+
668+ #[ test]
669+ fn badfilter_cancels_matching_rules ( ) {
670+ // Test that BAD_FILTER rules cancel out matching rules
671+ // Input: regular rule, BAD_FILTER rule, and differently modified rule
672+ // Output: only the differently modified rule should remain (BAD_FILTER cancels the exact match)
673+ test_from_abp_multi (
674+ & [
675+ "||example.com^" ,
676+ "||example.com^$badfilter" ,
677+ "||example.com^$third-party" ,
678+ ] ,
679+ r####"[{
680+ "action": {
681+ "type": "block"
682+ },
683+ "trigger": {
684+ "url-filter": "^[^:]+:(//)?([^/]+\\.)?example\\.com",
685+ "load-type": ["third-party"]
686+ }
687+ }, {
688+ "action": {
689+ "type": "ignore-previous-rules"
690+ },
691+ "trigger": {
692+ "url-filter": ".*",
693+ "resource-type": ["document"],
694+ "load-type": ["first-party"]
695+ }
696+ }]"#### ,
697+ ) ;
698+ }
656699}
657700
658701#[ cfg( test) ]
You can’t perform that action at this time.
0 commit comments