diff --git a/modules/upload/filetype.go b/modules/upload/filetype.go index 1ec7324ed3196..2ab326d11690f 100644 --- a/modules/upload/filetype.go +++ b/modules/upload/filetype.go @@ -31,19 +31,16 @@ func (err ErrFileTypeForbidden) Error() string { func VerifyAllowedContentType(buf []byte, allowedTypes []string) error { fileType := http.DetectContentType(buf) - allowed := false for _, t := range allowedTypes { t := strings.Trim(t, " ") - if t == "*/*" || t == fileType { - allowed = true - break - } - } - if !allowed { - log.Info("Attachment with type %s blocked from upload", fileType) - return ErrFileTypeForbidden{Type: fileType} + if t == "*/*" || t == fileType || + // Allow directives after type, like 'text/plain; charset=utf-8' + strings.HasPrefix(fileType, t+";") { + return nil + } } - return nil + log.Info("Attachment with type %s blocked from upload", fileType) + return ErrFileTypeForbidden{Type: fileType} } diff --git a/modules/upload/filetype_test.go b/modules/upload/filetype_test.go new file mode 100644 index 0000000000000..f93a1c5cc3bc3 --- /dev/null +++ b/modules/upload/filetype_test.go @@ -0,0 +1,47 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package upload + +import ( + "bytes" + "compress/gzip" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestUpload(t *testing.T) { + testContent := []byte(`This is a plain text file.`) + var b bytes.Buffer + w := gzip.NewWriter(&b) + w.Write(testContent) + w.Close() + + kases := []struct { + data []byte + allowedTypes []string + err error + }{ + { + data: testContent, + allowedTypes: []string{"text/plain"}, + err: nil, + }, + { + data: testContent, + allowedTypes: []string{"application/x-gzip"}, + err: ErrFileTypeForbidden{"text/plain; charset=utf-8"}, + }, + { + data: b.Bytes(), + allowedTypes: []string{"application/x-gzip"}, + err: nil, + }, + } + + for _, kase := range kases { + assert.Equal(t, kase.err, VerifyAllowedContentType(kase.data, kase.allowedTypes)) + } +}