1
0
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:
DarthSim 2020-02-11 19:28:13 +06:00
parent fd2c0203b9
commit af8366139f
7 changed files with 64 additions and 10 deletions

View File

@ -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.

View File

@ -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")

View File

@ -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;

View File

@ -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.

View File

@ -90,6 +90,8 @@ func initDownloading() {
}
downloadBufPool = newBufPool("download", conf.Concurrency, conf.DownloadBufferSize)
imagemeta.SetMaxSvgCheckRead(conf.MaxSvgCheckBytes)
}
func checkDimensions(width, height int) error {

View File

@ -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
}

View File

@ -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
}