Skip to content

Commit 4a548a0

Browse files
authored
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 <[email protected]> * Add testcase as per @mrsdizzie Signed-off-by: Andrew Thornton <[email protected]>
1 parent 8bf2ee1 commit 4a548a0

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"
1919
"os/exec"
2020
"sort"
21-
"strconv"
2221
"strings"
2322

2423
"code.gitea.io/gitea/models"
@@ -532,40 +531,28 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
532531
break
533532
}
534533

535-
var middle int
536-
537534
// Note: In case file name is surrounded by double quotes (it happens only in git-shell).
538535
// e.g. diff --git "a/xxx" "b/xxx"
539-
hasQuote := line[len(cmdDiffHead)] == '"'
540-
if hasQuote {
541-
middle = strings.Index(line, ` "b/`)
536+
var a string
537+
var b string
538+
539+
rd := strings.NewReader(line[len(cmdDiffHead):])
540+
char, _ := rd.ReadByte()
541+
_ = rd.UnreadByte()
542+
if char == '"' {
543+
fmt.Fscanf(rd, "%q ", &a)
542544
} else {
543-
middle = strings.Index(line, " b/")
545+
fmt.Fscanf(rd, "%s ", &a)
544546
}
545-
546-
beg := len(cmdDiffHead)
547-
a := line[beg+2 : middle]
548-
b := line[middle+3:]
549-
550-
if hasQuote {
551-
// Keep the entire string in double quotes for now
552-
a = line[beg:middle]
553-
b = line[middle+1:]
554-
555-
var err error
556-
a, err = strconv.Unquote(a)
557-
if err != nil {
558-
return nil, fmt.Errorf("Unquote: %v", err)
559-
}
560-
b, err = strconv.Unquote(b)
561-
if err != nil {
562-
return nil, fmt.Errorf("Unquote: %v", err)
563-
}
564-
// Now remove the /a /b
565-
a = a[2:]
566-
b = b[2:]
567-
547+
char, _ = rd.ReadByte()
548+
_ = rd.UnreadByte()
549+
if char == '"' {
550+
fmt.Fscanf(rd, "%q", &b)
551+
} else {
552+
fmt.Fscanf(rd, "%s", &b)
568553
}
554+
a = a[2:]
555+
b = b[2:]
569556

570557
curFile = &DiffFile{
571558
Name: b,

services/gitdiff/gitdiff_test.go

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

79+
var diff2a = `diff --git "a/A \\ B" b/A/B
80+
--- "a/A \\ B"
81+
+++ b/A/B
82+
@@ -1,3 +1,6 @@
83+
# gitea-github-migrator
84+
+
85+
+ Build Status
86+
- Latest Release
87+
Docker Pulls
88+
+ cut off
89+
+ cut off`
90+
result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2a))
91+
if err != nil {
92+
t.Errorf("ParsePatch failed: %s", err)
93+
}
94+
println(result)
95+
7996
var diff3 = `diff --git a/README.md b/README.md
8097
--- a/README.md
8198
+++ b/README.md

0 commit comments

Comments
 (0)