@@ -61,6 +61,7 @@ func (r *MultiFileDiffReader) ReadFile() (*FileDiff, error) {
61
61
if e .Err == ErrNoFileHeader || e .Err == ErrExtendedHeadersEOF {
62
62
return nil , io .EOF
63
63
}
64
+ return nil , err
64
65
65
66
case OverflowError :
66
67
r .nextFileFirstLine = []byte (e )
@@ -513,9 +514,22 @@ func (r *HunksReader) ReadHunk() (*Hunk, error) {
513
514
r .hunk .Section = section
514
515
} else {
515
516
// Read hunk body line.
517
+
518
+ // If the line starts with `---` and the next one with `+++` we're
519
+ // looking at a non-extended file header and need to abort.
520
+ if bytes .HasPrefix (line , []byte ("---" )) {
521
+ ok , err := peekPrefix (r .reader , "+++" )
522
+ if err != nil {
523
+ return r .hunk , err
524
+ }
525
+ if ok {
526
+ return r .hunk , & ParseError {r .line , r .offset , & ErrBadHunkLine {Line : line }}
527
+ }
528
+ }
529
+
530
+ // If the line starts with the hunk prefix, this hunk is complete.
516
531
if bytes .HasPrefix (line , hunkPrefix ) {
517
- // Saw start of new hunk, so this hunk is
518
- // complete. But we've already read in the next hunk's
532
+ // But we've already read in the next hunk's
519
533
// header, so we need to be sure that the next call to
520
534
// ReadHunk starts with that header.
521
535
r .nextHunkHeaderLine = line
@@ -527,7 +541,7 @@ func (r *HunksReader) ReadHunk() (*Hunk, error) {
527
541
return r .hunk , nil
528
542
}
529
543
530
- if len (line ) >= 1 && ( ! linePrefix (line [0 ]) || bytes . HasPrefix ( line , [] byte ( "--- " )) ) {
544
+ if len (line ) >= 1 && ! linePrefix (line [0 ]) {
531
545
// Bad hunk header line. If we're reading a multi-file
532
546
// diff, this may be the end of the current
533
547
// file. Return a "rich" error that lets our caller
@@ -579,6 +593,19 @@ func linePrefix(c byte) bool {
579
593
return false
580
594
}
581
595
596
+ // peekPrefix peeks into the given reader to check whether the next
597
+ // bytes match the given prefix.
598
+ func peekPrefix (reader * bufio.Reader , prefix string ) (bool , error ) {
599
+ next , err := reader .Peek (len (prefix ))
600
+ if err != nil {
601
+ if err == io .EOF {
602
+ return false , nil
603
+ }
604
+ return false , err
605
+ }
606
+ return bytes .HasPrefix (next , []byte (prefix )), nil
607
+ }
608
+
582
609
// normalizeHeader takes a header of the form:
583
610
// "@@ -linestart[,chunksize] +linestart[,chunksize] @@ section"
584
611
// and returns two strings, with the first in the form:
0 commit comments