Catastrophic backtracking bug
eight04 opened this issue · comments
eight commented
This runs forever when:
- There are many ejs components.
- The last item
<\/\1>
doesn't match.
This happens naturally when there is another tag stick with ejs component. Here is an example:
<p><div class="ejs-component" data-ejs-component="Fumen" data-ejs-props="{blabla}" data-ejs-options="{blabla}"></div>
... and more ejs components ...
- The first capturing group matches
p><div
. - The last item
</p><div>
can't match</div>
in the file. - All
[^]*?
expand down to the entire file. - Still doesn't match. So it backtracks and test the previous
[^]*?
down to the entire file...
I think it will be better to write it as:
/<([^<]+) class="ejs-component[^"]*" data-ejs-component="([A-Za-z]+)" data-ejs-props="({[^"]*})" data-ejs-options="({[^"]*})"><\/\1>/gim
Ensure that:
- The last item is a valid tag.
- Even if the last item doesn't match, it doesn't expand down to the entire file.
After the fix, the build time reduces from 5 minutes to 9 seconds.
eight commented
After changing the regex, I found that some tests failed:
elderjs/src/partialHydration/__tests__/mountComponentsInHtml.spec.ts
Lines 36 to 41 in bf528f1
It this a valid use case? While debugging the server, I saw data like
"
were encoded into "e;
to produce valid HTML. But the test file doesn't seem to quote them. It is not valid svelte syntax either.