Skip to content

Commit a7fc600

Browse files
committed
Fix diff path unquoting (go-gitea#12554)
Backport go-gitea#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 go-gitea#12546 Signed-off-by: Andrew Thornton <[email protected]> * Add testcase as per @mrsdizzie Signed-off-by: Andrew Thornton <[email protected]>
1 parent 8bf2ee1 commit a7fc600

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)