Skip to content

Commit

Permalink
merge 1.58.1rc11
Browse files Browse the repository at this point in the history
  • Loading branch information
mneunomne committed Jul 25, 2024
2 parents 0dcdbae + b7676e8 commit 05ec6d1
Show file tree
Hide file tree
Showing 24 changed files with 328 additions and 160 deletions.
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
- [Improve `href-sanitizer` scriptlet](https://github.com/gorhill/uBlock/commit/84be9cde6d)
- [Improve `trusted-replace-node-text` scriptlet](https://github.com/gorhill/uBlock/commit/8afd9e233d)
- [Improve `set-constant` scriptlet](https://github.com/gorhill/uBlock/commit/77feb25c4d)
- [Improve `prevent-fetch` scriptlet](https://github.com/gorhill/uBlock/commit/e785b99338)
- [Improve `href-sanitizer` scriptlet](https://github.com/gorhill/uBlock/commit/66e3a1ad47)
- [Fix CSP/PP header injection in non-document resources](https://github.com/gorhill/uBlock/commit/c90f4933df)
- [Add `trusted-suppress-native-method` scriptlet](https://github.com/gorhill/uBlock/commit/97d11c03c2)
- [Add support for `$currentISODate$` in `trusted-set-cookie` scriptlet](https://github.com/gorhill/uBlock/commit/a3576ea651)
- [Add `essential` and `nonessential` to set-cookie](https://github.com/gorhill/uBlock/commit/37d31a82d8) (by @ryanbr)
- [Fix distance calculation in picker](https://github.com/gorhill/uBlock/commit/9569969b55)
- [Fix bad serialization of Date objects](https://github.com/gorhill/uBlock/commit/c154aaa69c)
- [Fix race condition when loading redirect/scriptlet resources](https://github.com/gorhill/uBlock/commit/896737d098)
- [Improve logging in `prevent-addEventListener` scriptlet](https://github.com/gorhill/uBlock/commit/8eb3b19c69)
- [Add `:matches-prop()` pseudo CSS operator](https://github.com/gorhill/uBlock/commit/aca7674bac)
- [Improve `set-cookie` scriptlet](https://github.com/gorhill/uBlock/commit/b4d8750f44)
- [Improve `trusted-replace-node-text` scriptlet](https://github.com/gorhill/uBlock/commit/cb0f65e035)
- [Improve `trusted-replace-[fetch|xhr]-response` scriptlets](https://github.com/gorhill/uBlock/commit/9072772f61)
- [Improve `trusted-replace-(fetch|xhr)-response` scriptlets](https://github.com/gorhill/uBlock/commit/9072772f61)
- [Improve `prevent-addEventListener` scriptlet](https://github.com/gorhill/uBlock/commit/91ee5bdeae)
- [Add `isodate` as available placeholder for auto-comment](https://github.com/gorhill/uBlock/commit/d5208ee5dd)
- [Improve `trusted-replace-outbound-text` scriptlet](https://github.com/gorhill/uBlock/commit/fa6740a059)
Expand Down
4 changes: 2 additions & 2 deletions assets/assets.dev.json
Original file line number Diff line number Diff line change
Expand Up @@ -681,8 +681,8 @@
"title": "🇮🇸is: Icelandic ABP List",
"tags": "ads icelandic",
"lang": "is",
"contentURL": "https://adblock.gardar.net/is.abp.txt",
"supportURL": "https://adblock.gardar.net/"
"contentURL": "https://raw.githubusercontent.com/brave/adblock-lists/master/custom/is.txt",
"supportURL": "https://github.com/brave/adblock-lists/issues"
},
"ISR-0": {
"content": "filters",
Expand Down
4 changes: 2 additions & 2 deletions assets/assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -713,8 +713,8 @@
"title": "🇮🇸is: Icelandic ABP List",
"tags": "ads icelandic",
"lang": "is",
"contentURL": "https://adblock.gardar.net/is.abp.txt",
"supportURL": "https://adblock.gardar.net/"
"contentURL": "https://raw.githubusercontent.com/brave/adblock-lists/master/custom/is.txt",
"supportURL": "https://github.com/brave/adblock-lists/issues"
},
"ISR-0": {
"content": "filters",
Expand Down
213 changes: 168 additions & 45 deletions assets/resources/scriptlets.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ function safeSelf() {
'Math_random': Math.random,
'Object': Object,
'Object_defineProperty': Object.defineProperty.bind(Object),
'Object_defineProperties': Object.defineProperties.bind(Object),
'Object_fromEntries': Object.fromEntries.bind(Object),
'Object_getOwnPropertyDescriptor': Object.getOwnPropertyDescriptor.bind(Object),
'RegExp': self.RegExp,
Expand Down Expand Up @@ -484,9 +485,8 @@ builtinScriptlets.push({
'safe-self.fn',
],
});
function validateConstantFn(trusted, raw) {
function validateConstantFn(trusted, raw, extraArgs = {}) {
const safe = safeSelf();
const extraArgs = safe.getExtraArgs(Array.from(arguments), 2);
let value;
if ( raw === 'undefined' ) {
value = undefined;
Expand Down Expand Up @@ -586,7 +586,7 @@ function setConstantFn(
};
if ( trappedProp === '' ) { return; }
const thisScript = document.currentScript;
let normalValue = validateConstantFn(trusted, rawValue);
let normalValue = validateConstantFn(trusted, rawValue, extraArgs);
if ( rawValue === 'noopFunc' || rawValue === 'trueFunc' || rawValue === 'falseFunc' ) {
normalValue = cloakFunc(normalValue);
}
Expand Down Expand Up @@ -714,7 +714,12 @@ function replaceNodeTextFn(
const reNodeName = safe.patternToRegex(nodeName, 'i', true);
const rePattern = safe.patternToRegex(pattern, 'gms');
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
const reCondition = safe.patternToRegex(extraArgs.condition || '', 'ms');
const reIncludes = extraArgs.includes || extraArgs.condition
? safe.patternToRegex(extraArgs.includes || extraArgs.condition, 'ms')
: null;
const reExcludes = extraArgs.excludes
? safe.patternToRegex(extraArgs.excludes, 'ms')
: null;
const stop = (takeRecord = true) => {
if ( takeRecord ) {
handleMutations(observer.takeRecords());
Expand All @@ -727,8 +732,14 @@ function replaceNodeTextFn(
let sedCount = extraArgs.sedCount || 0;
const handleNode = node => {
const before = node.textContent;
reCondition.lastIndex = 0;
if ( safe.RegExp_test.call(reCondition, before) === false ) { return true; }
if ( reIncludes ) {
reIncludes.lastIndex = 0;
if ( safe.RegExp_test.call(reIncludes, before) === false ) { return true; }
}
if ( reExcludes ) {
reExcludes.lastIndex = 0;
if ( safe.RegExp_test.call(reExcludes, before) ) { return true; }
}
rePattern.lastIndex = 0;
if ( safe.RegExp_test.call(rePattern, before) === false ) { return true; }
rePattern.lastIndex = 0;
Expand Down Expand Up @@ -1661,7 +1672,9 @@ function addEventListenerDefuser(
if ( elem instanceof Document ) { return 'document'; }
if ( elem instanceof Element === false ) { return '?'; }
const parts = [];
if ( elem.id !== '' ) { parts.push(`#${CSS.escape(elem.id)}`); }
// https://github.com/uBlockOrigin/uAssets/discussions/17907#discussioncomment-9871079
const id = String(elem.id);
if ( id !== '' ) { parts.push(`#${CSS.escape(id)}`); }
for ( let i = 0; i < elem.classList.length; i++ ) {
parts.push(`.${CSS.escape(elem.classList.item(i))}`);
}
Expand Down Expand Up @@ -2065,11 +2078,11 @@ builtinScriptlets.push({
});
function noFetchIf(
propsToMatch = '',
responseBody = ''
responseBody = '',
responseType = ''
) {
if ( typeof propsToMatch !== 'string' ) { return; }
const safe = safeSelf();
const logPrefix = safe.makeLogPrefix('prevent-fetch', propsToMatch, responseBody);
const logPrefix = safe.makeLogPrefix('prevent-fetch', propsToMatch, responseBody, responseType);
const needles = [];
for ( const condition of propsToMatch.split(/\s+/) ) {
if ( condition === '' ) { continue; }
Expand All @@ -2084,6 +2097,28 @@ function noFetchIf(
}
needles.push({ key, re: safe.patternToRegex(value) });
}
const validResponseProps = {
ok: [ false, true ],
statusText: [ '', 'Not Found' ],
type: [ 'basic', 'cors', 'default', 'error', 'opaque' ],
};
const responseProps = {
statusText: { value: 'OK' },
};
if ( /^\{.*\}$/.test(responseType) ) {
try {
Object.entries(JSON.parse(responseType)).forEach(([ p, v ]) => {
if ( validResponseProps[p] === undefined ) { return; }
if ( validResponseProps[p].includes(v) === false ) { return; }
responseProps[p] = { value: v };
});
}
catch(ex) {}
} else if ( responseType !== '' ) {
if ( validResponseProps.type.includes(responseType) ) {
responseProps.type = { value: responseType };
}
}
self.fetch = new Proxy(self.fetch, {
apply: function(target, thisArg, args) {
const details = args[0] instanceof self.Request
Expand Down Expand Up @@ -2121,33 +2156,18 @@ function noFetchIf(
if ( proceed ) {
return Reflect.apply(target, thisArg, args);
}
let responseType = '';
if ( details.mode === undefined || details.mode === 'cors' ) {
try {
const desURL = new URL(details.url);
responseType = desURL.origin !== document.location.origin
? 'cors'
: 'basic';
} catch(ex) {
safe.uboErr(logPrefix, `Error: ${ex}`);
}
}
return generateContentFn(responseBody).then(text => {
safe.adnlog(logPrefix, `Prevented with response "${text}"`);
const response = new Response(text, {
statusText: 'OK',
headers: {
'Content-Length': text.length,
}
});
safe.Object_defineProperty(response, 'url', {
value: details.url
});
if ( responseType !== '' ) {
safe.Object_defineProperty(response, 'type', {
value: responseType
});
}
const props = Object.assign(
{ url: { value: details.url } },
responseProps
);
safe.Object_defineProperties(response, props);
return response;
});
}
Expand Down Expand Up @@ -3475,25 +3495,34 @@ function hrefSanitizer(
};
const validateURL = text => {
if ( text === '' ) { return ''; }
if ( /[^\x21-\x7e]/.test(text) ) { return ''; }
if ( /[\x00-\x20\x7f]/.test(text) ) { return ''; }
try {
const url = new URL(text, document.location);
return url.href;
} catch(ex) {
}
return '';
};
const extractParam = (href, source) => {
if ( Boolean(source) === false ) { return href; }
const recursive = source.includes('?', 1);
const end = recursive ? source.indexOf('?', 1) : source.length;
try {
const url = new URL(href, document.location);
const value = url.searchParams.get(source.slice(1, end));
if ( value === null ) { return href }
if ( recursive ) { return extractParam(value, source.slice(end)); }
return value;
} catch(x) {
}
return href;
};
const extractText = (elem, source) => {
if ( /^\[.*\]$/.test(source) ) {
return elem.getAttribute(source.slice(1,-1).trim()) || '';
}
if ( source.startsWith('?') ) {
try {
const url = new URL(elem.href, document.location);
return url.searchParams.get(source.slice(1)) || '';
} catch(x) {
}
return '';
return extractParam(elem.href, source);
}
if ( source === 'text' ) {
return elem.textContent
Expand Down Expand Up @@ -3740,10 +3769,10 @@ builtinScriptlets.push({
});
function removeNodeText(
nodeName,
condition,
includes,
...extraArgs
) {
replaceNodeTextFn(nodeName, '', '', 'condition', condition || '', ...extraArgs);
replaceNodeTextFn(nodeName, '', '', 'includes', includes || '', ...extraArgs);
}

/*******************************************************************************
Expand Down Expand Up @@ -3789,6 +3818,7 @@ function setCookie(
'necessary', 'required',
'approved', 'disapproved',
'hide', 'hidden',
'essential', 'nonessential',
];
const normalized = value.toLowerCase();
const match = /^("?)(.+)\1$/.exec(normalized);
Expand Down Expand Up @@ -4245,6 +4275,9 @@ function trustedSetCookie(
if ( value.includes('$currentDate$') ) {
value = value.replaceAll('$currentDate$', time.toUTCString());
}
if ( value.includes('$currentISODate$') ) {
value = value.replaceAll('$currentISODate$', time.toISOString());
}

let expires = '';
if ( offsetExpiresSec !== '' ) {
Expand Down Expand Up @@ -4750,24 +4783,29 @@ builtinScriptlets.push({
});
function trustedReplaceArgument(
propChain = '',
argpos = '',
argposRaw = '',
argraw = ''
) {
if ( propChain === '' ) { return; }
if ( argpos === '' ) { return; }
if ( argraw === '' ) { return; }
const safe = safeSelf();
const logPrefix = safe.makeLogPrefix('trusted-replace-argument', propChain, argpos, argraw);
const logPrefix = safe.makeLogPrefix('trusted-replace-argument', propChain, argposRaw, argraw);
const argpos = parseInt(argposRaw, 10) || 0;
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
const normalValue = validateConstantFn(true, argraw);
const normalValue = validateConstantFn(true, argraw, extraArgs);
const reCondition = extraArgs.condition
? safe.patternToRegex(extraArgs.condition)
: /^/;
const reflector = proxyApplyFn(propChain, function(...args) {
if ( argposRaw === '' ) {
safe.uboLog(logPrefix, `Arguments:\n${args.join('\n')}`);
return reflector(...args);
}
const arglist = args[args.length-1];
if ( Array.isArray(arglist) === false ) { return reflector(...args); }
const argBefore = arglist[argpos];
if ( reCondition.test(argBefore) === false ) { return reflector(...args); }
if ( safe.RegExp_test.call(reCondition, argBefore) === false ) {
return reflector(...args);
}
arglist[argpos] = normalValue;
safe.adnlog(logPrefix, `Replaced argument:\nBefore: ${JSON.stringify(argBefore)}\nAfter: ${normalValue}`);
return reflector(...args);
Expand Down Expand Up @@ -4824,4 +4862,89 @@ function trustedReplaceOutboundText(
});
}

/*******************************************************************************
*
* Reference:
* https://github.com/AdguardTeam/Scriptlets/blob/5a92d79489/wiki/about-trusted-scriptlets.md#trusted-suppress-native-method
*
* This is a first version with current limitations:
* - Does not support matching arguments which are object or array
* - Does not support `stack` parameter
*
* If `signatureStr` parameter is not declared, the scriptlet will log all calls
* to `methodPath` along with the arguments passed and will not prevent the
* trapped method.
*
* */

builtinScriptlets.push({
name: 'trusted-suppress-native-method.js',
requiresTrust: true,
fn: trustedSuppressNativeMethod,
dependencies: [
'proxy-apply.fn',
'safe-self.fn',
],
});
function trustedSuppressNativeMethod(
methodPath = '',
signature = '',
how = '',
stack = ''
) {
if ( methodPath === '' ) { return; }
if ( stack !== '' ) { return; }
const safe = safeSelf();
const logPrefix = safe.makeLogPrefix('trusted-suppress-native-method', methodPath, signature, how);
const signatureArgs = signature.split(/\s*\|\s*/).map(v => {
if ( /^".*"$/.test(v) ) {
return { type: 'pattern', re: safe.patternToRegex(v.slice(1, -1)) };
}
if ( v === 'false' ) {
return { type: 'exact', value: false };
}
if ( v === 'true' ) {
return { type: 'exact', value: true };
}
if ( v === 'null' ) {
return { type: 'exact', value: null };
}
if ( v === 'undefined' ) {
return { type: 'exact', value: undefined };
}
});
const reflector = proxyApplyFn(methodPath, function(...args) {
if ( signature === '' ) {
safe.uboLog(logPrefix, `Arguments:\n${args.join('\n')}`);
return reflector(...args);
}
const arglist = args[args.length-1];
if ( Array.isArray(arglist) === false ) {
return reflector(...args);
}
if ( arglist.length < signatureArgs.length ) {
return reflector(...args);
}
for ( let i = 0; i < signatureArgs.length; i++ ) {
const signatureArg = signatureArgs[i];
if ( signatureArg === undefined ) { continue; }
const targetArg = arglist[i];
if ( signatureArg.type === 'exact' ) {
if ( targetArg !== signatureArg.value ) {
return reflector(...args);
}
}
if ( signatureArg.type === 'pattern' ) {
if ( safe.RegExp_test.call(signatureArg.re, targetArg) === false ) {
return reflector(...args);
}
}
}
safe.uboLog(logPrefix, `Suppressed:\n${args.join('\n')}`);
if ( how === 'abort' ) {
throw new ReferenceError();
}
});
}

/******************************************************************************/
Loading

0 comments on commit 05ec6d1

Please sign in to comment.