fix(thumb): max pixel dimensions constraint in builtin thumb generator

master
Aaron Liu 4 days ago
parent 7e1289d552
commit 3607f79bb4

@ -1,6 +1,7 @@
package thumb
import (
"bytes"
"context"
"fmt"
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/manager/entitysource"
@ -19,6 +20,12 @@ import (
const thumbTempFolder = "thumb"
// maxDecodePixels caps the decoded pixel count to prevent pixel-bomb DoS:
// stdlib decoders allocate bytesPerPixel*W*H from the header before reading
// pixel data, so a tiny file with huge dimensions can otherwise OOM-kill the
// process. 64 MP covers any realistic camera output.
const maxDecodePixels = 64 * 1000 * 1000
// BuiltinSupportedExts lists file extensions supported by the built-in
// thumbnail generator. Extensions are lowercased and do not include the dot.
var BuiltinSupportedExts = []string{"jpg", "jpeg", "png", "gif"}
@ -37,7 +44,18 @@ func NewThumbFromFile(file io.Reader, ext string) (*Thumb, error) {
return nil, fmt.Errorf("unknown image format: %w", ErrPassThrough)
}
var err error
var hdr bytes.Buffer
cfg, _, err := image.DecodeConfig(io.TeeReader(file, &hdr))
if err != nil {
return nil, fmt.Errorf("failed to read image config: %w (%w)", err, ErrPassThrough)
}
if cfg.Width <= 0 || cfg.Height <= 0 ||
int64(cfg.Width)*int64(cfg.Height) > maxDecodePixels {
return nil, fmt.Errorf("image dimensions too large (%dx%d): %w",
cfg.Width, cfg.Height, ErrPassThrough)
}
file = io.MultiReader(&hdr, file)
var img image.Image
switch ext {
case "jpg", "jpeg":

Loading…
Cancel
Save