Skip to content

Commit 7a8a05c

Browse files
authored
Fix diff path unquoting (#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>
1 parent fcabbae commit 7a8a05c

File tree

2 files changed

+34
-30
lines changed

2 files changed

+34
-30
lines changed

services/gitdiff/gitdiff.go

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import (
1818
"os/exec"
1919
"regexp"
2020
"sort"
21-
"strconv"
2221
"strings"
2322

2423
"code.gitea.io/gitea/models"
@@ -570,40 +569,28 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
570569
break
571570
}
572571

573-
var middle int
574-
575572
// Note: In case file name is surrounded by double quotes (it happens only in git-shell).
576573
// e.g. diff --git "a/xxx" "b/xxx"
577-
hasQuote := line[len(cmdDiffHead)] == '"'
578-
if hasQuote {
579-
middle = strings.Index(line, ` "b/`)
574+
var a string
575+
var b string
576+
577+
rd := strings.NewReader(line[len(cmdDiffHead):])
578+
char, _ := rd.ReadByte()
579+
_ = rd.UnreadByte()
580+
if char == '"' {
581+
fmt.Fscanf(rd, "%q ", &a)
580582
} else {
581-
middle = strings.Index(line, " b/")
583+
fmt.Fscanf(rd, "%s ", &a)
582584
}
583-
584-
beg := len(cmdDiffHead)
585-
a := line[beg+2 : middle]
586-
b := line[middle+3:]
587-
588-
if hasQuote {
589-
// Keep the entire string in double quotes for now
590-
a = line[beg:middle]
591-
b = line[middle+1:]
592-
593-
var err error
594-
a, err = strconv.Unquote(a)
595-
if err != nil {
596-
return nil, fmt.Errorf("Unquote: %v", err)
597-
}
598-
b, err = strconv.Unquote(b)
599-
if err != nil {
600-
return nil, fmt.Errorf("Unquote: %v", err)
601-
}
602-
// Now remove the /a /b
603-
a = a[2:]
604-
b = b[2:]
605-
585+
char, _ = rd.ReadByte()
586+
_ = rd.UnreadByte()
587+
if char == '"' {
588+
fmt.Fscanf(rd, "%q", &b)
589+
} else {
590+
fmt.Fscanf(rd, "%s", &b)
606591
}
592+
a = a[2:]
593+
b = b[2:]
607594

608595
curFile = &DiffFile{
609596
Name: b,

services/gitdiff/gitdiff_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,23 @@ func TestParsePatch(t *testing.T) {
112112
}
113113
println(result)
114114

115+
var diff2a = `diff --git "a/A \\ B" b/A/B
116+
--- "a/A \\ B"
117+
+++ b/A/B
118+
@@ -1,3 +1,6 @@
119+
# gitea-github-migrator
120+
+
121+
+ Build Status
122+
- Latest Release
123+
Docker Pulls
124+
+ cut off
125+
+ cut off`
126+
result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2a))
127+
if err != nil {
128+
t.Errorf("ParsePatch failed: %s", err)
129+
}
130+
println(result)
131+
115132
var diff3 = `diff --git a/README.md b/README.md
116133
--- a/README.md
117134
+++ b/README.md

0 commit comments

Comments
 (0)