Skip to content

Commit 0126325

Browse files
Add tests of existing broken parsePatch behaviour, to fix before next release (kpdecker#525)
1 parent 9bb34dc commit 0126325

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

test/patch/parse.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,5 +425,103 @@ Index: test2
425425
}
426426
]);
427427
});
428+
429+
it('should tolerate patches with extra trailing newlines after hunks', () => {
430+
// Regression test for https://github.com/kpdecker/jsdiff/issues/524
431+
// Not only are these considered valid by GNU patch, but jsdiff's own formatPatch method
432+
// emits patches like this, which jsdiff used to then be unable to parse!
433+
const patchStr = `--- foo 2024-06-14 22:16:31.444276792 +0100
434+
+++ bar 2024-06-14 22:17:14.910611219 +0100
435+
@@ -1,7 +1,7 @@
436+
first
437+
second
438+
third
439+
-fourth
440+
-fifth
441+
+vierte
442+
+fünfte
443+
sixth
444+
seventh
445+
446+
`;
447+
expect(parsePatch(patchStr)).to.eql([{
448+
oldFileName: 'foo',
449+
oldHeader: '2024-06-14 22:16:31.444276792 +0100',
450+
newFileName: 'bar',
451+
newHeader: '2024-06-14 22:17:14.910611219 +0100',
452+
hunks: [
453+
{
454+
oldStart: 1,
455+
oldLines: 7,
456+
newStart: 1,
457+
newLines: 7,
458+
lines: [
459+
' first',
460+
' second',
461+
' third',
462+
'-fourth',
463+
'-fifth',
464+
'+vierte',
465+
'+fünfte',
466+
' sixth',
467+
' seventh'
468+
]
469+
}
470+
]
471+
}]);
472+
});
473+
474+
it("shouldn't be caught out by removal/addition of lines starting with -- or ++", () => {
475+
// The patch below is a valid patch generated by diffing this file, foo:
476+
477+
// first
478+
// second
479+
// third
480+
// -- bla
481+
// fifth
482+
// sixth
483+
484+
// against this file, bar:
485+
486+
// first
487+
// second
488+
// third
489+
// ++ bla
490+
// fifth
491+
// sixth
492+
// seventh
493+
494+
// with the command `diff -u0 foo bar`. (All lines in `foo` and `bar` have no leading
495+
// whitespace and a trailing LF.)
496+
497+
// This is effectively an adversarial example meant to catch out a parser that tries to
498+
// detect the end of a file in a multi-file diff by looking for lines starting with '---',
499+
// '+++', and then '@@'. jsdiff used to do this. However, as this example illustrates, it is
500+
// unsound, since the '---' and '+++' lines might actually just represent the deletion and
501+
// insertion of lines starting with '--' and '++'. The only way to disambiguate these
502+
// interpretations is to heed the line counts in the @@ hunk headers; you *cannot* reliably
503+
// determine where a hunk or file ends in a unified diff patch without heeding those line
504+
// counts.
505+
506+
const patchStr = `--- foo 2024-06-14 21:57:04.341065736 +0100
507+
+++ bar 2024-06-14 22:00:57.988080321 +0100
508+
@@ -4 +4 @@
509+
--- bla
510+
+++ bla
511+
@@ -6,0 +7 @@
512+
+seventh
513+
`;
514+
515+
expect(parsePatch(patchStr)).to.eql([{
516+
oldFileName: 'foo 2024-06-14 21:57:04.341065736 +0100',
517+
oldHeader: '',
518+
newFileName: 'bar 2024-06-14 22:00:57.988080321 +0100',
519+
newHeader: '',
520+
hunks: [
521+
{ oldStart: 4, oldLines: 1, newStart: 4, newLines: 1, lines: ['--- bla', '+++ bla'] },
522+
{ oldStart: 7, oldLines: 0, newStart: 7, newLines: 1, lines: ['+seventh'] }
523+
]
524+
}]);
525+
});
428526
});
429527
});

0 commit comments

Comments
 (0)