Skip to content

Commit 3ab7319

Browse files
committed
Address multiple static filter parser issues
Add gutter widget in editor when a filter is not supported on the current platform: uBlockOrigin/uBlock-issues#4096 Fix error count improperly updated when end of change is not at start of line: uBlockOrigin/uBlock-issues#4097 Add support for redirectable resources to require trusted source: 933efff4dd#r198472817 Detect mismatch between resources requiring trusted source and untrusted source at static filter parsing time.
1 parent c9eb5b2 commit 3ab7319

15 files changed

Lines changed: 141 additions & 56 deletions

‎platform/mv3/extension/js/offscreen/compile-filters.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import * as s14e from '../../lib/s14e-serializer.js';
2424
import * as sfp from '../static-filtering-parser.js';
2525
import { minimizeRules, minimizeRuleset, validateRules } from '../ubo-parser.js';
2626
import { fetchList } from './fetch-list.js';
27+
import { getTrustedTokens } from '../trusted-tokens.js';
2728
import { makeCosmeticScripts } from './make-cosmetic-filters.js';
2829
import { parseNetworkFilter } from '../ubo-parser.js';
2930
import { safeReplace } from './safe-replace.js';
@@ -346,6 +347,7 @@ async function updateList(list) {
346347

347348
const compiled = compileFilters(list.id, text, {
348349
nativeCssHas: true,
350+
trustedTokens: getTrustedTokens(),
349351
});
350352
if ( Boolean(compiled) === false ) { return; }
351353

‎src/css/codemirror.css‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,9 +320,12 @@ html:not(.mobile) .cm-search-widget .fa-icon:not(.fa-icon-ro):hover {
320320
.CodeMirror-lintmarker > * {
321321
position: absolute;
322322
}
323-
.CodeMirror-lintmarker[data-error="y"] {
323+
.CodeMirror-lintmarker[data-lint="error"] {
324324
background-color: var(--sf-error-ink);
325325
}
326+
.CodeMirror-lintmarker[data-lint="warning"] {
327+
background-color: var(--sf-warning-ink);
328+
}
326329
.CodeMirror-lintmarker .msg {
327330
background-color: var(--surface-0);
328331
border: 1px solid var(--sf-error-ink);
@@ -340,7 +343,8 @@ html:not(.mobile) .cm-search-widget .fa-icon:not(.fa-icon-ro):hover {
340343
top: 15%;
341344
width: 70%;
342345
}
343-
.CodeMirror-lintmarker[data-error="y"] svg {
346+
.CodeMirror-lintmarker[data-lint="error"] svg,
347+
.CodeMirror-lintmarker[data-lint="warning"] svg {
344348
display: none;
345349
}
346350
.CodeMirror-lintmarker[data-fold="start"] {
@@ -352,8 +356,10 @@ html:not(.mobile) .cm-search-widget .fa-icon:not(.fa-icon-ro):hover {
352356
.CodeMirror-lintmarker[data-fold="end"] {
353357
fill: var(--border-2);
354358
}
355-
.CodeMirror-lintmarker[data-error="y"]:hover > span,
356-
.CodeMirror-lintmarker[data-error="y"] > span:hover {
359+
.CodeMirror-lintmarker[data-lint="error"]:hover > span,
360+
.CodeMirror-lintmarker[data-lint="error"] > span:hover,
361+
.CodeMirror-lintmarker[data-lint="warning"]:hover > span,
362+
.CodeMirror-lintmarker[data-lint="warning"] > span:hover {
357363
display: initial;
358364
}
359365

‎src/css/themes/default.css‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@
290290
--sf-unicode-ink: var(--ink-1);
291291
--sf-value-ink: #974900 /* h:30 S:100 Luv:40 */;
292292
--sf-variable-ink: var(--ink-1);
293-
--sf-warning-ink: #e49d00; /* h:50 S:100 Luv:70 */
293+
--sf-warning-ink: #ffbb03; /* h:50 S:100 Luv:70 */
294294
--sf-warning-surface: #e49d0033; /* h:50 S:100 Luv:70 @ 20% */
295295

296296
/* syntax highlight: dynamic filtering */

‎src/js/1p-filters.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ uBlockDashboard.patchCodeMirrorEditor(cmEditor);
8080
}
8181

8282
vAPI.messaging.send('dashboard', {
83-
what: 'getTrustedScriptletTokens',
83+
what: 'getTrustedTokens',
8484
}).then(tokens => {
85-
cmEditor.setOption('trustedScriptletTokens', tokens);
85+
cmEditor.setOption('trustedTokens', tokens);
8686
});
8787

8888
/******************************************************************************/

‎src/js/asset-viewer.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ import { dom, qs$ } from './dom.js';
7373
});
7474

7575
vAPI.messaging.send('dashboard', {
76-
what: 'getTrustedScriptletTokens',
76+
what: 'getTrustedTokens',
7777
}).then(tokens => {
78-
cmEditor.setOption('trustedScriptletTokens', tokens);
78+
cmEditor.setOption('trustedTokens', tokens);
7979
});
8080

8181
const details = await vAPI.messaging.send('default', {

‎src/js/codemirror/ubo-static-filtering.js‎

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ CodeMirror.defineOption('trustedSource', false, (cm, trusted) => {
4646
}));
4747
});
4848

49-
CodeMirror.defineOption('trustedScriptletTokens', undefined, (cm, tokens) => {
49+
CodeMirror.defineOption('trustedTokens', undefined, (cm, tokens) => {
5050
if ( tokens === undefined || tokens === null ) { return; }
5151
if ( typeof tokens[Symbol.iterator] !== 'function' ) { return; }
52-
self.dispatchEvent(new CustomEvent('trustedScriptletTokens', {
52+
self.dispatchEvent(new CustomEvent('trustedTokens', {
5353
detail: new Set(tokens),
5454
}));
5555
});
@@ -226,6 +226,7 @@ const uBOStaticFilteringMode = (( ) => {
226226
this.astParser = new sfp.AstFilterParser({
227227
interactive: true,
228228
nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'),
229+
canFilterResponseBody: vAPI.webextFlavor.env.includes('html_filtering'),
229230
});
230231
this.astWalker = this.astParser.getWalker();
231232
this.currentWalkerNode = 0;
@@ -234,8 +235,8 @@ const uBOStaticFilteringMode = (( ) => {
234235
const { trusted } = ev.detail;
235236
this.astParser.options.trustedSource = trusted;
236237
});
237-
self.addEventListener('trustedScriptletTokens', ev => {
238-
this.astParser.options.trustedScriptletTokens = ev.detail;
238+
self.addEventListener('trustedTokens', ev => {
239+
this.astParser.options.trustedTokens = ev.detail;
239240
});
240241
}
241242
}
@@ -346,6 +347,7 @@ function initHints() {
346347
const astParser = new sfp.AstFilterParser({
347348
interactive: true,
348349
nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'),
350+
canFilterResponseBody: vAPI.webextFlavor.env.includes('html_filtering'),
349351
});
350352
const proceduralOperatorNames = new Map(
351353
Array.from(sfp.proceduralOperatorTokens)
@@ -715,6 +717,7 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
715717
const astParser = new sfp.AstFilterParser({
716718
interactive: true,
717719
nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'),
720+
canFilterResponseBody: vAPI.webextFlavor.env.includes('html_filtering'),
718721
});
719722

720723
const changeset = [];
@@ -760,6 +763,9 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
760763
case sfp.AST_ERROR_UNTRUSTED_SOURCE:
761764
msg = `${msg}: Filter requires trusted source`;
762765
break;
766+
case sfp.AST_ERROR_CAPABILITY:
767+
msg = `Filter unsupported on current platform`;
768+
return { lint: 'warning', msg };
763769
default:
764770
if ( astParser.isCosmeticFilter() && astParser.result.error ) {
765771
msg = `${msg}: ${astParser.result.error}`;
@@ -819,6 +825,14 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
819825
'</div>',
820826
],
821827
},
828+
'warning': {
829+
node: null,
830+
html: [
831+
'<div class="CodeMirror-lintmarker" data-lint="warning">&nbsp;',
832+
'<span class="msg"></span>',
833+
'</div>',
834+
],
835+
},
822836
'if-start': {
823837
node: null,
824838
html: [
@@ -963,8 +977,8 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
963977
};
964978

965979
const processDeletion = (doc, change) => {
966-
let { from, to } = change;
967-
doc.eachLine(from.line, to.line, lineHandle => {
980+
const { from, to } = change;
981+
doc.eachLine(from.line, to.line + (to.ch ? 1 : 0), lineHandle => {
968982
const marker = extractMarker(lineHandle);
969983
if ( marker === null ) { return; }
970984
if ( marker.dataset.error === 'y' ) {
@@ -1116,8 +1130,8 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
11161130
astParser.options.trustedSource = trusted;
11171131
});
11181132

1119-
self.addEventListener('trustedScriptletTokens', ev => {
1120-
astParser.options.trustedScriptletTokens = ev.detail;
1133+
self.addEventListener('trustedTokens', ev => {
1134+
astParser.options.trustedTokens = ev.detail;
11211135
});
11221136

11231137
CodeMirror.defineInitHook(cm => {

‎src/js/messaging.js‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import cacheStorage from './cachestorage.js';
4242
import cosmeticFilteringEngine from './cosmetic-filtering.js';
4343
import { denseBase64 } from './base64-custom.js';
4444
import { filteringBehaviorChanged } from './broadcast.js';
45+
import { getTrustedTokens } from './trusted-tokens.js';
4546
import htmlFilteringEngine from './html-filtering.js';
4647
import { i18n$ } from './i18n.js';
4748
import io from './assets.js';
@@ -155,7 +156,7 @@ const onMessage = function(request, sender, callback) {
155156

156157
case 'getAppData':
157158
response = {
158-
name: browser.runtime.getManifest().name,
159+
name: self.browser.runtime.getManifest().name,
159160
version: vAPI.app.version,
160161
canBenchmark: µb.hiddenSettings.benchmarkDatasetURL !== 'unset',
161162
};
@@ -165,8 +166,8 @@ const onMessage = function(request, sender, callback) {
165166
response = getDomainNames(request.targets);
166167
break;
167168

168-
case 'getTrustedScriptletTokens':
169-
response = redirectEngine.getTrustedScriptletTokens();
169+
case 'getTrustedTokens':
170+
response = Array.from(getTrustedTokens());
170171
break;
171172

172173
case 'getWhitelist':

‎src/js/redirect-engine.js‎

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -423,26 +423,6 @@ class RedirectEngine {
423423
});
424424
}
425425

426-
getTrustedScriptletTokens() {
427-
const out = [];
428-
const isTrustedScriptlet = entry => {
429-
if ( entry.requiresTrust !== true ) { return false; }
430-
if ( entry.warURL !== undefined ) { return false; }
431-
if ( typeof entry.data !== 'string' ) { return false; }
432-
if ( entry.name.endsWith('.js') === false ) { return false; }
433-
return true;
434-
};
435-
for ( const [ name, entry ] of this.resources ) {
436-
if ( isTrustedScriptlet(entry) === false ) { continue; }
437-
out.push(name.slice(0, -3));
438-
}
439-
for ( const [ alias, name ] of this.aliases ) {
440-
if ( out.includes(name.slice(0, -3)) === false ) { continue; }
441-
out.push(alias.slice(0, -3));
442-
}
443-
return out;
444-
}
445-
446426
selfieFromResources(storage) {
447427
return storage.toCache(RESOURCES_SELFIE_NAME, {
448428
version: RESOURCES_SELFIE_VERSION,

‎src/js/redirect-resources.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ export default new Map([
100100
data: 'text',
101101
} ],
102102
[ 'google-ima-dai.js', {
103-
aliases: [ 'google-ima3-dai' ], /* adguard compatibility */
103+
alias: 'google-ima3-dai', /* adguard compatibility */
104104
data: 'text',
105+
requiresTrust: true,
105106
} ],
106107
[ 'googlesyndication_adsbygoogle.js', {
107108
alias: [

‎src/js/scriptlet-filtering-core.js‎

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,13 @@ import { redirectEngine as reng } from './redirect-engine.js';
2525

2626
/******************************************************************************/
2727

28-
const normalizeRawFilter = (parser, sourceIsTrusted = false) => {
28+
const normalizeRawFilter = parser => {
2929
const args = parser.getScriptletArgs();
3030
if ( args.length !== 0 ) {
3131
let token = `${args[0]}.js`;
3232
if ( reng.aliases.has(token) ) {
3333
token = reng.aliases.get(token);
3434
}
35-
if ( parser.isException() !== true ) {
36-
if ( sourceIsTrusted !== true ) {
37-
if ( reng.tokenRequiresTrust(token) ) { return; }
38-
}
39-
}
4035
args[0] = token.slice(0, -3);
4136
}
4237
return JSON.stringify(args);
@@ -139,7 +134,7 @@ export class ScriptletFilteringEngine {
139134

140135
// Only exception filters are allowed to be global.
141136
const isException = parser.isException();
142-
const normalized = normalizeRawFilter(parser, writer.properties.get('trustedSource'));
137+
const normalized = normalizeRawFilter(parser);
143138

144139
// Can fail if there is a mismatch with trust requirement
145140
if ( normalized === undefined ) { return; }

0 commit comments

Comments
 (0)