20
20
package checker
21
21
22
22
import (
23
- "golang.org/x/image/webp "
23
+ "fmt "
24
24
"image"
25
25
_ "image/gif" // use init to support decode jpeg,jpg,png,gif
26
26
_ "image/jpeg"
27
27
_ "image/png"
28
28
"io"
29
+ "os"
30
+ "path/filepath"
29
31
"strings"
32
+
33
+ "github.com/segmentfault/pacman/log"
34
+ "golang.org/x/image/webp"
30
35
)
31
36
32
37
const (
@@ -35,47 +40,85 @@ const (
35
40
36
41
// IsSupportedImageFile currently answers support image type is
37
42
// `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 ), "." ))
41
45
switch ext {
42
46
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 ) {
44
51
return false
45
52
}
46
- _ , _ , err = image .Decode (file )
47
53
case "ico" :
48
54
// TODO: There is currently no good Golang library to parse whether the image is in ico format.
49
55
return true
50
56
case "webp" :
51
- if ! checkWebpSize (file ) {
57
+ if ! decodeAndCheckImageFile (localFilePath , webpImageConfigCheck ) {
58
+ return false
59
+ }
60
+ if ! decodeAndCheckImageFile (localFilePath , webpImageCheck ) {
52
61
return false
53
62
}
54
- _ , err = webp .Decode (file )
55
63
default :
56
64
return false
57
65
}
58
- return err == nil
66
+ return true
59
67
}
60
68
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 )
63
71
if err != nil {
72
+ log .Errorf ("open file error: %v" , err )
64
73
return false
65
74
}
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 )
67
79
return false
68
80
}
69
81
return true
70
82
}
71
83
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 {
73
104
config , err := webp .DecodeConfig (file )
74
105
if err != nil {
75
- return false
106
+ return fmt . Errorf ( "decode webp image config error: %v" , err )
76
107
}
77
- if (config . Width * config . Height ) > maxImageSize {
78
- return false
108
+ if imageSizeTooLarge (config ) {
109
+ return fmt . Errorf ( "image size too large" )
79
110
}
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
81
124
}
0 commit comments