[MM-45504] Improve GIF preprocessing logic (#20595)

* Improve GIF preprocessing logic

* Prefer io to ioutil

* Avoid color palette allocation
Этот коммит содержится в:
Claudio Costa
2022-07-11 09:34:49 +02:00
коммит произвёл GitHub
родитель c3d2602dfe
Коммит 76583344c0
7 изменённых файлов: 133 добавлений и 88 удалений

Просмотреть файл

@@ -744,7 +744,7 @@ func parseImages(body io.Reader) (*model.PostImage, error) {
if format == "gif" {
// Decoding the config may have read some of the image data, so re-read the data that has already been read first
frameCount, err := imgutils.CountFrames(io.MultiReader(buf, body))
frameCount, err := imgutils.CountGIFFrames(io.MultiReader(buf, body))
if err != nil {
return nil, err
}

Просмотреть файл

@@ -6,6 +6,7 @@ package app
import (
"errors"
"io"
"mime"
"net/http"
"path/filepath"
"strings"
@@ -21,6 +22,23 @@ import (
const minFirstPartSize = 5 * 1024 * 1024 // 5MB
func (a *App) genFileInfoFromReader(name string, file io.ReadSeeker, size int64) (*model.FileInfo, error) {
ext := strings.ToLower(filepath.Ext(name))
info := &model.FileInfo{
Name: name,
MimeType: mime.TypeByExtension(ext),
}
if info.IsImage() {
config, _, err := a.ch.imgDecoder.DecodeConfig(file)
if err != nil {
return nil, err
}
info.Width = config.Width
info.Height = config.Height
}
return info, nil
}
func (a *App) runPluginsHook(c *request.Context, info *model.FileInfo, file io.Reader) *model.AppError {
pluginsEnvironment := a.GetPluginsEnvironment()
if pluginsEnvironment == nil {
@@ -244,10 +262,11 @@ func (a *App) UploadData(c *request.Context, us *model.UploadSession, rd io.Read
return nil, model.NewAppError("UploadData", "app.upload.upload_data.read_file.app_error", nil, err.Error(), http.StatusInternalServerError)
}
info, err := model.GetInfoForBytes(us.Filename, file, int(us.FileSize))
// generate file info
info, genErr := a.genFileInfoFromReader(us.Filename, file, us.FileSize)
file.Close()
if err != nil {
return nil, err
if genErr != nil {
return nil, model.NewAppError("UploadData", "app.upload.upload_data.gen_info.app_error", nil, genErr.Error(), http.StatusInternalServerError)
}
info.CreatorId = us.UserId

Просмотреть файл

@@ -17,6 +17,7 @@ import (
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/utils/fileutils"
"github.com/mattermost/mattermost-server/v6/utils/imgutils"
)
func TestCreateUploadSession(t *testing.T) {
@@ -232,6 +233,23 @@ func TestUploadData(t *testing.T) {
require.NotEmpty(t, info.ThumbnailPath)
require.NotEmpty(t, info.PreviewPath)
})
t.Run("huge GIF", func(t *testing.T) {
gifData := imgutils.GenGIFData(65535, 65535, 10)
us.Id = model.NewId()
us.Filename = "test.gif"
us.FileSize = int64(len(gifData))
var appErr *model.AppError
us, appErr = th.App.CreateUploadSession(us)
require.Nil(t, appErr)
require.NotEmpty(t, us)
info, appErr := th.App.UploadData(th.Context, us, bytes.NewReader(gifData))
require.NotNil(t, appErr)
require.Equal(t, "app.upload.upload_data.large_image.app_error", appErr.Id)
require.Empty(t, info)
})
}
func TestUploadDataConcurrent(t *testing.T) {