How do I add a timeout to Regex call in JavaScript (runtime = Browser) so it doesn't catastrophically backtrack? I only found solution for NodeJS and other languages but not for JavaScript. Does anyone know a good solution?
Asked
Active
Viewed 328 times
2
-
1@WiktorStribiżew that's again nodejs – mehulmpt Jun 07 '18 at 20:13
-
You mean in a browser? – Jim W Jun 07 '18 at 20:13
-
Yes browser @JimW. I updated the question – mehulmpt Jun 07 '18 at 20:14
-
1Have you considered that regex may be the wrong tool for the problem you're attempting to solve? – zzzzBov Jun 07 '18 at 20:15
-
1The only way you can timeout a script is if it's threaded, and the only way to achieve that in browsers is with a web worker, which seems a bit overkill for this particular request. – Patrick Roberts Jun 07 '18 at 20:17
-
you have to check the elapsed time with every invocation of the RX, or maybe every tenth invocation, and abort if it's taking too long. In short, you can't check the runtime outside the main tight loop. – dandavis Jun 07 '18 at 20:18
-
1checking [this](https://www.regular-expressions.info/catastrophic.html) may help you – Elyas Esna Jun 07 '18 at 20:21
1 Answers
4
You can spin up a web worker in the browser, and terminate it at any point. The following example demonstrates terminating a worker before it finished running everything it had:
(I am creating a worker from a blob for demonstration purposes. Also, this was done in Chrome, and may need some browser specific changes to work in other browsers such as shown in this question)
const workerScript = `
setTimeout(function () {
postMessage('You will see this');
}, 1000);
setTimeout(function () {
postMessage('You will NOT see this');
}, 5000);
`;
const blob = new Blob([workerScript], {type: 'application/javascript'});
const worker = new Worker(URL.createObjectURL(blob));
worker.onmessage = function(e) {
console.log(e.data);
};
// You will only see ONE log from the worker
// if you change the timeout (ex. 6000), you will see two
setTimeout(() => {
worker.terminate();
}, 3000);

KevBot
- 17,900
- 5
- 50
- 68