@@ -61,6 +61,7 @@ func (r *MultiFileDiffReader) ReadFile() (*FileDiff, error) {
6161 if e .Err == ErrNoFileHeader || e .Err == ErrExtendedHeadersEOF {
6262 return nil , io .EOF
6363 }
64+ return nil , err
6465
6566 case OverflowError :
6667 r .nextFileFirstLine = []byte (e )
@@ -513,9 +514,22 @@ func (r *HunksReader) ReadHunk() (*Hunk, error) {
513514 r .hunk .Section = section
514515 } else {
515516 // 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.
516531 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
519533 // header, so we need to be sure that the next call to
520534 // ReadHunk starts with that header.
521535 r .nextHunkHeaderLine = line
@@ -527,7 +541,7 @@ func (r *HunksReader) ReadHunk() (*Hunk, error) {
527541 return r .hunk , nil
528542 }
529543
530- if len (line ) >= 1 && ( ! linePrefix (line [0 ]) || bytes . HasPrefix ( line , [] byte ( "--- " )) ) {
544+ if len (line ) >= 1 && ! linePrefix (line [0 ]) {
531545 // Bad hunk header line. If we're reading a multi-file
532546 // diff, this may be the end of the current
533547 // file. Return a "rich" error that lets our caller
@@ -579,6 +593,19 @@ func linePrefix(c byte) bool {
579593 return false
580594}
581595
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+
582609// normalizeHeader takes a header of the form:
583610// "@@ -linestart[,chunksize] +linestart[,chunksize] @@ section"
584611// and returns two strings, with the first in the form:
0 commit comments