diff options
author | Ahmad Sherif <me@ahmadsherif.com> | 2017-04-25 19:37:15 +0300 |
---|---|---|
committer | Ahmad Sherif <me@ahmadsherif.com> | 2017-05-01 19:17:36 +0300 |
commit | 518e0219acabd5570b2fc865b91ee76d0ee2e0a9 (patch) | |
tree | c448f11c060ea0cb7cbd801e12bc54806204718a | |
parent | 8456d9de5aab1b9c4cd8925f85a2a26bc41902ce (diff) |
Unescape things like tabs and new lines in diff files names
-rw-r--r-- | internal/diff/diff.go | 47 | ||||
-rw-r--r-- | internal/service/diff/commit_test.go | 14 | ||||
-rw-r--r-- | internal/service/diff/testdata/tab-newline-file-chunks.txt | 2 |
3 files changed, 53 insertions, 10 deletions
diff --git a/internal/diff/diff.go b/internal/diff/diff.go index 084dbaf20..837a4b7ed 100644 --- a/internal/diff/diff.go +++ b/internal/diff/diff.go @@ -190,7 +190,7 @@ func (parser *Parser) findNextPatchFromPath() error { } if matches := diffHeaderRegexp.FindSubmatch(line); len(matches) > 0 { - parser.nextPatchFromPath = unescapeOctalBytes(matches[1]) + parser.nextPatchFromPath = unescape(matches[1]) return nil } @@ -219,9 +219,9 @@ func parseRawLine(line []byte, diff *Diff) error { diff.FromID = string(matches[3]) diff.ToID = string(matches[4]) - diff.FromPath = unescapeOctalBytes(helper.UnquoteBytes(matches[6])) + diff.FromPath = unescape(helper.UnquoteBytes(matches[6])) if matches[5][0] == 'C' || matches[5][0] == 'R' { - diff.ToPath = unescapeOctalBytes(helper.UnquoteBytes(matches[7])) + diff.ToPath = unescape(helper.UnquoteBytes(matches[7])) } else { diff.ToPath = diff.FromPath } @@ -261,16 +261,45 @@ func consumeLine(reader *bufio.Reader) error { return nil } -func unescapeOctalBytes(s []byte) []byte { +// unescape unescapes the escape codes used by 'git diff' +func unescape(s []byte) []byte { var unescaped []byte for i := 0; i < len(s); i++ { - if s[i] == '\\' && i+3 < len(s) && helper.IsNumber(s[i+1:i+4]) { - octalByte, err := strconv.ParseUint(string(s[i+1:i+4]), 8, 8) - if err == nil { - unescaped = append(unescaped, byte(octalByte)) + if s[i] == '\\' { + if i+3 < len(s) && helper.IsNumber(s[i+1:i+4]) { + octalByte, err := strconv.ParseUint(string(s[i+1:i+4]), 8, 8) + if err == nil { + unescaped = append(unescaped, byte(octalByte)) + + i += 3 + continue + } + } - i += 3 + if i+1 < len(s) { + var unescapedByte byte + + switch s[i+1] { + case '"', '\\', '/', '\'': + unescapedByte = s[i+1] + case 'b': + unescapedByte = '\b' + case 'f': + unescapedByte = '\f' + case 'n': + unescapedByte = '\n' + case 'r': + unescapedByte = '\r' + case 't': + unescapedByte = '\t' + default: + unescaped = append(unescaped, '\\') + unescapedByte = s[i+1] + } + + unescaped = append(unescaped, unescapedByte) + i++ continue } } diff --git a/internal/service/diff/commit_test.go b/internal/service/diff/commit_test.go index 741a76e6b..56a7b1563 100644 --- a/internal/service/diff/commit_test.go +++ b/internal/service/diff/commit_test.go @@ -31,7 +31,7 @@ func TestSuccessfulCommitDiffRequest(t *testing.T) { client := newDiffClient(t) repo := &pb.Repository{Path: testRepoPath} - rightCommit := "41ae11ba5d091d73d5de671f6fa7d1a4539e979e" + rightCommit := "742518b2be68fc750bb4c357c0df821a88113286" leftCommit := "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab" rpcRequest := &pb.CommitDiffRequest{Repository: repo, RightCommitId: rightCommit, LeftCommitId: leftCommit, IgnoreWhitespaceChange: false} @@ -161,6 +161,18 @@ func TestSuccessfulCommitDiffRequest(t *testing.T) { { Diff: diff.Diff{ FromID: "0000000000000000000000000000000000000000", + ToID: "a135e3e0d4af177a902ca57dcc4c7fc6f30858b1", + OldMode: 0, + NewMode: 0100644, + FromPath: []byte("gitaly/tab\tnewline\n file"), + ToPath: []byte("gitaly/tab\tnewline\n file"), + Binary: false, + }, + ChunksCombined: testhelper.MustReadFile(t, "testdata/tab-newline-file-chunks.txt"), + }, + { + Diff: diff.Diff{ + FromID: "0000000000000000000000000000000000000000", ToID: "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", OldMode: 0, NewMode: 0100755, diff --git a/internal/service/diff/testdata/tab-newline-file-chunks.txt b/internal/service/diff/testdata/tab-newline-file-chunks.txt new file mode 100644 index 000000000..3be1b3d5a --- /dev/null +++ b/internal/service/diff/testdata/tab-newline-file-chunks.txt @@ -0,0 +1,2 @@ +@@ -0,0 +1 @@ ++A file with a tab (\t) and a new line (\n) in its name. |