Skip to content

Commit

Permalink
Match static popup filter against local context
Browse files Browse the repository at this point in the history
Related feedback:
- https://www.reddit.com/r/uBlockOrigin/comments/d6zbqv/

For static filter `popup` filter purpose, the URL of the
embedded frame from which the popup was launched will
be used in the matching algorithm.
  • Loading branch information
gorhill committed Sep 23, 2019
1 parent d15163d commit f204d24
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 47 deletions.
9 changes: 3 additions & 6 deletions platform/chromium/vapi-background.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,7 @@ vAPI.Tabs = class {
details.url = this.sanitizeURL(details.url);
this.onNavigation(details);
}
this.onCreated(
details.tabId,
details.sourceTabId
);
this.onCreated(details);
});

browser.webNavigation.onCommitted.addListener(details => {
Expand Down Expand Up @@ -592,7 +589,7 @@ vAPI.Tabs = class {
onClosed(/* tabId, details */) {
}

onCreated(/* openedTabId, openerTabId */) {
onCreated(/* details */) {
}

onNavigation(/* details */) {
Expand Down Expand Up @@ -655,7 +652,7 @@ if ( browser.windows instanceof Object ) {
// Ensure ImageData for toolbar icon is valid before use.

vAPI.setIcon = (( ) => {
const browserAction = browser.browserAction;
const browserAction = webext.browserAction;
const titleTemplate =
browser.runtime.getManifest().browser_action.default_title +
' ({badge})';
Expand Down
16 changes: 15 additions & 1 deletion platform/chromium/webext.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ const promisifyNoFail = function(thisArg, fnName, outFn = r => r) {
return function() {
return new Promise(resolve => {
fn.call(thisArg, ...arguments, function() {
void chrome.runtime.lastError;
if ( chrome.runtime.lastError instanceof Object ) {
void chrome.runtime.lastError.message;
}
resolve(outFn(...arguments));
});
});
Expand All @@ -55,6 +57,14 @@ const promisify = function(thisArg, fnName) {
};

const webext = {
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction
browserAction: {
onClicked: chrome.browserAction.onClicked,
setBadgeBackgroundColor: promisifyNoFail(chrome.browserAction, 'setBadgeBackgroundColor'),
setBadgeText: promisifyNoFail(chrome.browserAction, 'setBadgeText'),
setIcon: promisifyNoFail(chrome.browserAction, 'setIcon'),
setTitle: promisifyNoFail(chrome.browserAction, 'setTitle'),
},
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus
menus: {
create: function() {
Expand Down Expand Up @@ -89,6 +99,10 @@ const webext = {
remove: promisifyNoFail(chrome.tabs, 'remove'),
update: promisifyNoFail(chrome.tabs, 'update', tab => tab instanceof Object ? tab : null),
},
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation
webNavigation: {
getFrame: promisify(chrome.webNavigation, 'getFrame'),
},
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows
windows: {
get: promisifyNoFail(chrome.windows, 'get', win => win instanceof Object ? win : null),
Expand Down
109 changes: 69 additions & 40 deletions src/js/tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,13 @@

const popupMatch = function(
fctxt,
openerURL,
rootOpenerURL,
localOpenerURL,
targetURL,
popupType
popupType = 'popup'
) {
fctxt.setTabOriginFromURL(openerURL)
.setDocOriginFromURL(openerURL)
fctxt.setTabOriginFromURL(rootOpenerURL)
.setDocOriginFromURL(localOpenerURL || rootOpenerURL)
.setURL(targetURL)
.setType('popup');
let result;
Expand Down Expand Up @@ -231,10 +232,17 @@

const popunderMatch = function(
fctxt,
openerURL,
rootOpenerURL,
localOpenerURL,
targetURL
) {
let result = popupMatch(fctxt, targetURL, openerURL, 'popunder');
let result = popupMatch(
fctxt,
targetURL,
undefined,
rootOpenerURL,
'popunder'
);
if ( result === 1 ) { return result; }

// https://github.com/gorhill/uBlock/issues/1010#issuecomment-186824878
Expand All @@ -243,15 +251,15 @@
// a broad one, we will consider the opener tab to be a popunder tab.
// For now, a "broad" filter is one which does not touch any part of
// the hostname part of the opener URL.
let popunderURL = openerURL,
let popunderURL = rootOpenerURL,
popunderHostname = µb.URI.hostnameFromURI(popunderURL);
if ( popunderHostname === '' ) { return 0; }

result = mapPopunderResult(
fctxt,
popunderURL,
popunderHostname,
popupMatch(fctxt, targetURL, popunderURL, 'popup')
popupMatch(fctxt, targetURL, undefined, popunderURL)
);
if ( result !== 0 ) { return result; }

Expand All @@ -264,7 +272,7 @@
fctxt,
popunderURL,
popunderHostname,
popupMatch(fctxt, targetURL, popunderURL, 'popup')
popupMatch(fctxt, targetURL, undefined, popunderURL)
);
};

Expand All @@ -273,8 +281,11 @@
const openerTabId = openerDetails.tabId;
let tabContext = µb.tabContextManager.lookup(openerTabId);
if ( tabContext === null ) { return; }
const openerURL = tabContext.rawURL;
if ( openerURL === '' ) { return; }
const rootOpenerURL = tabContext.rawURL;
if ( rootOpenerURL === '' ) { return; }
const localOpenerURL = openerDetails.frameId !== 0
? openerDetails.frameURL
: undefined;

// Popup details.
tabContext = µb.tabContextManager.lookup(targetTabId);
Expand All @@ -283,21 +294,20 @@
if ( targetURL === '' ) { return; }

// https://github.com/gorhill/uBlock/issues/341
// Allow popups if uBlock is turned off in opener's context.
if ( µb.getNetFilteringSwitch(openerURL) === false ) { return; }
// Allow popups if uBlock is turned off in opener's context.
if ( µb.getNetFilteringSwitch(rootOpenerURL) === false ) { return; }

// https://github.com/gorhill/uBlock/issues/1538
if (
µb.getNetFilteringSwitch(µb.normalizePageURL(
openerTabId,
openerURL)
µb.getNetFilteringSwitch(
µb.normalizePageURL(openerTabId, rootOpenerURL)
) === false
) {
return;
}

// If the page URL is that of our "blocked page" URL, extract the URL of
// the page which was blocked.
// If the page URL is that of our "blocked page" URL, extract the URL
// of the page which was blocked.
if ( targetURL.startsWith(vAPI.getURL('document-blocked.html')) ) {
const matches = /details=([^&]+)/.exec(targetURL);
if ( matches !== null ) {
Expand All @@ -314,12 +324,12 @@
// https://github.com/gorhill/uBlock/issues/2919
// - If the target tab matches a clicked link, assume it's legit.
if ( areDifferentURLs(targetURL, openerDetails.trustedURL) ) {
result = popupMatch(fctxt, openerURL, targetURL, 'popup');
result = popupMatch(fctxt, rootOpenerURL, localOpenerURL, targetURL);
}

// Popunder test.
if ( result === 0 && openerDetails.popunder ) {
result = popunderMatch(fctxt, openerURL, targetURL);
result = popunderMatch(fctxt, rootOpenerURL, localOpenerURL, targetURL);
if ( result === 1 ) {
popupType = 'popunder';
}
Expand All @@ -332,10 +342,10 @@
if ( popupType === 'popup' ) {
fctxt.setURL(targetURL)
.setTabId(openerTabId)
.setTabOriginFromURL(openerURL)
.setDocOriginFromURL(openerURL);
.setTabOriginFromURL(rootOpenerURL)
.setDocOriginFromURL(localOpenerURL);
} else {
fctxt.setURL(openerURL)
fctxt.setURL(rootOpenerURL)
.setTabId(targetTabId)
.setTabOriginFromURL(targetURL)
.setDocOriginFromURL(targetURL);
Expand Down Expand Up @@ -446,12 +456,15 @@ housekeep itself.
const popupCandidates = new Map();

const PopupCandidate = class {
constructor(targetTabId, openerTabId) {
this.targetTabId = targetTabId;
constructor(createDetails, openerDetails) {
this.targetTabId = createDetails.tabId;
this.opener = {
tabId: openerTabId,
tabId: createDetails.sourceTabId,
tabURL: openerDetails[0].url,
frameId: createDetails.sourceFrameId,
frameURL: openerDetails[1].url,
popunder: false,
trustedURL: openerTabId === µb.maybeGoodPopup.tabId
trustedURL: createDetails.tabId === µb.maybeGoodPopup.tabId
? µb.maybeGoodPopup.url
: ''
};
Expand All @@ -477,10 +490,8 @@ housekeep itself.
}
};

const popupCandidateTest = function(targetTabId) {
for ( const entry of popupCandidates ) {
const tabId = entry[0];
const candidate = entry[1];
const popupCandidateTest = async function(targetTabId) {
for ( const [ tabId, candidate ] of popupCandidates ) {
if (
targetTabId !== tabId &&
targetTabId !== candidate.opener.tabId
Expand All @@ -493,23 +504,41 @@ housekeep itself.
if ( targetTabId === candidate.opener.tabId ) {
candidate.opener.popunder = true;
}
if ( µb.onPopupUpdated(tabId, candidate.opener) === true ) {
const result = await µb.onPopupUpdated(tabId, candidate.opener);
if ( result === true ) {
candidate.destroy();
} else {
candidate.launchSelfDestruction();
}
}
};

const onTabCreated = function(targetTabId, openerTabId) {
const popup = popupCandidates.get(targetTabId);
const onTabCreated = async function(createDetails) {
const { sourceTabId, sourceFrameId, tabId } = createDetails;
const popup = popupCandidates.get(tabId);
if ( popup === undefined ) {
let openerDetails;
try {
openerDetails = await Promise.all([
webext.webNavigation.getFrame({
tabId: createDetails.sourceTabId,
frameId: 0,
}),
webext.webNavigation.getFrame({
tabId: sourceTabId,
frameId: sourceFrameId,
}),
]);
}
catch (reason) {
return;
}
popupCandidates.set(
targetTabId,
new PopupCandidate(targetTabId, openerTabId)
tabId,
new PopupCandidate(createDetails, openerDetails)
);
}
popupCandidateTest(targetTabId);
popupCandidateTest(tabId);
};

const gcPeriod = 10 * 60 * 1000;
Expand Down Expand Up @@ -818,9 +847,9 @@ vAPI.Tabs = class extends vAPI.Tabs {
µBlock.contextMenu.update();
}

onCreated(targetTabId, openerTabId) {
super.onCreated(targetTabId, openerTabId);
µBlock.tabContextManager.onTabCreated(targetTabId, openerTabId);
onCreated(details) {
super.onCreated(details);
µBlock.tabContextManager.onTabCreated(details);
}

// When the DOM content of root frame is loaded, this means the tab
Expand Down

2 comments on commit f204d24

@gwarser
Copy link
Contributor

@gwarser gwarser commented on f204d24 Sep 23, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test 7 is not blocked in Chrome Version 77.0.3865.90 (Official Build) (64-bit), uBO b16

http://raymondhill.net/ublock/popup.html

Logger output
+0 blank.about-scheme 3 frame http://example.com/AdHandler.aspx?
+0 popup about:blank

@gorhill
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be blocked if you remove about-scheme from Whitelist.

Please sign in to comment.