Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#5345 closed defect (fixed)

[abp2blocklist] $elemhide not working on walmart.com

Reported by: mjethani Assignee: mjethani
Priority: P4 Milestone:
Module: Platform Keywords: abp2blocklist, Acceptable Ads, externaldependency
Cc: sebastian, kzar, mario Blocked By:
Blocking: #5464 Platform: Unknown / Cross platform
Ready: yes Confidential: no
Tester: Unknown Verified working: no
Review URL(s):

https://codereview.adblockplus.org/29473555/

Description (last modified by mjethani)

Environment

Safari 10.1.1 on macOS 10.12.5 using Adblock Plus built from the safari bookmark (changeset 3e423a0ad97f)

How to reproduce

  1. Go to the Options page enable Safari's native content blocking
  2. In the filter list, select EasyList and "Allow some non-intrusive advertising"
  3. Go to https://www.walmart.com/search/?query=car%20rental%20cologne
  4. Scroll to the bottom and wait a few seconds

Observed behaviour

Sponsored links are not displayed

Expected behaviour

Sponsored links should be displayed because walmart.com is whitelisted

Notes

The following filter hides the ad:

##.sponsored-container-bottom

Then the following filter is supposed to prevent the previous one from hiding the ad:

@@||walmart.com^$elemhide

It turns out that this is a known issue in WebKit.

Change History (13)

comment:1 Changed 2 years ago by mjethani

I created a rule set with just two rules to verify that this is broken:

{
  "trigger": {
    "url-filter": "^https?://"
  },
  "action": {
    "type": "css-display-none",
    "selector": ".sponsored-container-bottom"
  }
},
{
  "trigger": {
    "url-filter": "^https?://([^/]+\\.)?walmart\\.com"
  },
  "action": {
    "type": "ignore-previous-rules"
  }
}

Yep, it does not work. It's not ignoring the previous rule.

After some more analysis, I feel like this has something to do with the "specificity" (if there is such a thing for content blocker rules) of the url-filter field. The first one is more generic, it seems to be taking precedence! If I make the second one equally generic (^https?://) then it works. If the values are identical, it works. If the second one is more generic (simply swap the values), it works. I'm not one hundred percent sure what's going on, but I'm investigating.

Also, using if-domain instead of url-filter in the second rule works too. Maybe this is just a bug in Safari, and we might have to use this workaround.

By the way, this will affect $generichide and $genericblock as well.

comment:2 Changed 2 years ago by mjethani

It turns out that this is a known issue.

comment:3 Changed 2 years ago by mjethani

  • Description modified (diff)

comment:4 Changed 2 years ago by kzar

Ah bugger. In that case please add the externaldependency keyword to this issue.

comment:5 Changed 2 years ago by mjethani

  • Keywords abp2blocklist Acceptable Ads externaldependency added; ab removed

comment:6 Changed 2 years ago by mjethani

It seems that Safari creates a separate stylesheet for "generic" rules (ones that apply to all pages) and then does not support exceptions for those rules, unless the exceptions too are generic.

From the blog post (emphasis added):

When compiling the rules, we group the CSS rules whenever we determine they will be used together. For example, if a set of rules applies on every page (by using the filter “.*”), a special stylesheet is prepared for them to be ready to use them instantly when the page has loaded.

When a “ignore-previous-rules” appears, it forces the compiler to break the stylesheet since the rules appearing before an action “ignore-previous-rules” are all dismissed when the action is activated.

I tried to fool Safari into treating the generic rule as non-generic by replacing /^https?:\/\// with /^https?:\/\/[-A-Za-z0-9._~:\/?#[\]@!$&'()*+,;=`]+$/ (valid URL characters based on RFC 3986). This did not work.

Our only option then is to make the exception too generic by using the if-domain field instead. This will unfortunately give us false negatives (since we're whitelisting the entire domain), but we might be able to fix this by using if-top-url instead. It will also continue to give us false positives inside of frames.

comment:7 Changed 2 years ago by mjethani

  • Review URL(s) modified (diff)

comment:8 Changed 2 years ago by kzar

  • Priority changed from Unknown to P4
  • Ready set

comment:9 Changed 2 years ago by abpbot

comment:10 Changed 2 years ago by mjethani

  • Resolution set to fixed
  • Status changed from new to closed

comment:11 Changed 2 years ago by mjethani

The WebKit issue has been closed as "invalid". I've left a comment explaining the Adblock Plus issue. Meanwhile this is resolved for now using a workaround.

comment:12 Changed 2 years ago by mjethani

  • Blocking 5464 added

comment:13 Changed 2 years ago by mjethani

I've reported a new issue in WebKit: #175177

Note: See TracTickets for help on using tickets.