Skip to content

Commit acbbac8

Browse files
authored
fix(parser) Fix freezing issue with illegal 0 width matches (#2524)
* fix[parser] add edge case handle for illegal 0 width matches * add last ditch catch all that tries to detect other uncaught freezes
1 parent 8f5290e commit acbbac8

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

CHANGES.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,9 @@ Brower build:
3737
- [Issue](https://github.com/highlightjs/highlight.js/issues/2505) (bug) Fix: Version 10 fails to load as CommonJS module. (#2511) [Josh Goebel][]
3838
- [Issue](https://github.com/highlightjs/highlight.js/issues/2505) (removal) AMD module loading support has been removed. (#2511) [Josh Goebel][]
3939

40-
4140
Parser Engine Changes:
4241

43-
- ...
42+
- [Issue](https://github.com/highlightjs/highlight.js/issues/2522) fix(parser) Fix freez issue with illegal 0 width matches (#2524) [Josh Goebel][]
4443

4544

4645
[Josh Goebel]: https://github.com/yyyc514

src/highlight.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,23 @@ const HLJS = function(hljs) {
365365
}
366366
}
367367

368+
// edge case for when illegal matches $ (end of line) which is technically
369+
// a 0 width match but not a begin/end match so it's not caught by the
370+
// first handler (when ignoreIllegals is true)
371+
if (match.type === "illegal" && lexeme === "") {
372+
// advance so we aren't stuck in an infinite loop
373+
return 1;
374+
}
375+
376+
// infinite loops are BAD, this is a last ditch catch all. if we have a
377+
// decent number of iterations yet our index (cursor position in our
378+
// parsing) still 3x behind our index then something is very wrong
379+
// so we bail
380+
if (iterations > 100000 && iterations > match.index * 3) {
381+
const err = new Error('potential infinite loop, way more iterations than matches');
382+
throw err;
383+
}
384+
368385
/*
369386
Why might be find ourselves here? Only one occasion now. An end match that was
370387
triggered but could not be completed. When might this happen? When an `endSameasBegin`
@@ -396,12 +413,14 @@ const HLJS = function(hljs) {
396413
var mode_buffer = '';
397414
var relevance = 0;
398415
var index = 0;
416+
var iterations = 0;
399417
var continueScanAtSamePosition = false;
400418

401419
try {
402420
top.matcher.considerAll();
403421

404422
for (;;) {
423+
iterations++;
405424
if (continueScanAtSamePosition) {
406425
continueScanAtSamePosition = false;
407426
// only regexes not matched previously will now be

0 commit comments

Comments
 (0)