Repository: reviewdog/reviewdog
Pull request #967 (2021-06-08 22:43:28)

Fix parsing long lines in diffs
Fixes issue if there is a line longer than 4096 characters in a diff. Currently Reviewdog returns 4096 characters over multiple lines, this changes resolves the issue to return just a single (entire) line correctly.

- [x] Updated Unreleased section in [CHANGELOG](https://github.com/reviewdog/reviewdog/blob/master/CHANGELOG.md) or it's not notable changes.
  - Bugfix only 


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b48204dd..470ca03d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - ...
 
 ### :bug: Fixes
+- [#967](https://github.com/reviewdog/reviewdog/pull/967) Fix parsing long lines in diffs #967
 - ...
 
 ### :rotating_light: Breaking changes
diff --git a/diff/parse.go b/diff/parse.go
index 7df438f9..77f0b338 100644
--- a/diff/parse.go
+++ b/diff/parse.go
@@ -364,16 +364,24 @@ func parseLS(ls string) (l, s int, err error) {
 	return l, s, nil
 }
 
-// readline reads lines from bufio.Reader with size limit. It consumes
-// remaining content even if the line size reaches size limit.
+// readline reads a whole line.
 func readline(r *bufio.Reader) (string, error) {
 	line, isPrefix, err := r.ReadLine()
 	if err != nil {
 		return "", err
 	}
-	// consume all remaining line content
-	for isPrefix {
-		_, isPrefix, _ = r.ReadLine()
+	// append all remaining line content
+	if isPrefix {
+		l := make([]byte, len(line))
+		copy(l, line)
+		for isPrefix {
+			line, isPrefix, err = r.ReadLine()
+			if err != nil {
+				return "", err
+			}
+			l = append(l, line...)
+		}
+		line = l
 	}
 	return string(line), nil
 }


Test patch:
diff --git a/diff/parse_test.go b/diff/parse_test.go
index 8a4dc051..7ae223d6 100644
--- a/diff/parse_test.go
+++ b/diff/parse_test.go
@@ -13,6 +13,8 @@ import (
 
 //go:generate go run testdata/gen.go
 
+const longLine = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Convallis tellus id interdum velit laoreet. Porttitor rhoncus dolor purus non enim praesent. Phasellus egestas tellus rutrum tellus pellentesque. Fringilla urna porttitor rhoncus dolor purus non enim praesent. Proin fermentum leo vel orci porta non pulvinar neque laoreet. Imperdiet nulla malesuada pellentesque elit eget gravida cum. Sit amet nulla facilities morbi tempus iaculis urna id volutpat. Et molestie ac feugiat sed lectus vestibulum mattis. Tortor at auctor urna nunc id cursus metus. Nisl tincidunt eget nullam non nisi est. Tortor at auctor urna nunc id cursus metus.  Ornare massa eget egestas purus viverra accumsan. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Platea dictumst vestibulum rhoncus est pellentesque elit. Auctor neque vitae tempus quam pellentesque nec. Vivamus arcu felis bibendum ut tristique et egestas quis. At in tellus integer feugiat scelerisque varius morbi. Imperdiet nulla malesuada pellentesque elit eget gravida cum sociis natoque. Ac turpis egestas integer eget aliquet nibh praesent tristique. Senectus et netus et malesuada fames ac turpis egestas. Odio eu feugiat pretium nibh ipsum consequat nisl vel. Elit eget gravida cum sociis natoque penatibus et.  Curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Tincidunt arcu non sodales neque sodales ut etiam sit. Fringilla phasellus faucibus scelerisque eleifend donec pretium vulputate. Urna cursus eget nunc scelerisque viverra mauris in aliquam. Fames ac turpis egestas sed. Vivamus arcu felis bibendum ut tristique et egestas quis ipsum. Turpis tincidunt id aliquet risus feugiat in ante metus dictum. Leo a diam sollicitudin tempor id eu. Consectetur adipiscing elit ut aliquam. Facilities nullam vehicula ipsum a arcu. Dignissim suspendisse in est ante in nibh mauris cursus. Faucibus interdum posuere lorem ipsum dolor sit amet consectetur. Neque convallis a cras semper. Pellentesque habitant morbi tristique senectus. Arcu non sodales neque sodales ut etiam. Pretium quam vulputate dignissim suspendisse in. Id velit ut tortor pretium viverra suspendisse potenti. Venenatis urna cursus eget nunc scelerisque. Vestibulum lorem sed risus ultricies tristique. Faucibus purus in massa tempor.  Tellus elementum sagittis vitae et. Ut tortor pretium viverra suspendisse potenti nullam ac. Non arcu risus quis varius. Magna ac placerat vestibulum lectus mauris ultrices eros in. Venenatis lectus magna fringilla urna porttitor. Ultrices gravida dictum fusce ut. Hac habitasse platea dictumst quisque sagittis purus sit. Dictum at tempor commodo ullamcorper a lacus. Mi bibendum neque egestas congue quisque. Lobortis elementum nibh tellus molestie nunc non. Dolor sit amet consectetur adipiscing elit pellentesque habitant morbi tristique.  Pulvinar sapien et ligula ullamcorper malesuada proin libero nunc. Vel elit scelerisque mauris pellentesque pulvinar pellentesque. Eget nulla facilities etiam dignissim diam quis enim. Convallis posuere morbi leo urna molestie. Pellentesque adipiscing commodo elit at imperdiet dui. Mattis pellentesque id nibh tortor id aliquet. Praesent semper feugiat nibh sed pulvinar proin gravida hendrerit lectus. Enim lobortis scelerisque fermentum dui faucibus in ornare quam. Maecenas pharetra convallis posuere morbi leo. Dolor morbi non arcu risus quis. Sit amet purus gravida quis. Quis varius quam quisque id diam vel quam elementum. Tortor condimentum lacinia quis vel eros donec. Gravida neque convallis a cras semper auctor neque vitae tempus. Odio eu feugiat pretium nibh ipsum consequat nisl vel pretium. Urna et pharetra pharetra massa massa ultricies mi. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Convallis tellus id interdum velit laoreet. Porttitor rhoncus dolor purus non enim praesent. Phasellus egestas tellus rutrum tellus pellentesque. Fringilla urna porttitor rhoncus dolor purus non enim praesent. Proin fermentum leo vel orci porta non pulvinar neque laoreet. Imperdiet nulla malesuada pellentesque elit eget gravida cum. Sit amet nulla facilities morbi tempus iaculis urna id volutpat. Et molestie ac feugiat sed lectus vestibulum mattis. Tortor at auctor urna nunc id cursus metus. Nisl tincidunt eget nullam non nisi est. Tortor at auctor urna nunc id cursus metus.  Ornare massa eget egestas purus viverra accumsan. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Platea dictumst vestibulum rhoncus est pellentesque elit. Auctor neque vitae tempus quam pellentesque nec. Vivamus arcu felis bibendum ut tristique et egestas quis. At in tellus integer feugiat scelerisque varius morbi. Imperdiet nulla malesuada pellentesque elit eget gravida cum sociis natoque. Ac turpis egestas integer eget aliquet nibh praesent tristique. Senectus et netus et malesuada fames ac turpis egestas. Odio eu feugiat pretium nibh ipsum consequat nisl vel. Elit eget gravida cum sociis natoque penatibus et.  Curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Tincidunt arcu non sodales neque sodales ut etiam sit. Fringilla phasellus faucibus scelerisque eleifend donec pretium vulputate. Urna cursus eget nunc scelerisque viverra mauris in aliquam. Fames ac turpis egestas sed. Vivamus arcu felis bibendum ut tristique et egestas quis ipsum. Turpis tincidunt id aliquet risus feugiat in ante metus dictum. Leo a diam sollicitudin tempor id eu. Consectetur adipiscing elit ut aliquam. Facilities nullam vehicula ipsum a arcu. Dignissim suspendisse in est ante in nibh mauris cursus. Faucibus interdum posuere lorem ipsum dolor sit amet consectetur. Neque convallis a cras semper. Pellentesque habitant morbi tristique senectus. Arcu non sodales neque sodales ut etiam. Pretium quam vulputate dignissim suspendisse in. Id velit ut tortor pretium viverra suspendisse potenti. Venenatis urna cursus eget nunc scelerisque. Vestibulum lorem sed risus ultricies tristique. Faucibus purus in massa tempor.  Tellus elementum sagittis vitae et. Ut tortor pretium viverra suspendisse potenti nullam ac. Non arcu risus quis varius. Magna ac placerat vestibulum lectus mauris ultrices eros in. Venenatis lectus magna fringilla urna porttitor. Ultrices gravida dictum fusce ut. Hac habitasse platea dictumst quisque sagittis purus sit. Dictum at tempor commodo ullamcorper a lacus. Mi bibendum neque egestas congue quisque. Lobortis elementum nibh tellus molestie nunc non. Dolor sit amet consectetur adipiscing elit pellentesque habitant morbi tristique.  Pulvinar sapien et ligula ullamcorper malesuada proin libero nunc. Vel elit scelerisque mauris pellentesque pulvinar pellentesque. Eget nulla facilities etiam dignissim diam quis enim. Convallis posuere morbi leo urna molestie. Pellentesque adipiscing commodo elit at imperdiet dui. Mattis pellentesque id nibh tortor id aliquet. Praesent semper feugiat nibh sed pulvinar proin gravida hendrerit lectus. Enim lobortis scelerisque fermentum dui faucibus in ornare quam. Maecenas pharetra convallis posuere morbi leo. Dolor morbi non arcu risus quis. Sit amet purus gravida quis. Quis varius quam quisque id diam vel quam elementum. Tortor condimentum lacinia quis vel eros donec. Gravida neque convallis a cras semper auctor neque vitae tempus. Odio eu feugiat pretium nibh ipsum consequat nisl vel pretium. Urna et pharetra pharetra massa massa ultricies mi.`
+
 func TestParseMultiFile(t *testing.T) {
 	files, err := filepath.Glob("testdata/*.diff")
 	if err != nil {
@@ -434,40 +436,38 @@ func TestParseLS(t *testing.T) {
 }
 
 func TestReadline(t *testing.T) {
-	text := `line1
+	tests := []struct {
+		in  string
+		out []string
+	}{
+		{
+			in: `line1
 line2
-line3`
-	r := bufio.NewReader(strings.NewReader(text))
-	{
-		got, err := readline(r)
-		if err != nil {
-			t.Error(err)
-		}
-		if got != "line1" {
-			t.Errorf("got %v, want line1", got)
-		}
-	}
-	{
-		got, err := readline(r)
-		if err != nil {
-			t.Error(err)
-		}
-		if got != "line2" {
-			t.Errorf("got %v, want line2", got)
-		}
+line3`,
+			out: []string{"line1", "line2", "line3"},
+		},
+		{
+			in: longLine + `
+line2
+line3`,
+			out: []string{longLine, "line2", "line3"},
+		},
 	}
-	{
-		got, err := readline(r)
-		if err != nil {
-			t.Error(err)
-		}
-		if got != "line3" {
-			t.Errorf("got %v, want line3", got)
+	for _, tt := range tests {
+		r := bufio.NewReader(strings.NewReader(tt.in))
+		for _, exp := range tt.out {
+			got, err := readline(r)
+			if err != nil {
+				t.Error(err)
+			}
+			if got != exp {
+				t.Errorf("got:\n%v\n\nwant:\n%v", got, exp)
+			}
 		}
-	}
-	{
-		if _, err := readline(r); err != io.EOF {
-			t.Errorf("got err %v, want io.EOF", err)
+		{
+			if _, err := readline(r); err != io.EOF {
+				t.Errorf("got err %v, want io.EOF", err)
+			}
 		}
 	}
 }