aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGusted <williamzijl7@hotmail.com>2021-11-07 18:52:50 +0100
committerGitHub <noreply@github.com>2021-11-07 12:52:50 -0500
commit30515f2df3d75dc81a606725509cda70d8acef98 (patch)
treeada54af56654ea5bbc58202c234b294eb5195f26
parent69b61d437357235700306f28d22d21acc39bb2b5 (diff)
downloadgitea-30515f2df3d75dc81a606725509cda70d8acef98.tar.gz
gitea-30515f2df3d75dc81a606725509cda70d8acef98.zip
Make ParsePatch more robust (#17573)
-rw-r--r--services/gitdiff/gitdiff.go12
-rw-r--r--services/gitdiff/gitdiff_test.go19
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))
+ }
+}