mirror of
https://github.com/imgproxy/imgproxy.git
synced 2024-11-24 08:12:38 +02:00
Better SVG detection
This commit is contained in:
parent
fd2c0203b9
commit
af8366139f
@ -7,6 +7,10 @@
|
||||
- `imgproxy health` command.
|
||||
- (pro) `IMGPROXY_GIF_OPTIMIZE_FRAMES` & `IMGPROXY_GIF_OPTIMIZE_TRANSPARENCY` configs and `gif_options` processing option.
|
||||
|
||||
### Changed
|
||||
|
||||
- Better SVG detection.
|
||||
|
||||
### Fixed
|
||||
- Fix detection of SVG starting with a comment.
|
||||
|
||||
|
@ -163,6 +163,7 @@ type config struct {
|
||||
MaxSrcResolution int
|
||||
MaxSrcFileSize int
|
||||
MaxAnimationFrames int
|
||||
MaxSvgCheckBytes int
|
||||
|
||||
JpegProgressive bool
|
||||
PngInterlaced bool
|
||||
@ -245,6 +246,7 @@ var conf = config{
|
||||
TTL: 3600,
|
||||
MaxSrcResolution: 16800000,
|
||||
MaxAnimationFrames: 1,
|
||||
MaxSvgCheckBytes: 32 * 1024,
|
||||
SignatureSize: 32,
|
||||
PngQuantizationColors: 256,
|
||||
Quality: 80,
|
||||
@ -294,6 +296,7 @@ func configure() {
|
||||
intEnvConfig(&conf.MaxSrcDimension, "IMGPROXY_MAX_SRC_DIMENSION")
|
||||
megaIntEnvConfig(&conf.MaxSrcResolution, "IMGPROXY_MAX_SRC_RESOLUTION")
|
||||
intEnvConfig(&conf.MaxSrcFileSize, "IMGPROXY_MAX_SRC_FILE_SIZE")
|
||||
intEnvConfig(&conf.MaxSvgCheckBytes, "IMGPROXY_MAX_SVG_CHECK_BYTES")
|
||||
|
||||
if _, ok := os.LookupEnv("IMGPROXY_MAX_GIF_FRAMES"); ok {
|
||||
logWarning("`IMGPROXY_MAX_GIF_FRAMES` is deprecated and will be removed in future versions. Use `IMGPROXY_MAX_ANIMATION_FRAMES` instead")
|
||||
|
@ -53,6 +53,10 @@ imgproxy can process animated images (GIF, WebP), but since this operation is pr
|
||||
|
||||
**Note:** imgproxy summarizes all frames resolutions while checking source image resolution.
|
||||
|
||||
imgproxy reads some amount of bytes to check if the source image is SVG. By default it reads maximum of 32KB, but you can change this:
|
||||
|
||||
* `IMGPROXY_MAX_SVG_CHECK_BYTES`: the maximum number of bytes imgproxy will read to recognize SVG. If imgproxy can't recognize your SVG, try to increase this number. Default: `32768` (32KB)
|
||||
|
||||
You can also specify a secret to enable authorization with the HTTP `Authorization` header for use in production environments:
|
||||
|
||||
* `IMGPROXY_SECRET`: the authorization token. If specified, the HTTP request should contain the `Authorization: Bearer %secret%` header;
|
||||
|
@ -27,6 +27,10 @@ imgproxy supports SVG sources without limitations, but SVG results are not suppo
|
||||
|
||||
When the source image is SVG and the SVG result is requested, imgproxy returns source image without modifications.
|
||||
|
||||
imgproxy reads some amount of bytes to check if the source image is SVG. By default it reads maximum of 32KB, but you can change this:
|
||||
|
||||
* `IMGPROXY_MAX_SVG_CHECK_BYTES`: the maximum number of bytes imgproxy will read to recognize SVG. If imgproxy can't recognize your SVG, try to increase this number. Default: `32768` (32KB)
|
||||
|
||||
## HEIC support
|
||||
|
||||
imgproxy supports HEIC only when using libvips 8.8.0+. Official imgproxy Docker image supports HEIC out of the box.
|
||||
|
@ -90,6 +90,8 @@ func initDownloading() {
|
||||
}
|
||||
|
||||
downloadBufPool = newBufPool("download", conf.Concurrency, conf.DownloadBufferSize)
|
||||
|
||||
imagemeta.SetMaxSvgCheckRead(conf.MaxSvgCheckBytes)
|
||||
}
|
||||
|
||||
func checkDimensions(width, height int) error {
|
||||
|
@ -88,5 +88,11 @@ func DecodeMeta(r io.Reader) (Meta, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if ok, err := IsSVG(rr); err != nil {
|
||||
return nil, err
|
||||
} else if ok {
|
||||
return &meta{format: "svg", width: 1, height: 1}, nil
|
||||
}
|
||||
|
||||
return nil, ErrFormat
|
||||
}
|
||||
|
@ -1,17 +1,48 @@
|
||||
package imagemeta
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"io"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Register fake svg decoder. Since we need this only for type detecting, we can
|
||||
// return fake image sizes
|
||||
decodeMeta := func(io.Reader) (Meta, error) {
|
||||
return &meta{format: "svg", width: 1, height: 1}, nil
|
||||
}
|
||||
RegisterFormat("<?xml ", decodeMeta)
|
||||
RegisterFormat("<svg", decodeMeta)
|
||||
// We believe that file starting with HTML comment is SVG
|
||||
RegisterFormat("<!--", decodeMeta)
|
||||
var maxSvgBytes int64 = 32 * 1024
|
||||
|
||||
type svgHeader struct {
|
||||
XMLName xml.Name
|
||||
}
|
||||
|
||||
func SetMaxSvgCheckRead(n int) {
|
||||
atomic.StoreInt64(&maxSvgBytes, int64(n))
|
||||
}
|
||||
|
||||
func IsSVG(r io.Reader) (bool, error) {
|
||||
maxBytes := int(atomic.LoadInt64(&maxSvgBytes))
|
||||
|
||||
var h svgHeader
|
||||
|
||||
buf := make([]byte, 0, maxBytes)
|
||||
b := make([]byte, 1024)
|
||||
|
||||
for {
|
||||
n, err := r.Read(b)
|
||||
if err != nil && err != io.EOF {
|
||||
return false, err
|
||||
}
|
||||
if n <= 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
buf = append(buf, b[:n]...)
|
||||
|
||||
if xml.Unmarshal(buf, &h); h.XMLName.Local == "svg" {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if len(buf) >= maxBytes {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user