Skip to content

Commit 1bc0562

Browse files
committed
fix(parser) Fix freezing issue with illegal 0 width matches (highlightjs#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 82ae7ce commit 1bc0562

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

CHANGES.md

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

8-
98
Parser Engine Changes:
109

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

1312

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

src/highlight.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,23 @@ const HLJS = function(hljs) {
348348
return processed;
349349
}
350350

351+
// edge case for when illegal matches $ (end of line) which is technically
352+
// a 0 width match but not a begin/end match so it's not caught by the
353+
// first handler (when ignoreIllegals is true)
354+
if (match.type === "illegal" && lexeme === "") {
355+
// advance so we aren't stuck in an infinite loop
356+
return 1;
357+
}
358+
359+
// infinite loops are BAD, this is a last ditch catch all. if we have a
360+
// decent number of iterations yet our index (cursor position in our
361+
// parsing) still 3x behind our index then something is very wrong
362+
// so we bail
363+
if (iterations > 100000 && iterations > match.index * 3) {
364+
const err = new Error('potential infinite loop, way more iterations than matches');
365+
throw err;
366+
}
367+
351368
/*
352369
Why might be find ourselves here? Only one occasion now. An end match that was
353370
triggered but could not be completed. When might this happen? When an `endSameasBegin`
@@ -378,13 +395,17 @@ const HLJS = function(hljs) {
378395
processContinuations();
379396
var mode_buffer = '';
380397
var relevance = 0;
381-
var match, processedCount, index = 0;
398+
var match;
399+
var processedCount;
400+
var index = 0;
401+
var iterations = 0;
402+
var continueScanAtSamePosition = false;
382403

383404
try {
384-
var continueScanAtSamePosition = false;
385405
top.matcher.considerAll();
386406

387-
while (true) {
407+
for (;;) {
408+
iterations++;
388409
if (continueScanAtSamePosition) {
389410
continueScanAtSamePosition = false;
390411
// only regexes not matched previously will now be

0 commit comments

Comments
 (0)