webp fix v1
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/gif"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// buildGIF 生成指定帧数的动画 GIF。
|
||||
func buildGIF(t *testing.T, frames int) []byte {
|
||||
t.Helper()
|
||||
g := &gif.GIF{}
|
||||
for i := 0; i < frames; i++ {
|
||||
pal := color.Palette{color.Black, color.White}
|
||||
img := image.NewPaletted(image.Rect(0, 0, 4, 4), pal)
|
||||
if i%2 == 1 {
|
||||
for y := 0; y < 4; y++ {
|
||||
for x := 0; x < 4; x++ {
|
||||
img.SetColorIndex(x, y, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
g.Image = append(g.Image, img)
|
||||
g.Delay = append(g.Delay, 10)
|
||||
}
|
||||
var b bytes.Buffer
|
||||
if err := gif.EncodeAll(&b, g); err != nil {
|
||||
t.Fatalf("encode gif: %v", err)
|
||||
}
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
func TestGIFFrameCount(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
frames int
|
||||
}{
|
||||
{"单帧", 1},
|
||||
{"多帧", 12},
|
||||
{"恰好等于上限", maxGIFFrames},
|
||||
{"超过上限", maxGIFFrames + 1},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
data := buildGIF(t, c.frames)
|
||||
if got := gifFrameCount(data); got != c.frames {
|
||||
t.Fatalf("gifFrameCount = %d, want %d", got, c.frames)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 帧数统计必须能承受构造超大 GIF 的场景而不过度消耗内存。
|
||||
func TestGIFFrameCount_RejectsGarbage(t *testing.T) {
|
||||
cases := map[string][]byte{
|
||||
"空数据": nil,
|
||||
"非 GIF": []byte("not a gif at all, just some bytes"),
|
||||
"仅有文件头": []byte("GIF89a"),
|
||||
"截断的 LSD": []byte("GIF89a\x01\x00"),
|
||||
"截断的色表": append([]byte("GIF89a"), bytes.Repeat([]byte{0xFF}, 8)...),
|
||||
}
|
||||
for name, data := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
if n := gifFrameCount(data); n < 0 || n > 3 {
|
||||
t.Fatalf("gifFrameCount = %d, out of sane range", n)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 转换入口在帧数超限时必须返回错误(而不是把超大 GIF 丢给 cwebp)。
|
||||
// 注意本机无 cwebp 时该测试只能覆盖「帧数检查发生在 LookPath 之后」这条路径,
|
||||
// 故直接针对判定逻辑断言,不依赖外部二进制。
|
||||
func TestGIFFrameLimitConstant(t *testing.T) {
|
||||
if maxGIFFrames <= 0 {
|
||||
t.Fatalf("maxGIFFrames = %d, must be positive", maxGIFFrames)
|
||||
}
|
||||
if gifFrameCount(buildGIF(t, maxGIFFrames+1)) <= maxGIFFrames {
|
||||
t.Fatal("oversized GIF should be detected as over limit")
|
||||
}
|
||||
if gifFrameCount(buildGIF(t, 3)) > maxGIFFrames {
|
||||
t.Fatal("small GIF should not be flagged as over limit")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user