From 43d08d7737d0ea2e945d3017419a5ffed17e7c1a Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Fri, 6 Mar 2026 11:38:50 -0500 Subject: [PATCH] investigate to= issue --- platform/mv3/safari/patch-ruleset.js | 51 ++++++++++++++++++++++++++++ src/js/static-net-filtering.js | 8 ++--- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/platform/mv3/safari/patch-ruleset.js b/platform/mv3/safari/patch-ruleset.js index a821251e1..31214b0b4 100644 --- a/platform/mv3/safari/patch-ruleset.js +++ b/platform/mv3/safari/patch-ruleset.js @@ -19,6 +19,44 @@ Home: https://github.com/gorhill/uBlock */ +const restrSeparator = '(?:[^%.0-9a-z_-]|$)'; +const rePlainChars = /[.+?${}()|[\]\\]/g; +const reSeparators = /\^/g; +const reDanglingAsterisks = /^\*+|\*+$/g; +const reAsterisks = /\*+/g; +const restrHostnameAnchor1 = '^[a-z-]+://(?:[^/?#]+\\.)?'; +const restrHostnameAnchor2 = '^[a-z-]+://(?:[^/?#]+)?'; + +function regexFilterFromUrlFilter(urlFilter) { + let regexFilter = urlFilter; + if ( urlFilter.startsWith('||') ) { + regexFilter = regexFilter.slice(2); + } else if ( urlFilter.startsWith('|') ) { + regexFilter = regexFilter.slice(1); + } + if ( urlFilter.endsWith('|') ) { + regexFilter = regexFilter.slice(0, -1); + } + regexFilter = regexFilter.replace(rePlainChars, '\\$&') + .replace(reSeparators, restrSeparator) + .replace(reDanglingAsterisks, '') + .replace(reAsterisks, '.*?'); + if ( urlFilter.startsWith('||') ) { + regexFilter = ( + regexFilter.startsWith('\\.') ? + restrHostnameAnchor2 : + restrHostnameAnchor1 + ) + regexFilter; + } else if ( urlFilter.startsWith('|') ) { + regexFilter = `^${regexFilter}`; + } + if ( urlFilter.endsWith('|') ) { + regexFilter = `${regexFilter}$`; + } + console.info(`converting "${urlFilter}" to "${regexFilter}"`); + return regexFilter; +} + // https://github.com/uBlockOrigin/uBOL-home/issues/539 function patchRuleForIssue539(rule) { const { condition } = rule; @@ -39,6 +77,18 @@ function patchRuleForIssue539(rule) { } } +// https://github.com/WebKit/WebKit/blob/6cef2858442a4012b783876efd7dd8c0c5669cf9/Source/WebKit/UIProcess/Extensions/Cocoa/_WKWebExtensionDeclarativeNetRequestRule.mm#L1134 +function patchRuleWithTo(rule) { + const { condition } = rule; + if ( Array.isArray(condition.requestDomains) === false ) { return; } + const { urlFilter } = condition; + if ( urlFilter === undefined ) { return; } + if ( urlFilter.includes('*') === false ) { return; } + if ( urlFilter.includes('/') === false ) { return; } + condition.regexFilter = regexFilterFromUrlFilter(urlFilter); + condition.urlFilter = undefined; +} + function patchRule(rule, out) { const copy = structuredClone(rule); const condition = copy.condition; @@ -62,6 +112,7 @@ function patchRule(rule, out) { delete condition.excludedInitiatorDomains; } patchRuleForIssue539(copy); + patchRuleWithTo(copy); // https://github.com/uBlockOrigin/uBOL-home/issues/434 let { urlFilter } = condition; if ( urlFilter?.endsWith('^') ) { diff --git a/src/js/static-net-filtering.js b/src/js/static-net-filtering.js index 18be63231..f1d6f03ec 100644 --- a/src/js/static-net-filtering.js +++ b/src/js/static-net-filtering.js @@ -314,7 +314,7 @@ const $httpHeaders = { // Local helpers -const restrSeparator = '(?:[^%.0-9a-z_-]|$)'; +const restrSeparator = '([^%.0-9a-z_-]|$)'; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions const reEscape = /[.*+?^${}()|[\]\\]/g; @@ -326,7 +326,7 @@ const restrFromGenericPattern = function(s, anchor = 0) { let reStr = s.replace(restrFromGenericPattern.rePlainChars, '\\$&') .replace(restrFromGenericPattern.reSeparators, restrSeparator) .replace(restrFromGenericPattern.reDanglingAsterisks, '') - .replace(restrFromGenericPattern.reAsterisks, '\\S*?'); + .replace(restrFromGenericPattern.reAsterisks, ' .*?'); if ( anchor & 0b100 ) { reStr = ( reStr.startsWith('\\.') ? @@ -345,8 +345,8 @@ restrFromGenericPattern.rePlainChars = /[.+?${}()|[\]\\]/g; restrFromGenericPattern.reSeparators = /\^/g; restrFromGenericPattern.reDanglingAsterisks = /^\*+|\*+$/g; restrFromGenericPattern.reAsterisks = /\*+/g; -restrFromGenericPattern.restrHostnameAnchor1 = '^[a-z-]+://(?:[^/?#]+\\.)?'; -restrFromGenericPattern.restrHostnameAnchor2 = '^[a-z-]+://(?:[^/?#]+)?'; +restrFromGenericPattern.restrHostnameAnchor1 = '^[a-z-]+://([^/?#]+\\.)?'; +restrFromGenericPattern.restrHostnameAnchor2 = '^[a-z-]+://([^/?#]+)?'; /******************************************************************************/