Lazy regex throws 'Uncaught InternalError: too much recursion' if not matched
Categories
(Core :: JavaScript Engine, defect, P3)
Tracking
()
People
(Reporter: ratchkov, Unassigned)
References
Details
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0
Steps to reproduce:
buf = Array(165537).join('x')
/.?module/s.exec(buf+'module') // works fine
/.?module/s.exec(buf) // Throws 'Uncaught InternalError: too much recursion'
Actual results:
The above code throws 'Uncaught InternalError: too much recursion'
Expected results:
Should return null.
The original submission ate some of the chars in the regex. Second attempt:
buf = Array(165537).join('x')
/.?module/s.exec(buf+'module') // works fine
/.?module/s.exec(buf) // Throws 'Uncaught InternalError: too much recursion'
Submission didn't work again. There is supposed to be a star '*' between the . and the ? in the regex.
Comment 3•5 years ago
|
||
You need to enclose code block with triple backquote.
https://guides.github.com/features/mastering-markdown/
buf = Array(165537).join('x')
/.*?module/s.exec(buf+'module') // works fine
/.*?module/s.exec(buf) // Throws 'Uncaught InternalError: too much recursion'
Updated•5 years ago
|
Comment 4•5 years ago
|
||
On nightly 82.0a1 (2020-09-15) (64-bit), this behaves differently, that Error: undefined
is thrown.
from the following change:
https://hg.mozilla.org/integration/autoland/pushloghtml?fromchange=1fcabd8b2c9ec2ba55ce65124dc694758753efc3&tochange=6ac9edc64fe58b7de451c9a1bd82b673d66ca54d
so there seems to be another error around there.
also, strangely, the issue doesn't happen on JS shell.
Updated•5 years ago
|
Comment 5•5 years ago
|
||
looks like it's hitting this case:
https://searchfox.org/mozilla-central/rev/30e70f2fe80c97bfbfcd975e68538cefd7f58b2a/js/src/vm/RegExpObject.cpp#754
that explains why this doesn't happen on JS shell
Comment 6•5 years ago
|
||
basically, similar issue as bug 1391654.
once non-backtracking execution gets implemented, the pattern will run quickly.
Comment 7•5 years ago
|
||
I pasted this code into the Chrome devtools, and this regexp makes Chrome unhappy too. With this exact number of characters, Chrome manages to get to the end (after 30 seconds or so) and return null
. Then I tried it with buf.repeat(32)
and it has gone unresponsive. Quitting Chrome doesn't even work.
Firefox uses V8's Regexp engine, so this requires work on the V8 side.
Comment 8•5 years ago
|
||
I've just filed bug #1677315 today. Is that one a dupe of this one?
Comment 9•5 years ago
|
||
yes. but you can workaround this issue by fixing your pattern to correctly match what you want.
Comment 10•5 years ago
|
||
Hi, I've just run into the same issue with the following regular expression:
/^([a-z0-9]+-?)*[a-z0-9]+$/.test('one-two-three-four-five-six-seven-eight-nine-')
This fails with Uncaught InternalError: too much recursion
on the console of Firefox Developer Edition (85.0b7 (64-bit) – Apple M1, MacOS 11.1)
Comment 11•5 years ago
|
||
Your pattern results in exponential backtracking. See the "catastrophic backtracking" section of this V8 blog post for an explanation.
The problem is ([a-z0-9]+-?)*
, which has an exponential number of potential matches. If you remove the ?
in ([a-z0-9]+-?)*
, your regexp will match the same inputs but execute much faster.
Comment 12•5 years ago
|
||
Thank you Iain, that helped a lot!
Updated•9 months ago
|
Description
•