[MM-45504] Improve GIF preprocessing logic (#20595)
* Improve GIF preprocessing logic * Prefer io to ioutil * Avoid color palette allocation
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
c3d2602dfe
Коммит
76583344c0
@@ -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) {
|
||||
|
||||
Ссылка в новой задаче
Block a user