Fix parsing of recursive !#if-`!#endif directives

Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/270
This commit is contained in:
Raymond Hill 2019-05-18 10:31:04 -04:00
parent ebf92c007f
commit de41c1bf53
No known key found for this signature in database
GPG key ID: 25E1490B761470C2

View file

@ -923,36 +923,46 @@
µBlock.processDirectives = function(content) { µBlock.processDirectives = function(content) {
const reIf = /^!#(if|endif)\b([^\n]*)/gm; const reIf = /^!#(if|endif)\b([^\n]*)/gm;
const stack = [];
const shouldDiscard = ( ) => stack.some(v => v);
const parts = []; const parts = [];
let beg = 0, depth = 0, discard = false; let beg = 0, discard = false;
while ( beg < content.length ) { while ( beg < content.length ) {
const match = reIf.exec(content); const match = reIf.exec(content);
if ( match === null ) { break; } if ( match === null ) { break; }
if ( match[1] === 'if' ) {
switch ( match[1] ) {
case 'if':
let expr = match[2].trim(); let expr = match[2].trim();
const target = expr.startsWith('!'); const target = expr.charCodeAt(0) === 0x21 /* '!' */;
if ( target ) { expr = expr.slice(1); } if ( target ) { expr = expr.slice(1); }
const token = this.processDirectives.tokens.get(expr); const token = this.processDirectives.tokens.get(expr);
if ( const startDiscard =
depth === 0 &&
discard === false &&
token !== undefined && token !== undefined &&
vAPI.webextFlavor.soup.has(token) === target vAPI.webextFlavor.soup.has(token) === target;
) { if ( discard === false && startDiscard ) {
parts.push(content.slice(beg, match.index)); parts.push(content.slice(beg, match.index));
discard = true; discard = true;
} }
depth += 1; stack.push(startDiscard);
continue; break;
}
depth -= 1; case 'endif':
if ( depth < 0 ) { break; } stack.pop();
if ( depth === 0 && discard ) { const stopDiscard = shouldDiscard() === false;
beg = match.index + match[0].length + 1; if ( discard && stopDiscard ) {
discard = false; beg = match.index + match[0].length + 1;
discard = false;
}
break;
default:
break;
} }
} }
if ( depth === 0 && parts.length !== 0 ) {
if ( stack.length === 0 && parts.length !== 0 ) {
parts.push(content.slice(beg)); parts.push(content.slice(beg));
content = parts.join('\n'); content = parts.join('\n');
} }