diff --git a/src/js/static-filtering-parser.js b/src/js/static-filtering-parser.js index e2854aea8..764c6b38f 100644 --- a/src/js/static-filtering-parser.js +++ b/src/js/static-filtering-parser.js @@ -866,6 +866,7 @@ const Parser = class { return i; } + // Important: the from-to indices are inclusive. strFromSlices(from, to) { return this.raw.slice( this.slices[from+1], @@ -2396,10 +2397,17 @@ const NetOptionsIterator = class { // `queryprune=`: only for network requests. { const i = this.tokenPos[OPTTokenQueryprune]; - if ( i !== -1 && hasBits(allBits, OPTNonNetworkType) ) { - optSlices[i] = OPTTokenInvalid; - if ( this.interactive ) { - this.parser.errorSlices(optSlices[i+1], optSlices[i+5]); + if ( i !== -1 ) { + if ( hasBits(allBits, OPTNonNetworkType) ) { + optSlices[i] = OPTTokenInvalid; + if ( this.interactive ) { + this.parser.errorSlices(optSlices[i+1], optSlices[i+5]); + } + } else if ( this.validateQueryPruneArg(i) === false ) { + optSlices[i] = OPTTokenInvalid; + if ( this.interactive ) { + this.parser.errorSlices(optSlices[i+4], optSlices[i+5]); + } } } } @@ -2442,6 +2450,20 @@ const NetOptionsIterator = class { this.readPtr = i + 6; return this; } + validateQueryPruneArg(i) { + let val = this.parser.strFromSlices( + this.optSlices[i+4], + this.optSlices[i+5] - 3 + ); + if ( val.startsWith('|') ) { val = `^${val.slice(1)}`; } + if ( val.endsWith('|') ) { val = `${val.slice(0,-1)}$`; } + try { + void new RegExp(val); + } catch(ex) { + return false; + } + return true; + } }; /******************************************************************************/