Opened 18 months ago

Closed 17 months ago

Last modified 16 months 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 18 months 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 18 months ago by mjethani

It turns out that this is a known issue.

comment:3 Changed 18 months ago by mjethani

  • Description modified (diff)

comment:4 Changed 18 months ago by kzar

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

comment:5 Changed 18 months ago by mjethani

  • Keywords abp2blocklist Acceptable Ads externaldependency added; ab removed

comment:6 Changed 18 months 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 18 months ago by mjethani

  • Review URL(s) modified (diff)

comment:8 Changed 17 months ago by kzar

  • Priority changed from Unknown to P4
  • Ready set

comment:9 Changed 17 months ago by abpbot

comment:10 Changed 17 months ago by mjethani

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

comment:11 Changed 17 months 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 17 months ago by mjethani

  • Blocking 5464 added

comment:13 Changed 16 months ago by mjethani

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

Note: See TracTickets for help on using tickets.