diff options
author | Gusted <williamzijl7@hotmail.com> | 2021-11-07 18:52:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-07 12:52:50 -0500 |
commit | 30515f2df3d75dc81a606725509cda70d8acef98 (patch) | |
tree | ada54af56654ea5bbc58202c234b294eb5195f26 | |
parent | 69b61d437357235700306f28d22d21acc39bb2b5 (diff) | |
download | gitea-30515f2df3d75dc81a606725509cda70d8acef98.tar.gz gitea-30515f2df3d75dc81a606725509cda70d8acef98.zip |
Make ParsePatch more robust (#17573)
-rw-r--r-- | services/gitdiff/gitdiff.go | 12 | ||||
-rw-r--r-- | services/gitdiff/gitdiff_test.go | 19 |
2 files changed, 30 insertions, 1 deletions
diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index f843bc4dcf..614f8104ec 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -839,7 +839,12 @@ parsingLoop: case strings.HasPrefix(line, "--- "): // Handle ambiguous filenames if curFile.IsAmbiguous { - if len(line) > 6 && line[4] == 'a' { + // The shortest string that can end up here is: + // "--- a\t\n" without the qoutes. + // This line has a len() of 7 but doesn't contain a oldName. + // So the amount that the line need is at least 8 or more. + // The code will otherwise panic for a out-of-bounds. + if len(line) > 7 && line[4] == 'a' { curFile.OldName = line[6 : len(line)-1] if line[len(line)-2] == '\t' { curFile.OldName = curFile.OldName[:len(curFile.OldName)-1] @@ -1194,6 +1199,11 @@ func readFileName(rd *strings.Reader) (string, bool) { _ = rd.UnreadByte() if char == '"' { fmt.Fscanf(rd, "%q ", &name) + if len(name) == 0 { + log.Error("Reader has no file name: %v", rd) + return "", true + } + if name[0] == '\\' { name = name[1:] } diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go index d69d0c01d8..6decb59b64 100644 --- a/services/gitdiff/gitdiff_test.go +++ b/services/gitdiff/gitdiff_test.go @@ -541,3 +541,22 @@ func TestDiffToHTML_14231(t *testing.T) { assertEqual(t, expected, output) } + +func TestNoCrashes(t *testing.T) { + type testcase struct { + gitdiff string + } + + tests := []testcase{ + { + gitdiff: "diff --git \n--- a\t\n", + }, + { + gitdiff: "diff --git \"0\n", + }, + } + for _, testcase := range tests { + // It shouldn't crash, so don't care about the output. + ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(testcase.gitdiff)) + } +} |