Fix diff path unquoting (#12554) (#12575)

Backport #12554

* Fix diff path unquoting

services/gitdiff/gitdiff.go whereby there it assumed that the path would
always be quoted on both sides

This PR simplifies the code here and uses fmt.Fscanf to parse the
strings as necessary.

Fix #12546

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Add testcase as per @mrsdizzie

Signed-off-by: Andrew Thornton <art27@cantab.net>
pull/12593/head
zeripath 4 years ago committed by GitHub
parent 8bf2ee1e02
commit 4a548a0332
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 43
      services/gitdiff/gitdiff.go
  2. 17
      services/gitdiff/gitdiff_test.go

@ -18,7 +18,6 @@ import (
"os" "os"
"os/exec" "os/exec"
"sort" "sort"
"strconv"
"strings" "strings"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
@ -532,41 +531,29 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
break break
} }
var middle int
// Note: In case file name is surrounded by double quotes (it happens only in git-shell). // Note: In case file name is surrounded by double quotes (it happens only in git-shell).
// e.g. diff --git "a/xxx" "b/xxx" // e.g. diff --git "a/xxx" "b/xxx"
hasQuote := line[len(cmdDiffHead)] == '"' var a string
if hasQuote { var b string
middle = strings.Index(line, ` "b/`)
rd := strings.NewReader(line[len(cmdDiffHead):])
char, _ := rd.ReadByte()
_ = rd.UnreadByte()
if char == '"' {
fmt.Fscanf(rd, "%q ", &a)
} else { } else {
middle = strings.Index(line, " b/") fmt.Fscanf(rd, "%s ", &a)
}
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 {
return nil, fmt.Errorf("Unquote: %v", err)
} }
b, err = strconv.Unquote(b) char, _ = rd.ReadByte()
if err != nil { _ = rd.UnreadByte()
return nil, fmt.Errorf("Unquote: %v", err) if char == '"' {
fmt.Fscanf(rd, "%q", &b)
} else {
fmt.Fscanf(rd, "%s", &b)
} }
// Now remove the /a /b
a = a[2:] a = a[2:]
b = b[2:] b = b[2:]
}
curFile = &DiffFile{ curFile = &DiffFile{
Name: b, Name: b,
OldName: a, OldName: a,

@ -76,6 +76,23 @@ func TestParsePatch(t *testing.T) {
} }
println(result) println(result)
var diff2a = `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(diff2a))
if err != nil {
t.Errorf("ParsePatch failed: %s", err)
}
println(result)
var diff3 = `diff --git a/README.md b/README.md var diff3 = `diff --git a/README.md b/README.md
--- a/README.md --- a/README.md
+++ b/README.md +++ b/README.md

Loading…
Cancel
Save