VYPR
Low severityOSV Advisory· Published Jan 22, 2026· Updated Feb 3, 2026

jsdiff has a Denial of Service vulnerability in parsePatch and applyPatch

CVE-2026-24001

Description

jsdiff is a JavaScript text differencing implementation. Prior to versions 8.0.3, 5.2.2, 4.0.4, and 3.5.1, attempting to parse a patch whose filename headers contain the line break characters \r, \u2028, or \u2029 can cause the parsePatch method to enter an infinite loop. It then consumes memory without limit until the process crashes due to running out of memory. Applications are therefore likely to be vulnerable to a denial-of-service attack if they call parsePatch with a user-provided patch as input. A large payload is not needed to trigger the vulnerability, so size limits on user input do not provide any protection. Furthermore, some applications may be vulnerable even when calling parsePatch on a patch generated by the application itself if the user is nonetheless able to control the filename headers (e.g. by directly providing the filenames of the files to be diffed). The applyPatch method is similarly affected if (and only if) called with a string representation of a patch as an argument, since under the hood it parses that string using parsePatch. Other methods of the library are unaffected. Finally, a second and lesser interdependent bug - a ReDOS - also exhibits when those same line break characters are present in a patch's *patch* header (also known as its "leading garbage"). A maliciously-crafted patch header of length *n* can take parsePatch O(*n*³) time to parse. Versions 8.0.3, 5.2.2, 4.0.4, and 3.5.1 contain a fix. As a workaround, do not attempt to parse patches that contain any of these characters: \r, \u2028, or \u2029.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
diffnpm
>= 6.0.0, < 8.0.38.0.3
diffnpm
>= 5.0.0, < 5.2.25.2.2
diffnpm
>= 4.0.0, < 4.0.44.0.4
diffnpm
< 3.5.13.5.1

Affected products

1

Patches

1
15a158523074

Fix the second denial-of-service vulnerability in parsePatch (#649)

https://github.com/kpdecker/jsdiffMark AmeryJan 7, 2026via ghsa
2 files changed · +7 6
  • release-notes.md+1 1 modified
    @@ -5,7 +5,7 @@
     - [#631](https://github.com/kpdecker/jsdiff/pull/631) - **fix support for using an `Intl.Segmenter` with `diffWords`**. This has been almost completely broken since the feature was added in v6.0.0, since it would outright crash on any text that featured two consecutive newlines between a pair of words (a very common case).
     - [#635](https://github.com/kpdecker/jsdiff/pull/635) - **small tweaks to tokenization behaviour of `diffWords`** when used *without* an `Intl.Segmenter`. Specifically, the soft hyphen (U+00AD) is no longer considered to be a word break, and the multiplication and division signs (`×` and `÷`) are now treated as punctuation instead of as letters / word characters.
     - [#641](https://github.com/kpdecker/jsdiff/pull/641) - **the format of file headers in `createPatch` etc. patches can now be customised somewhat**. It now takes a `headerOptions` option that can be used to disable the file headers entirely, or omit the `Index:` line and/or the underline. In particular, this was motivated by a request to make jsdiff patches compatible with react-diff-view, which they now are if produced with `headerOptions: FILE_HEADERS_ONLY`.
    -- [#647](https://github.com/kpdecker/jsdiff/pull/647) and [#TODO] - **fix ReDOS vulnerabilities in `parsePatch`**. Previously, adversarially-crafted patch headers could take cubic time to parse; now, `parsePatch` should reliably take linear time. (Handling of headers that include the line break characters `\r`, `\u2028`, or `\u2029` in non-trailing positions is also now more reasonable as side effect of the fix.)
    +- [#647](https://github.com/kpdecker/jsdiff/pull/647) and [#649](https://github.com/kpdecker/jsdiff/pull/649) - **fix denial-of-service vulnerabilities in `parsePatch` whereby adversarial input could cause a memory-leaking infinite loop, typically crashing the calling process**. Also fixed ReDOS vulnerabilities whereby adversarially-crafted patch headers could take cubic time to parse. Now, `parsePatch` should reliably take linear time. (Handling of headers that include the line break characters `\r`, `\u2028`, or `\u2029` in non-trailing positions is also now more reasonable as side effect of the fix.)
     
     ## 8.0.2
     
    
  • src/patch/parse.ts+6 5 modified
    @@ -74,15 +74,16 @@ export function parsePatch(uniDiff: string): StructuredPatch[] {
       // Parses the --- and +++ headers, if none are found, no lines
       // are consumed.
       function parseFileHeader(index: Partial<StructuredPatch>) {
    -    const fileHeader = (/^(---|\+\+\+)\s+(.*)\r?$/).exec(diffstr[i]);
    -    if (fileHeader) {
    -      const data = fileHeader[2].split('\t', 2),
    +    const fileHeaderMatch = (/^(---|\+\+\+)\s+/).exec(diffstr[i]);
    +    if (fileHeaderMatch) {
    +      const prefix = fileHeaderMatch[1],
    +            data = diffstr[i].substring(3).trim().split('\t', 2),
                 header = (data[1] || '').trim();
           let fileName = data[0].replace(/\\\\/g, '\\');
    -      if ((/^".*"$/).test(fileName)) {
    +      if (fileName.startsWith('"') && fileName.endsWith('"')) {
             fileName = fileName.substr(1, fileName.length - 2);
           }
    -      if (fileHeader[1] === '---') {
    +      if (prefix === '---') {
             index.oldFileName = fileName;
             index.oldHeader = header;
           } else {
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.