uBO will fallback using a JSON string when trying to encode an array
buffer in Chromium version 59 and earlier.
This commit is contained in:
Raymond Hill 2019-03-16 09:00:31 -04:00
parent 7875bb6ebc
commit 008370e4b9
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
4 changed files with 77 additions and 10 deletions

View File

@ -372,11 +372,13 @@ HNTrieContainer.prototype = {
}, },
unserialize: function(selfie, decoder) { unserialize: function(selfie, decoder) {
this.needle = '';
const shouldDecode = typeof selfie === 'string'; const shouldDecode = typeof selfie === 'string';
let byteLength = shouldDecode let byteLength = shouldDecode
? decoder.decodeSize(selfie) ? decoder.decodeSize(selfie)
: selfie.length << 2; : selfie.length << 2;
byteLength = byteLength + HNTRIE_PAGE_SIZE-1 & ~(HNTRIE_PAGE_SIZE-1); byteLength = byteLength + HNTRIE_PAGE_SIZE-1 & ~(HNTRIE_PAGE_SIZE-1);
if ( byteLength === 0 ) { return; }
if ( this.wasmMemory !== null ) { if ( this.wasmMemory !== null ) {
const pageCountBefore = this.buf.length >>> 16; const pageCountBefore = this.buf.length >>> 16;
const pageCountAfter = byteLength >>> 16; const pageCountAfter = byteLength >>> 16;
@ -394,7 +396,6 @@ HNTrieContainer.prototype = {
} else { } else {
this.buf32.set(selfie); this.buf32.set(selfie);
} }
this.needle = '';
}, },
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------

View File

@ -935,17 +935,17 @@
// https://github.com/AdguardTeam/AdguardBrowserExtension/issues/917 // https://github.com/AdguardTeam/AdguardBrowserExtension/issues/917
µBlock.processDirectives = function(content) { µBlock.processDirectives = function(content) {
var reIf = /^!#(if|endif)\b([^\n]*)/gm, const reIf = /^!#(if|endif)\b([^\n]*)/gm;
parts = [], const parts = [];
beg = 0, depth = 0, discard = false; let beg = 0, depth = 0, discard = false;
while ( beg < content.length ) { while ( beg < content.length ) {
var match = reIf.exec(content); const match = reIf.exec(content);
if ( match === null ) { break; } if ( match === null ) { break; }
if ( match[1] === 'if' ) { if ( match[1] === 'if' ) {
var expr = match[2].trim(); let expr = match[2].trim();
var target = expr.startsWith('!'); const target = expr.startsWith('!');
if ( target ) { expr = expr.slice(1); } if ( target ) { expr = expr.slice(1); }
var token = this.processDirectives.tokens.get(expr); const token = this.processDirectives.tokens.get(expr);
if ( if (
depth === 0 && depth === 0 &&
discard === false && discard === false &&
@ -1034,8 +1034,11 @@
'compiled/' + this.pslAssetKey 'compiled/' + this.pslAssetKey
).then(details => ).then(details =>
publicSuffixList.fromSelfie(details.content, µBlock.base128) publicSuffixList.fromSelfie(details.content, µBlock.base128)
).then(valid => { ).catch(reason => {
if ( valid === true ) { return; } console.info(reason);
return false;
}).then(success => {
if ( success ) { return; }
return this.assets.get(this.pslAssetKey, details => { return this.assets.get(this.pslAssetKey, details => {
if ( details.content !== '' ) { if ( details.content !== '' ) {
this.compilePublicSuffixList(details.content); this.compilePublicSuffixList(details.content);

View File

@ -505,9 +505,22 @@
// Could expand the LZ4 codec API to be able to return UTF8-safe string // Could expand the LZ4 codec API to be able to return UTF8-safe string
// representation of a compressed buffer, and thus the code below could be // representation of a compressed buffer, and thus the code below could be
// moved LZ4 codec-side. // moved LZ4 codec-side.
// https://github.com/uBlockOrigin/uBlock-issues/issues/461
// Provide a fallback encoding for Chromium 59 and less by issuing a plain
// JSON string. The fallback can be removed once min supported version is
// above 59.
µBlock.base128 = { µBlock.base128 = {
encode: function(arrbuf, arrlen) { encode: function(arrbuf, arrlen) {
if (
vAPI.webextFlavor.soup.has('chromium') &&
vAPI.webextFlavor.major < 60
) {
return this.encodeJSON(arrbuf);
}
return this.encodeBase128(arrbuf, arrlen);
},
encodeBase128: function(arrbuf, arrlen) {
const inbuf = new Uint8Array(arrbuf, 0, arrlen); const inbuf = new Uint8Array(arrbuf, 0, arrlen);
const inputLength = arrlen; const inputLength = arrlen;
let _7cnt = Math.floor(inputLength / 7); let _7cnt = Math.floor(inputLength / 7);
@ -556,6 +569,9 @@
const textDecoder = new TextDecoder(); const textDecoder = new TextDecoder();
return textDecoder.decode(outbuf); return textDecoder.decode(outbuf);
}, },
encodeJSON: function(arrbuf) {
return JSON.stringify(Array.from(new Uint32Array(arrbuf)));
},
// TODO: // TODO:
// Surprisingly, there does not seem to be any performance gain when // Surprisingly, there does not seem to be any performance gain when
// first converting the input string into a Uint8Array through // first converting the input string into a Uint8Array through
@ -568,6 +584,22 @@
// const inbuf = textEncoder.encode(instr); // const inbuf = textEncoder.encode(instr);
// const inputLength = inbuf.byteLength; // const inputLength = inbuf.byteLength;
decode: function(instr, arrbuf) { decode: function(instr, arrbuf) {
if ( instr.length === 0 ) { return; }
if ( instr.charCodeAt(0) === 0x5B /* '[' */ ) {
const outbuf = this.decodeJSON(instr, arrbuf);
if ( outbuf !== undefined ) {
return outbuf;
}
}
if (
vAPI.webextFlavor.soup.has('chromium') &&
vAPI.webextFlavor.major < 60
) {
throw new Error('Unexpected µBlock.base128 encoding');
}
return this.decodeBase128(instr, arrbuf);
},
decodeBase128: function(instr, arrbuf) {
const inputLength = instr.length; const inputLength = instr.length;
let _8cnt = inputLength >>> 3; let _8cnt = inputLength >>> 3;
let outputLength = _8cnt * 7; let outputLength = _8cnt * 7;
@ -599,7 +631,37 @@
} }
return outbuf; return outbuf;
}, },
decodeJSON: function(instr, arrbuf) {
let buf;
try {
buf = JSON.parse(instr);
} catch (ex) {
}
if ( Array.isArray(buf) === false ) { return; }
const outbuf = arrbuf instanceof ArrayBuffer === false
? new Uint32Array(buf.length << 2)
: new Uint32Array(arrbuf);
outbuf.set(buf);
return new Uint8Array(outbuf.buffer);
},
decodeSize: function(instr) { decodeSize: function(instr) {
if ( instr.length === 0 ) { return 0; }
if ( instr.charCodeAt(0) === 0x5B /* '[' */ ) {
let buf;
try {
buf = JSON.parse(instr);
} catch (ex) {
}
if ( Array.isArray(buf) ) {
return buf.length << 2;
}
}
if (
vAPI.webextFlavor.soup.has('chromium') &&
vAPI.webextFlavor.major < 60
) {
throw new Error('Unexpected µBlock.base128 encoding');
}
const size = (instr.length >>> 3) * 7; const size = (instr.length >>> 3) * 7;
const rem = instr.length & 7; const rem = instr.length & 7;
return rem === 0 ? size : size + rem - 1; return rem === 0 ? size : size + rem - 1;

View File

@ -500,6 +500,7 @@ const fromSelfie = function(selfie, decoder) {
} }
const bufferStr = selfie.slice(pos + 1); const bufferStr = selfie.slice(pos + 1);
byteLength = decoder.decodeSize(bufferStr); byteLength = decoder.decodeSize(bufferStr);
if ( byteLength === 0 ) { return false; }
allocateBuffers(byteLength); allocateBuffers(byteLength);
decoder.decode(bufferStr, pslBuffer8.buffer); decoder.decode(bufferStr, pslBuffer8.buffer);
} else if ( } else if (