You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@answer.apache.org by li...@apache.org on 2024/01/30 08:16:21 UTC

(incubator-answer) branch refactor/file created (now cf4e05fb)

This is an automated email from the ASF dual-hosted git repository.

linkinstar pushed a change to branch refactor/file
in repository https://gitbox.apache.org/repos/asf/incubator-answer.git


      at cf4e05fb refactor(file): refactor file format check function

This branch includes the following new commits:

     new cf4e05fb refactor(file): refactor file format check function

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(incubator-answer) 01/01: refactor(file): refactor file format check function

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

linkinstar pushed a commit to branch refactor/file
in repository https://gitbox.apache.org/repos/asf/incubator-answer.git

commit cf4e05fbc653e1888cd895e44fc4608af15a458f
Author: LinkinStars <li...@foxmail.com>
AuthorDate: Tue Jan 30 16:16:07 2024 +0800

    refactor(file): refactor file format check function
---
 internal/service/uploader/upload.go |  2 +-
 pkg/checker/file_type.go            | 77 +++++++++++++++++++++++++++++--------
 2 files changed, 61 insertions(+), 18 deletions(-)

diff --git a/internal/service/uploader/upload.go b/internal/service/uploader/upload.go
index fb0b2af0..3619a6e1 100644
--- a/internal/service/uploader/upload.go
+++ b/internal/service/uploader/upload.go
@@ -244,7 +244,7 @@ func (us *uploaderService) uploadFile(ctx *gin.Context, file *multipart.FileHead
 	}
 	defer src.Close()
 
-	if !checker.IsSupportedImageFile(src, filepath.Ext(fileSubPath)) {
+	if !checker.IsSupportedImageFile(filePath) {
 		return "", errors.BadRequest(reason.UploadFileUnsupportedFileFormat)
 	}
 
diff --git a/pkg/checker/file_type.go b/pkg/checker/file_type.go
index 3599270a..6c61dca2 100644
--- a/pkg/checker/file_type.go
+++ b/pkg/checker/file_type.go
@@ -20,13 +20,18 @@
 package checker
 
 import (
-	"golang.org/x/image/webp"
+	"fmt"
 	"image"
 	_ "image/gif" // use init to support decode jpeg,jpg,png,gif
 	_ "image/jpeg"
 	_ "image/png"
 	"io"
+	"os"
+	"path/filepath"
 	"strings"
+
+	"github.com/segmentfault/pacman/log"
+	"golang.org/x/image/webp"
 )
 
 const (
@@ -35,47 +40,85 @@ const (
 
 // IsSupportedImageFile currently answers support image type is
 // `image/jpeg, image/jpg, image/png, image/gif, image/webp`
-func IsSupportedImageFile(file io.Reader, ext string) bool {
-	ext = strings.ToLower(strings.TrimPrefix(ext, "."))
-	var err error
+func IsSupportedImageFile(localFilePath string) bool {
+	ext := strings.ToLower(strings.TrimPrefix(filepath.Ext(localFilePath), "."))
 	switch ext {
 	case "jpg", "jpeg", "png", "gif": // only allow for `image/jpeg,image/jpg,image/png, image/gif`
-		if !checkImageSize(file) {
+		if !decodeAndCheckImageFile(localFilePath, standardImageConfigCheck) {
+			return false
+		}
+		if !decodeAndCheckImageFile(localFilePath, standardImageCheck) {
 			return false
 		}
-		_, _, err = image.Decode(file)
 	case "ico":
 		// TODO: There is currently no good Golang library to parse whether the image is in ico format.
 		return true
 	case "webp":
-		if !checkWebpSize(file) {
+		if !decodeAndCheckImageFile(localFilePath, webpImageConfigCheck) {
+			return false
+		}
+		if !decodeAndCheckImageFile(localFilePath, webpImageCheck) {
 			return false
 		}
-		_, err = webp.Decode(file)
 	default:
 		return false
 	}
-	return err == nil
+	return true
 }
 
-func checkImageSize(file io.Reader) bool {
-	config, _, err := image.DecodeConfig(file)
+func decodeAndCheckImageFile(localFilePath string, checker func(io.Reader) error) bool {
+	file, err := os.Open(localFilePath)
 	if err != nil {
+		log.Errorf("open file error: %v", err)
 		return false
 	}
-	if (config.Width * config.Height) > maxImageSize {
+	defer file.Close()
+
+	if err = checker(file); err != nil {
+		log.Errorf("check image format error: %v", err)
 		return false
 	}
 	return true
 }
 
-func checkWebpSize(file io.Reader) bool {
+func standardImageConfigCheck(file io.Reader) error {
+	config, _, err := image.DecodeConfig(file)
+	if err != nil {
+		return fmt.Errorf("decode image config error: %v", err)
+	}
+	if imageSizeTooLarge(config) {
+		return fmt.Errorf("image size too large")
+	}
+	return nil
+}
+
+func standardImageCheck(file io.Reader) error {
+	_, _, err := image.Decode(file)
+	if err != nil {
+		return fmt.Errorf("decode image error: %v", err)
+	}
+	return nil
+}
+
+func webpImageConfigCheck(file io.Reader) error {
 	config, err := webp.DecodeConfig(file)
 	if err != nil {
-		return false
+		return fmt.Errorf("decode webp image config error: %v", err)
 	}
-	if (config.Width * config.Height) > maxImageSize {
-		return false
+	if imageSizeTooLarge(config) {
+		return fmt.Errorf("image size too large")
 	}
-	return true
+	return nil
+}
+
+func webpImageCheck(file io.Reader) error {
+	_, err := webp.Decode(file)
+	if err != nil {
+		return fmt.Errorf("decode webp image error: %v", err)
+	}
+	return nil
+}
+
+func imageSizeTooLarge(config image.Config) bool {
+	return config.Width*config.Height > maxImageSize
 }