From de41c1bf533d7a58400ea91f8361620912375bb1 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Sat, 18 May 2019 10:31:04 -0400 Subject: [PATCH] Fix parsing of recursive `!#if`-`!#endif directives Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/270 --- src/js/storage.js | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/js/storage.js b/src/js/storage.js index 4a89f0b0b..aaeef420f 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -923,36 +923,46 @@ µBlock.processDirectives = function(content) { const reIf = /^!#(if|endif)\b([^\n]*)/gm; + const stack = []; + const shouldDiscard = ( ) => stack.some(v => v); const parts = []; - let beg = 0, depth = 0, discard = false; + let beg = 0, discard = false; + while ( beg < content.length ) { const match = reIf.exec(content); if ( match === null ) { break; } - if ( match[1] === 'if' ) { + + switch ( match[1] ) { + case 'if': let expr = match[2].trim(); - const target = expr.startsWith('!'); + const target = expr.charCodeAt(0) === 0x21 /* '!' */; if ( target ) { expr = expr.slice(1); } const token = this.processDirectives.tokens.get(expr); - if ( - depth === 0 && - discard === false && + const startDiscard = 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)); discard = true; } - depth += 1; - continue; - } - depth -= 1; - if ( depth < 0 ) { break; } - if ( depth === 0 && discard ) { - beg = match.index + match[0].length + 1; - discard = false; + stack.push(startDiscard); + break; + + case 'endif': + stack.pop(); + const stopDiscard = shouldDiscard() === false; + if ( discard && stopDiscard ) { + 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)); content = parts.join('\n'); }