From 7780ea88907197abf6166bedc8b3021489444ea3 Mon Sep 17 00:00:00 2001
From: mrsdizzie <info@mrsdizzie.com>
Date: Thu, 14 Mar 2019 12:09:53 -0400
Subject: [PATCH] Fix ParsePatch function to work with quoted diff --git
 strings (#6323)

* Fix ParsePatch to work properly with quoted diff --git string

Currently ParsePatch fails when a diff contains a quoted diff line like:

diff --git "a/file" "b/file"

This patch makes it properly parse the line when that happens.

Fixes #6309

* Add test for regular case while here

* Simplify string modification
---
 models/git_diff.go      | 10 +++++++++
 models/git_diff_test.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

diff --git a/models/git_diff.go b/models/git_diff.go
index 2a8019995d..2e76e56bea 100644
--- a/models/git_diff.go
+++ b/models/git_diff.go
@@ -550,7 +550,12 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
 			beg := len(cmdDiffHead)
 			a := line[beg+2 : middle]
 			b := line[middle+3:]
+
 			if hasQuote {
+				// Keep the entire string in double quotes for now
+				a = line[beg:middle]
+				b = line[middle+1:]
+
 				var err error
 				a, err = strconv.Unquote(a)
 				if err != nil {
@@ -560,6 +565,10 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
 				if err != nil {
 					return nil, fmt.Errorf("Unquote: %v", err)
 				}
+				// Now remove the /a /b
+				a = a[2:]
+				b = b[2:]
+
 			}
 
 			curFile = &DiffFile{
@@ -637,6 +646,7 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
 			}
 		}
 	}
+
 	return diff, nil
 }
 
diff --git a/models/git_diff_test.go b/models/git_diff_test.go
index ac64771226..2111e9044f 100644
--- a/models/git_diff_test.go
+++ b/models/git_diff_test.go
@@ -5,6 +5,8 @@ import (
 	"strings"
 	"testing"
 
+	"code.gitea.io/gitea/modules/setting"
+
 	dmp "github.com/sergi/go-diff/diffmatchpatch"
 	"github.com/stretchr/testify/assert"
 )
@@ -99,6 +101,59 @@ func ExampleCutDiffAroundLine() {
 	println(result)
 }
 
+func TestParsePatch(t *testing.T) {
+	var diff = `diff --git "a/README.md" "b/README.md"
+--- a/README.md
++++ b/README.md
+@@ -1,3 +1,6 @@
+ # gitea-github-migrator
++
++ Build Status
+- Latest Release
+ Docker Pulls
++ cut off
++ cut off`
+	result, err := ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff))
+	if err != nil {
+		t.Errorf("ParsePatch failed: %s", err)
+	}
+	println(result)
+
+	var diff2 = `diff --git "a/A \\ B" "b/A \\ B"
+--- "a/A \\ B"
++++ "b/A \\ B"
+@@ -1,3 +1,6 @@
+ # gitea-github-migrator
++
++ Build Status
+- Latest Release
+ Docker Pulls
++ cut off
++ cut off`
+	result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2))
+	if err != nil {
+		t.Errorf("ParsePatch failed: %s", err)
+	}
+	println(result)
+
+	var diff3 = `diff --git a/README.md b/README.md
+--- a/README.md
++++ b/README.md
+@@ -1,3 +1,6 @@
+ # gitea-github-migrator
++
++ Build Status
+- Latest Release
+ Docker Pulls
++ cut off
++ cut off`
+	result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff3))
+	if err != nil {
+		t.Errorf("ParsePatch failed: %s", err)
+	}
+	println(result)
+}
+
 func setupDefaultDiff() *Diff {
 	return &Diff{
 		Files: []*DiffFile{