Fix the second denial-of-service vulnerability in parsePatch#649
Merged
ExplodingCabbage merged 2 commits intomasterfrom Jan 7, 2026
Merged
Fix the second denial-of-service vulnerability in parsePatch#649ExplodingCabbage merged 2 commits intomasterfrom
ExplodingCabbage merged 2 commits intomasterfrom
Conversation
This was referenced Jan 15, 2026
Merged
1 task
1 task
1 task
This was referenced Jan 15, 2026
This was referenced Jan 16, 2026
This was referenced Feb 3, 2026
7 tasks
This was referenced Feb 4, 2026
Merged
Merged
This was referenced Feb 5, 2026
Open
1 task
This was referenced Feb 18, 2026
This was referenced Feb 27, 2026
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

This fixes the second, uh, ReDOS reported in #644. Though there's worse here than just a ReDOS!
First, I will explain the ReDOS. The regex
/^(---|\+\+\+)\s+(.*)\r?$/takes n^2 time to execute against a string that ends with n spaces followed by a \u2028 and a non-space character, for similar reasons to those explained in #647. The change here fixes that.But it was worse than that! The bigger problem is that the code around this regex used to go into an infinite loop (consuming more and more memory until an OOM error occurs) when called with even small adversarial inputs. e.g.:
This happens because the line
--- x\u2028xtriggers the break on this line...... but does NOT match the regex at the start of
parseFileHeader:(The reason it doesn't match is again down to the nasty trap that the regex wildcard
.does not match character\u2028.)The logic for chomping through lines of the patch relies on those two regexes being consistent with each other; since they are not,
parseIndexfinishes execution without actually having chomped the line, and gets called again by the mainwhileloop inparsePatch, resulting in the linelist.push(index);near the start ofparseIndexbeing called again, resulting inlistgrowing larger on each call until an OOM eventually occurs.Oops!
This PR fixes it.