mirror of https://github.com/gorhill/uBlock.git
Further fix new setTimeout-if/setInterval-if scriptlets
Addtionally, a dedicated test page has been added: https://gorhill.github.io/uBlock/tests/scriptlet-injection-filters-1.html
This commit is contained in:
parent
a7c852ca5d
commit
e0fd9750d4
|
@ -537,7 +537,7 @@
|
||||||
if ( delayNot ) { delay = delay.slice(1); }
|
if ( delayNot ) { delay = delay.slice(1); }
|
||||||
delay = parseInt(delay, 10);
|
delay = parseInt(delay, 10);
|
||||||
if ( needle === '' || needle === '{{1}}' ) {
|
if ( needle === '' || needle === '{{1}}' ) {
|
||||||
needle = '.?';
|
needle = '';
|
||||||
} else if ( needle.startsWith('/') && needle.endsWith('/') ) {
|
} else if ( needle.startsWith('/') && needle.endsWith('/') ) {
|
||||||
needle = needle.slice(1,-1);
|
needle = needle.slice(1,-1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -547,20 +547,24 @@
|
||||||
delayNot === false && isNaN(delay)
|
delayNot === false && isNaN(delay)
|
||||||
? console.log
|
? console.log
|
||||||
: undefined;
|
: undefined;
|
||||||
needle = new RegExp(needle);
|
const reNeedle = new RegExp(needle);
|
||||||
window.setInterval = new Proxy(window.setInterval, {
|
window.setInterval = new Proxy(window.setInterval, {
|
||||||
apply: function(target, thisArg, args) {
|
apply: function(target, thisArg, args) {
|
||||||
const a = String(args[0]);
|
const a = String(args[0]);
|
||||||
const b = args[1];
|
const b = args[1];
|
||||||
|
let defuse = false;
|
||||||
if ( log !== undefined ) {
|
if ( log !== undefined ) {
|
||||||
log('uBO: setInterval("%s", %s)', a, b);
|
log('uBO: setInterval("%s", %s)', a, b);
|
||||||
} else if (
|
} else if ( needle === '' && needleNot || isNaN(delay) && delayNot ) {
|
||||||
(
|
defuse = true;
|
||||||
isNaN(delay) && (delayNot || needleNot) ||
|
} else if ( isNaN(delay) ) {
|
||||||
isNaN(delay) === false && (b === delay) === delayNot
|
defuse = reNeedle.test(a) === needleNot;
|
||||||
) &&
|
} else if ( needle === '' ) {
|
||||||
(needle.test(a) === needleNot)
|
defuse = (b === delay) === delayNot;
|
||||||
) {
|
} else if ( reNeedle.test(a) === needleNot || (b === delay) === delayNot ) {
|
||||||
|
defuse = true;
|
||||||
|
}
|
||||||
|
if ( defuse ) {
|
||||||
args[0] = function(){};
|
args[0] = function(){};
|
||||||
}
|
}
|
||||||
return target.apply(thisArg, args);
|
return target.apply(thisArg, args);
|
||||||
|
@ -606,7 +610,7 @@
|
||||||
if ( delayNot ) { delay = delay.slice(1); }
|
if ( delayNot ) { delay = delay.slice(1); }
|
||||||
delay = parseInt(delay, 10);
|
delay = parseInt(delay, 10);
|
||||||
if ( needle === '' || needle === '{{1}}' ) {
|
if ( needle === '' || needle === '{{1}}' ) {
|
||||||
needle = '.?';
|
needle = '';
|
||||||
} else if ( needle.startsWith('/') && needle.endsWith('/') ) {
|
} else if ( needle.startsWith('/') && needle.endsWith('/') ) {
|
||||||
needle = needle.slice(1,-1);
|
needle = needle.slice(1,-1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -616,20 +620,24 @@
|
||||||
delayNot === false && isNaN(delay)
|
delayNot === false && isNaN(delay)
|
||||||
? console.log
|
? console.log
|
||||||
: undefined;
|
: undefined;
|
||||||
needle = new RegExp(needle);
|
const reNeedle = new RegExp(needle);
|
||||||
window.setTimeout = new Proxy(window.setTimeout, {
|
window.setTimeout = new Proxy(window.setTimeout, {
|
||||||
apply: function(target, thisArg, args) {
|
apply: function(target, thisArg, args) {
|
||||||
const a = String(args[0]);
|
const a = String(args[0]);
|
||||||
const b = args[1];
|
const b = args[1];
|
||||||
|
let defuse = false;
|
||||||
if ( log !== undefined ) {
|
if ( log !== undefined ) {
|
||||||
log('uBO: setTimeout("%s", %s)', a, b);
|
log('uBO: setTimeout("%s", %s)', a, b);
|
||||||
} else if (
|
} else if ( needle === '' && needleNot || isNaN(delay) && delayNot ) {
|
||||||
(
|
defuse = true;
|
||||||
isNaN(delay) && (delayNot || needleNot) ||
|
} else if ( isNaN(delay) ) {
|
||||||
isNaN(delay) === false && (b === delay) === delayNot
|
defuse = reNeedle.test(a) === needleNot;
|
||||||
) &&
|
} else if ( needle === '' ) {
|
||||||
(needle.test(a) === needleNot)
|
defuse = (b === delay) === delayNot;
|
||||||
) {
|
} else if ( reNeedle.test(a) === needleNot || (b === delay) === delayNot ) {
|
||||||
|
defuse = true;
|
||||||
|
}
|
||||||
|
if ( defuse ) {
|
||||||
args[0] = function(){};
|
args[0] = function(){};
|
||||||
}
|
}
|
||||||
return target.apply(thisArg, args);
|
return target.apply(thisArg, args);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
<li><a href="https://raw.githack.com/gorhill/uBlock/master/docs/tests/hnbigset-benchmark.html">HNTrie, small (2) to large (40,000+) set: benchmarks</a>
|
<li><a href="https://raw.githack.com/gorhill/uBlock/master/docs/tests/hnbigset-benchmark.html">HNTrie, small (2) to large (40,000+) set: benchmarks</a>
|
||||||
<li><a href="procedural-cosmetic-filters.html">Procedural cosmetic filters</a>
|
<li><a href="procedural-cosmetic-filters.html">Procedural cosmetic filters</a>
|
||||||
<li><a href="procedural-html-filters.html">Procedural HTML filters</a>
|
<li><a href="procedural-html-filters.html">Procedural HTML filters</a>
|
||||||
|
<li><a href="scriptlet-injection-filters-1.html">Scriptlet injection filters / setTimeout-if</a>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -0,0 +1,194 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Scriptlet injection filters / setTimeout-if</title>
|
||||||
|
<style>
|
||||||
|
.filters {
|
||||||
|
font-family: monospace;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
.filters td > b {
|
||||||
|
display: inline-block;
|
||||||
|
height: 1em;
|
||||||
|
margin-left: 2px;
|
||||||
|
width: 2em;
|
||||||
|
}
|
||||||
|
.filters td > b.G {
|
||||||
|
background-color: green;
|
||||||
|
}
|
||||||
|
.filters td > b.R {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
.tests {
|
||||||
|
align-items: flex-start;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.tile {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin: 0 20px 10px 0;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
.tile div {
|
||||||
|
align-items: center;
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.tile > div {
|
||||||
|
height: 50px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.tile > div > div {
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.tile > code {
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
.cell.bad {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
.cell.bad.notexecuted {
|
||||||
|
background-color: green;
|
||||||
|
}
|
||||||
|
.cell.good {
|
||||||
|
background-color: green;
|
||||||
|
}
|
||||||
|
.cell.good.notexecuted {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
.cell::before {
|
||||||
|
content: 'executed';
|
||||||
|
}
|
||||||
|
.cell.notexecuted::before {
|
||||||
|
content: 'not executed';
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Scriptlet injection filters / setTimeout-if</h1>
|
||||||
|
<p><a href="./.">Back</a>
|
||||||
|
<br><br></p>
|
||||||
|
<h3>Filters</h3>
|
||||||
|
<p>The filters below must be tried one by one, not all at the same
|
||||||
|
time. When you try a filter, ensure the result is what is expected.</p>
|
||||||
|
<noscript>Enable JavaScript to see needed filter</noscript>
|
||||||
|
<table class="filters">
|
||||||
|
<tr><th>Filter<th>Expected
|
||||||
|
<tr><td>None<td><b class="R"> </b><b class="R"> </b><b class="G"> </b><b class="G"> </b>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3>Results</h3>
|
||||||
|
<div id="sif" class="tests">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function createSetTimeout(fn, delay) {
|
||||||
|
self.addEventListener('load', ( ) => {
|
||||||
|
self.setTimeout(fn, delay)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function removeClass(sel, cls) {
|
||||||
|
document.querySelector(sel).classList.remove(cls);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="a1" class="tile">
|
||||||
|
<div class="cell bad notexecuted"></div>
|
||||||
|
<code>bad, 33</code>
|
||||||
|
<script>
|
||||||
|
createSetTimeout(
|
||||||
|
function() {
|
||||||
|
'bad';
|
||||||
|
removeClass('#a1 .cell', 'notexecuted');
|
||||||
|
},
|
||||||
|
33
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="a2" class="tile">
|
||||||
|
<div class="cell bad notexecuted"></div>
|
||||||
|
<code>bad, 66</code>
|
||||||
|
<script>
|
||||||
|
createSetTimeout(
|
||||||
|
function() {
|
||||||
|
'bad';
|
||||||
|
removeClass('#a2 .cell', 'notexecuted');
|
||||||
|
},
|
||||||
|
66
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="a3" class="tile">
|
||||||
|
<div class="cell good notexecuted"></div>
|
||||||
|
<code>good, 33</code>
|
||||||
|
<script>
|
||||||
|
createSetTimeout(
|
||||||
|
function() {
|
||||||
|
'good';
|
||||||
|
removeClass('#a3 .cell', 'notexecuted');
|
||||||
|
},
|
||||||
|
33
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="a4" class="tile">
|
||||||
|
<div class="cell good notexecuted"></div>
|
||||||
|
<code>good, 66</code>
|
||||||
|
<script>
|
||||||
|
createSetTimeout(
|
||||||
|
function() {
|
||||||
|
'good';
|
||||||
|
removeClass('#a4 .cell', 'notexecuted');
|
||||||
|
},
|
||||||
|
66
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const hostname = self.location.hostname;
|
||||||
|
const fragment = document.createDocumentFragment();
|
||||||
|
const filters = [
|
||||||
|
[ [ '!bad' ], 'GGGG' ],
|
||||||
|
[ [ 'good' ], 'GGGG' ],
|
||||||
|
[ [ '', '!33' ], 'GRRG' ],
|
||||||
|
[ [ '', '66' ], 'GRRG' ],
|
||||||
|
[ [ '!bad', '!33' ], 'GGRG' ],
|
||||||
|
[ [ 'good', '66' ], 'GGRG' ],
|
||||||
|
[ [ '!bad', '33' ], 'GGGR' ],
|
||||||
|
[ [ 'good', '!66' ], 'GGGR' ],
|
||||||
|
[ [ 'bad', '!33' ], 'GRRR' ],
|
||||||
|
[ [ '!good', '66' ], 'GRRR' ],
|
||||||
|
];
|
||||||
|
for ( const [ args, result ] of filters ) {
|
||||||
|
const tr = document.createElement('tr');
|
||||||
|
let td = document.createElement('td');
|
||||||
|
td.textContent = `${hostname}##+js(stif, ${args.join(', ')})`;
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
for ( let i = 0; i < result.length; i++ ) {
|
||||||
|
const b = document.createElement('b');
|
||||||
|
b.className = result.charAt(i);
|
||||||
|
b.textContent = '\xA0';
|
||||||
|
td.appendChild(b);
|
||||||
|
}
|
||||||
|
tr.appendChild(td);
|
||||||
|
fragment.appendChild(tr);
|
||||||
|
}
|
||||||
|
document.querySelector('.filters').appendChild(fragment);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue