2020package checker
2121
2222import (
23- "golang.org/x/image/webp "
23+ "fmt "
2424 "image"
2525 _ "image/gif" // use init to support decode jpeg,jpg,png,gif
2626 _ "image/jpeg"
2727 _ "image/png"
2828 "io"
29+ "os"
30+ "path/filepath"
2931 "strings"
32+
33+ "github.com/segmentfault/pacman/log"
34+ "golang.org/x/image/webp"
3035)
3136
3237const (
@@ -35,47 +40,85 @@ const (
3540
3641// IsSupportedImageFile currently answers support image type is
3742// `image/jpeg, image/jpg, image/png, image/gif, image/webp`
38- func IsSupportedImageFile (file io.Reader , ext string ) bool {
39- ext = strings .ToLower (strings .TrimPrefix (ext , "." ))
40- var err error
43+ func IsSupportedImageFile (localFilePath string ) bool {
44+ ext := strings .ToLower (strings .TrimPrefix (filepath .Ext (localFilePath ), "." ))
4145 switch ext {
4246 case "jpg" , "jpeg" , "png" , "gif" : // only allow for `image/jpeg,image/jpg,image/png, image/gif`
43- if ! checkImageSize (file ) {
47+ if ! decodeAndCheckImageFile (localFilePath , standardImageConfigCheck ) {
48+ return false
49+ }
50+ if ! decodeAndCheckImageFile (localFilePath , standardImageCheck ) {
4451 return false
4552 }
46- _ , _ , err = image .Decode (file )
4753 case "ico" :
4854 // TODO: There is currently no good Golang library to parse whether the image is in ico format.
4955 return true
5056 case "webp" :
51- if ! checkWebpSize (file ) {
57+ if ! decodeAndCheckImageFile (localFilePath , webpImageConfigCheck ) {
58+ return false
59+ }
60+ if ! decodeAndCheckImageFile (localFilePath , webpImageCheck ) {
5261 return false
5362 }
54- _ , err = webp .Decode (file )
5563 default :
5664 return false
5765 }
58- return err == nil
66+ return true
5967}
6068
61- func checkImageSize ( file io.Reader ) bool {
62- config , _ , err := image . DecodeConfig ( file )
69+ func decodeAndCheckImageFile ( localFilePath string , checker func ( io.Reader ) error ) bool {
70+ file , err := os . Open ( localFilePath )
6371 if err != nil {
72+ log .Errorf ("open file error: %v" , err )
6473 return false
6574 }
66- if (config .Width * config .Height ) > maxImageSize {
75+ defer file .Close ()
76+
77+ if err = checker (file ); err != nil {
78+ log .Errorf ("check image format error: %v" , err )
6779 return false
6880 }
6981 return true
7082}
7183
72- func checkWebpSize (file io.Reader ) bool {
84+ func standardImageConfigCheck (file io.Reader ) error {
85+ config , _ , err := image .DecodeConfig (file )
86+ if err != nil {
87+ return fmt .Errorf ("decode image config error: %v" , err )
88+ }
89+ if imageSizeTooLarge (config ) {
90+ return fmt .Errorf ("image size too large" )
91+ }
92+ return nil
93+ }
94+
95+ func standardImageCheck (file io.Reader ) error {
96+ _ , _ , err := image .Decode (file )
97+ if err != nil {
98+ return fmt .Errorf ("decode image error: %v" , err )
99+ }
100+ return nil
101+ }
102+
103+ func webpImageConfigCheck (file io.Reader ) error {
73104 config , err := webp .DecodeConfig (file )
74105 if err != nil {
75- return false
106+ return fmt . Errorf ( "decode webp image config error: %v" , err )
76107 }
77- if (config . Width * config . Height ) > maxImageSize {
78- return false
108+ if imageSizeTooLarge (config ) {
109+ return fmt . Errorf ( "image size too large" )
79110 }
80- return true
111+ return nil
112+ }
113+
114+ func webpImageCheck (file io.Reader ) error {
115+ _ , err := webp .Decode (file )
116+ if err != nil {
117+ return fmt .Errorf ("decode webp image error: %v" , err )
118+ }
119+ return nil
120+ }
121+
122+ func imageSizeTooLarge (config image.Config ) bool {
123+ return config .Width * config .Height > maxImageSize
81124}
0 commit comments