summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhackademix2019-05-28 00:48:00 +0200
committerhackademix2019-05-28 01:35:44 +0200
commit37d148e3af8f33f9a8b89ebc392b869c30dafb54 (patch)
tree14fc40b04e29e45fac42cb309c22a880f479063e
parentc2f0ce0dfc8fcb514b620c75415601c78eb8c669 (diff)
downloadnoscript-37d148e3af8f33f9a8b89ebc392b869c30dafb54.tar.gz
noscript-37d148e3af8f33f9a8b89ebc392b869c30dafb54.tar.xz
noscript-37d148e3af8f33f9a8b89ebc392b869c30dafb54.zip
Fixed JSON parsing preamble regression.
-rw-r--r--src/lib/Timing.js39
-rw-r--r--src/xss/InjectionChecker.js3
2 files changed, 41 insertions, 1 deletions
diff --git a/src/lib/Timing.js b/src/lib/Timing.js
new file mode 100644
index 0000000..5d09e3a
--- /dev/null
+++ b/src/lib/Timing.js
@@ -0,0 +1,39 @@
+class Timing {
+
+ constructor(workSlot = 4, longTime = 20000, pauseTime = 20) {
+ this.workSlot = workSlot;
+ this.longTime = longTime;
+ this.pauseTime = pauseTime;
+ this.interrupted = false;
+ this.fatalTimeout = false;
+ this.reset();
+ }
+
+ static sleep(ms) {
+ return new Promise(resolve => setTimeout(resolve, ms));
+ }
+
+ async pause() {
+ if (this.interrupted) throw new TimingException("Interrupted");
+ let now = Date.now();
+ this.elapsed = now - this.timeOrigin;
+ if (now - this.lastPause > this.workSlot) {
+ this.tooLong = this.elapsed >= this.longTime;
+ if (this.tooLong && this.fatalTimeout) {
+ throw new TimingException(`Exceeded ${this.longTime}ms timeout`);
+ }
+ await Timing.sleep(this.pauseTime);
+ this.lastPause = Date.now();
+ return true;
+ }
+ return false;
+ }
+
+ reset() {
+ this.elapsed = 0;
+ this.timeOrigin = this.lastPause = Date.now();
+ this.tooLong = false;
+ }
+}
+
+class TimingException extends Error {};
diff --git a/src/xss/InjectionChecker.js b/src/xss/InjectionChecker.js
index d750232..ae5fea0 100644
--- a/src/xss/InjectionChecker.js
+++ b/src/xss/InjectionChecker.js
@@ -172,7 +172,8 @@ XSS.InjectionChecker = (async () => {
const toStringRx = /^function\s*toString\(\)\s*{\s*\[native code\]\s*\}$/;
// optimistic case first, one big JSON block
- let m = s.match(/{[^]+}|\[\s*{[^]+}\s*\]/);
+ s = s.replace(/[^{"]+=/, "")
+ let m = s.match(/{[^]+}|\[[^]*{[^]*}[^]*\]/);
if (!m) return s;
// semicolon-separated JSON chunks, like on syndication.twitter.com