Skip to content

Commit

Permalink
Add tests of existing broken parsePatch behaviour, to fix before next…
Browse files Browse the repository at this point in the history
… release (#525)
  • Loading branch information
ExplodingCabbage authored Jun 14, 2024
1 parent 9bb34dc commit 0126325
Showing 1 changed file with 98 additions and 0 deletions.
98 changes: 98 additions & 0 deletions test/patch/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,5 +425,103 @@ Index: test2
}
]);
});

it('should tolerate patches with extra trailing newlines after hunks', () => {
// Regression test for https://github.com/kpdecker/jsdiff/issues/524
// Not only are these considered valid by GNU patch, but jsdiff's own formatPatch method
// emits patches like this, which jsdiff used to then be unable to parse!
const patchStr = `--- foo 2024-06-14 22:16:31.444276792 +0100
+++ bar 2024-06-14 22:17:14.910611219 +0100
@@ -1,7 +1,7 @@
first
second
third
-fourth
-fifth
+vierte
+fünfte
sixth
seventh
`;
expect(parsePatch(patchStr)).to.eql([{
oldFileName: 'foo',
oldHeader: '2024-06-14 22:16:31.444276792 +0100',
newFileName: 'bar',
newHeader: '2024-06-14 22:17:14.910611219 +0100',
hunks: [
{
oldStart: 1,
oldLines: 7,
newStart: 1,
newLines: 7,
lines: [
' first',
' second',
' third',
'-fourth',
'-fifth',
'+vierte',
'+fünfte',
' sixth',
' seventh'
]
}
]
}]);
});

it("shouldn't be caught out by removal/addition of lines starting with -- or ++", () => {
// The patch below is a valid patch generated by diffing this file, foo:

// first
// second
// third
// -- bla
// fifth
// sixth

// against this file, bar:

// first
// second
// third
// ++ bla
// fifth
// sixth
// seventh

// with the command `diff -u0 foo bar`. (All lines in `foo` and `bar` have no leading
// whitespace and a trailing LF.)

// This is effectively an adversarial example meant to catch out a parser that tries to
// detect the end of a file in a multi-file diff by looking for lines starting with '---',
// '+++', and then '@@'. jsdiff used to do this. However, as this example illustrates, it is
// unsound, since the '---' and '+++' lines might actually just represent the deletion and
// insertion of lines starting with '--' and '++'. The only way to disambiguate these
// interpretations is to heed the line counts in the @@ hunk headers; you *cannot* reliably
// determine where a hunk or file ends in a unified diff patch without heeding those line
// counts.

const patchStr = `--- foo 2024-06-14 21:57:04.341065736 +0100
+++ bar 2024-06-14 22:00:57.988080321 +0100
@@ -4 +4 @@
--- bla
+++ bla
@@ -6,0 +7 @@
+seventh
`;

expect(parsePatch(patchStr)).to.eql([{
oldFileName: 'foo 2024-06-14 21:57:04.341065736 +0100',
oldHeader: '',
newFileName: 'bar 2024-06-14 22:00:57.988080321 +0100',
newHeader: '',
hunks: [
{ oldStart: 4, oldLines: 1, newStart: 4, newLines: 1, lines: ['--- bla', '+++ bla'] },
{ oldStart: 7, oldLines: 0, newStart: 7, newLines: 1, lines: ['+seventh'] }
]
}]);
});
});
});

0 comments on commit 0126325

Please sign in to comment.