• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

cshum / imagor / 15329455260

29 May 2025 05:16PM UTC coverage: 92.386%. First build
15329455260

push

github

cshum
feat(vips): unlimited option and check resolution before export

17 of 21 new or added lines in 3 files covered. (80.95%)

4902 of 5306 relevant lines covered (92.39%)

1.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.91
/processor/vipsprocessor/fallback.go
1
package vipsprocessor
2

3
import (
4
        "github.com/cshum/imagor"
5
        "github.com/cshum/vipsgen/vips"
6
        "golang.org/x/image/bmp"
7
        "image"
8
        "image/draw"
9
        "io"
10
)
11

12
// FallbackFunc vips.Image fallback handler when vips.NewImageFromSource failed
13
type FallbackFunc func(blob *imagor.Blob, options *vips.LoadOptions) (*vips.Image, error)
14

15
// bufferFallbackFunc load image from buffer FallbackFunc
NEW
16
func bufferFallbackFunc(blob *imagor.Blob, options *vips.LoadOptions) (*vips.Image, error) {
×
17
        buf, err := blob.ReadAll()
×
18
        if err != nil {
×
19
                return nil, err
×
20
        }
×
21
        return vips.NewImageFromBuffer(buf, options)
×
22
}
23

24
func estimateMaxBMPFileSize(maxResolution int64) int64 {
1✔
25
        const (
1✔
26
                bmpHeaderSize = 54
1✔
27
                bytesPerPixel = 4   // 32-bit RGBA (worst case)
1✔
28
                safetyMargin  = 1.2 // 20% buffer
1✔
29
        )
1✔
30
        return int64(float64(bmpHeaderSize+maxResolution*bytesPerPixel) * safetyMargin)
1✔
31
}
1✔
32

33
func (v *Processor) loadImageFromBMP(r io.Reader) (*vips.Image, error) {
1✔
34
        img, err := bmp.Decode(r)
1✔
35
        if err != nil {
1✔
36
                return nil, err
×
37
        }
×
38
        rect := img.Bounds()
1✔
39
        size := rect.Size()
1✔
40
        if !v.Unlimited && (size.X > v.MaxWidth || size.Y > v.MaxHeight || size.X*size.Y > v.MaxResolution) {
1✔
NEW
41
                return nil, imagor.ErrMaxResolutionExceeded
×
NEW
42
        }
×
43
        rgba, ok := img.(*image.RGBA)
1✔
44
        if !ok {
2✔
45
                rgba = image.NewRGBA(rect)
1✔
46
                draw.Draw(rgba, rect, img, rect.Min, draw.Src)
1✔
47
        }
1✔
48
        return vips.NewImageFromMemory(rgba.Pix, size.X, size.Y, 4)
1✔
49
}
50

51
func (v *Processor) bmpFallbackFunc(blob *imagor.Blob, _ *vips.LoadOptions) (*vips.Image, error) {
1✔
52
        if blob.BlobType() == imagor.BlobTypeBMP {
2✔
53
                if blob.Size() > estimateMaxBMPFileSize(int64(v.MaxResolution)) {
2✔
54
                        return nil, imagor.ErrMaxResolutionExceeded
1✔
55
                }
1✔
56
                r, _, err := blob.NewReader()
1✔
57
                if err != nil {
1✔
58
                        return nil, err
×
59
                }
×
60
                defer func() {
2✔
61
                        _ = r.Close()
1✔
62
                }()
1✔
63
                return v.loadImageFromBMP(r)
1✔
64
        } else {
1✔
65
                return nil, imagor.ErrUnsupportedFormat
1✔
66
        }
1✔
67
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc