From 51b4e381fd8d0d966b0100c866dad9d37b5c174e Mon Sep 17 00:00:00 2001 From: Erik Seliger Date: Fri, 8 May 2020 14:27:36 +0200 Subject: [PATCH] Add support for special characters in file names --- diff/diff_test.go | 13 ++++++++++ diff/parse.go | 41 +++++++++++++++++++++++++----- diff/testdata/quoted_filename.diff | 8 ++++++ 3 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 diff/testdata/quoted_filename.diff diff --git a/diff/diff_test.go b/diff/diff_test.go index 7883180..442f0f4 100644 --- a/diff/diff_test.go +++ b/diff/diff_test.go @@ -203,6 +203,19 @@ func TestParseFileDiffHeaders(t *testing.T) { }, }, }, + { + filename: "quoted_filename.diff", + wantDiff: &FileDiff{ + OrigName: "a/商品详情.txt", + OrigTime: nil, + NewName: "b/商品详情.txt", + NewTime: nil, + Extended: []string{ + "diff --git \"a/\\345\\225\\206\\345\\223\\201\\350\\257\\246\\346\\203\\205.txt\" \"b/\\345\\225\\206\\345\\223\\201\\350\\257\\246\\346\\203\\205.txt\"", + "index e69de29..c67479b 100644", + }, + }, + }, } for _, test := range tests { diffData, err := ioutil.ReadFile(filepath.Join("testdata", test.filename)) diff --git a/diff/parse.go b/diff/parse.go index f525c64..f788e7e 100644 --- a/diff/parse.go +++ b/diff/parse.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "strconv" "strings" "time" @@ -234,6 +235,15 @@ func (r *FileDiffReader) ReadFileHeaders() (origName, newName string, origTimest return "", "", nil, nil, err } + unquotedOrigName, err := strconv.Unquote(origName) + if err == nil { + origName = unquotedOrigName + } + unquotedNewName, err := strconv.Unquote(newName) + if err == nil { + newName = unquotedNewName + } + return origName, newName, origTimestamp, newTimestamp, nil } @@ -329,30 +339,49 @@ func (r *FileDiffReader) ReadExtendedHeaders() ([]string, error) { // handleEmpty detects when FileDiff was an empty diff and will not have any hunks // that follow. It updates fd fields from the parsed extended headers. func handleEmpty(fd *FileDiff) (wasEmpty bool) { + var err error switch { case (len(fd.Extended) == 3 || len(fd.Extended) == 4 && strings.HasPrefix(fd.Extended[3], "Binary files ")) && strings.HasPrefix(fd.Extended[1], "new file mode ") && strings.HasPrefix(fd.Extended[0], "diff --git "): names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2) fd.OrigName = "/dev/null" - fd.NewName = names[1] + fd.NewName, err = strconv.Unquote(names[1]) + if err != nil { + fd.NewName = names[1] + } return true case (len(fd.Extended) == 3 || len(fd.Extended) == 4 && strings.HasPrefix(fd.Extended[3], "Binary files ")) && strings.HasPrefix(fd.Extended[1], "deleted file mode ") && strings.HasPrefix(fd.Extended[0], "diff --git "): names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2) - fd.OrigName = names[0] + fd.OrigName, err = strconv.Unquote(names[0]) + if err != nil { + fd.OrigName = names[0] + } fd.NewName = "/dev/null" return true case len(fd.Extended) == 4 && strings.HasPrefix(fd.Extended[2], "rename from ") && strings.HasPrefix(fd.Extended[3], "rename to ") && strings.HasPrefix(fd.Extended[0], "diff --git "): names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2) - fd.OrigName = names[0] - fd.NewName = names[1] + fd.OrigName, err = strconv.Unquote(names[0]) + if err != nil { + fd.OrigName = names[0] + } + fd.NewName, err = strconv.Unquote(names[1]) + if err != nil { + fd.NewName = names[1] + } return true case len(fd.Extended) == 3 && strings.HasPrefix(fd.Extended[2], "Binary files ") && strings.HasPrefix(fd.Extended[0], "diff --git "): names := strings.SplitN(fd.Extended[0][len("diff --git "):], " ", 2) - fd.OrigName = names[0] - fd.NewName = names[1] + fd.OrigName, err = strconv.Unquote(names[0]) + if err != nil { + fd.OrigName = names[0] + } + fd.NewName, err = strconv.Unquote(names[1]) + if err != nil { + fd.NewName = names[1] + } return true default: return false diff --git a/diff/testdata/quoted_filename.diff b/diff/testdata/quoted_filename.diff new file mode 100644 index 0000000..73dea88 --- /dev/null +++ b/diff/testdata/quoted_filename.diff @@ -0,0 +1,8 @@ +diff --git "a/\345\225\206\345\223\201\350\257\246\346\203\205.txt" "b/\345\225\206\345\223\201\350\257\246\346\203\205.txt" +index e69de29..c67479b 100644 +--- "a/\345\225\206\345\223\201\350\257\246\346\203\205.txt" ++++ "b/\345\225\206\345\223\201\350\257\246\346\203\205.txt" +@@ -0,0 +1,3 @@ ++some ++test ++file