From 19a27ded86b7bd97d2611bae11850743bcaf5098 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Wed, 13 Nov 2024 19:09:40 +0100 Subject: [PATCH] feat: Make AVIF Images work with Forgejo --- custom/conf/app.example.ini | 6 +++--- modules/setting/attachment.go | 4 ++-- modules/typesniffer/typesniffer.go | 8 ++++++++ modules/typesniffer/typesniffer_test.go | 10 ++++++++++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 70db76cf7f..2b5b518a19 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1938,7 +1938,7 @@ LEVEL = Info ;ENABLED = true ;; ;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types. -;ALLOWED_TYPES = .cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip +;ALLOWED_TYPES = .avif,.cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip ;; ;; Max size of each file. Defaults to 2048MB ;MAX_SIZE = 2048 @@ -1976,7 +1976,7 @@ LEVEL = Info ;; Url lookup for the minio bucket only available when STORAGE_TYPE is `minio` ;; Available values: auto, dns, path ;; If empty, it behaves the same as "auto" was set -;MINIO_BUCKET_LOOKUP = +;MINIO_BUCKET_LOOKUP = ;; ;; Minio location to create bucket only available when STORAGE_TYPE is `minio` ;MINIO_LOCATION = us-east-1 @@ -2703,7 +2703,7 @@ LEVEL = Info ;; Url lookup for the minio bucket only available when STORAGE_TYPE is `minio` ;; Available values: auto, dns, path ;; If empty, it behaves the same as "auto" was set -;MINIO_BUCKET_LOOKUP = +;MINIO_BUCKET_LOOKUP = ;; ;; Minio location to create bucket only available when STORAGE_TYPE is `minio` ;MINIO_LOCATION = us-east-1 diff --git a/modules/setting/attachment.go b/modules/setting/attachment.go index 4255ac985e..956525f0db 100644 --- a/modules/setting/attachment.go +++ b/modules/setting/attachment.go @@ -12,7 +12,7 @@ var Attachment = struct { Enabled bool }{ Storage: &Storage{}, - AllowedTypes: ".cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.webp,.xls,.xlsx,.zip", + AllowedTypes: ".avif,.cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.webp,.xls,.xlsx,.zip", MaxSize: 2048, MaxFiles: 5, Enabled: true, @@ -25,7 +25,7 @@ func loadAttachmentFrom(rootCfg ConfigProvider) (err error) { return err } - Attachment.AllowedTypes = sec.Key("ALLOWED_TYPES").MustString(".cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.webp,.xls,.xlsx,.zip") + Attachment.AllowedTypes = sec.Key("ALLOWED_TYPES").MustString(".avif,.cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.webp,.xls,.xlsx,.zip") Attachment.MaxSize = sec.Key("MAX_SIZE").MustInt64(2048) Attachment.MaxFiles = sec.Key("MAX_FILES").MustInt(5) Attachment.Enabled = sec.Key("ENABLED").MustBool(true) diff --git a/modules/typesniffer/typesniffer.go b/modules/typesniffer/typesniffer.go index 6aec5c285e..64037af8d3 100644 --- a/modules/typesniffer/typesniffer.go +++ b/modules/typesniffer/typesniffer.go @@ -20,6 +20,8 @@ const sniffLen = 1024 const ( // SvgMimeType MIME type of SVG images. SvgMimeType = "image/svg+xml" + // AvifMimeType MIME type of AVIF images + AvifMimeType = "image/avif" // ApplicationOctetStream MIME type of binary files. ApplicationOctetStream = "application/octet-stream" ) @@ -106,6 +108,12 @@ func DetectContentType(data []byte) SniffedType { } } + // AVIF is unsuported by http.DetectContentType + // Signature taken from https://stackoverflow.com/a/68322450 + if bytes.Index(data, []byte("ftypavif")) == 4 { + ct = AvifMimeType + } + if strings.HasPrefix(ct, "audio/") && bytes.HasPrefix(data, []byte("ID3")) { // The MP3 detection is quite inaccurate, any content with "ID3" prefix will result in "audio/mpeg". // So remove the "ID3" prefix and detect again, if result is text, then it must be text content. diff --git a/modules/typesniffer/typesniffer_test.go b/modules/typesniffer/typesniffer_test.go index f6fa07ee7f..8d80b4ddb4 100644 --- a/modules/typesniffer/typesniffer_test.go +++ b/modules/typesniffer/typesniffer_test.go @@ -135,3 +135,13 @@ func TestDetectContentTypeOgg(t *testing.T) { require.NoError(t, err) assert.True(t, st.IsVideo()) } + +func TestDetectContentTypeAvif(t *testing.T) { + avifImage, err := hex.DecodeString("000000206674797061766966") + require.NoError(t, err) + + st, err := DetectContentTypeFromReader(bytes.NewReader(avifImage)) + require.NoError(t, err) + + assert.True(t, st.IsImage()) +}