mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-09-16 09:36:18 +02:00
Better SVG detection
This commit is contained in:
@@ -7,6 +7,10 @@
|
|||||||
- `imgproxy health` command.
|
- `imgproxy health` command.
|
||||||
- (pro) `IMGPROXY_GIF_OPTIMIZE_FRAMES` & `IMGPROXY_GIF_OPTIMIZE_TRANSPARENCY` configs and `gif_options` processing option.
|
- (pro) `IMGPROXY_GIF_OPTIMIZE_FRAMES` & `IMGPROXY_GIF_OPTIMIZE_TRANSPARENCY` configs and `gif_options` processing option.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Better SVG detection.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Fix detection of SVG starting with a comment.
|
- Fix detection of SVG starting with a comment.
|
||||||
|
|
||||||
|
@@ -163,6 +163,7 @@ type config struct {
|
|||||||
MaxSrcResolution int
|
MaxSrcResolution int
|
||||||
MaxSrcFileSize int
|
MaxSrcFileSize int
|
||||||
MaxAnimationFrames int
|
MaxAnimationFrames int
|
||||||
|
MaxSvgCheckBytes int
|
||||||
|
|
||||||
JpegProgressive bool
|
JpegProgressive bool
|
||||||
PngInterlaced bool
|
PngInterlaced bool
|
||||||
@@ -245,6 +246,7 @@ var conf = config{
|
|||||||
TTL: 3600,
|
TTL: 3600,
|
||||||
MaxSrcResolution: 16800000,
|
MaxSrcResolution: 16800000,
|
||||||
MaxAnimationFrames: 1,
|
MaxAnimationFrames: 1,
|
||||||
|
MaxSvgCheckBytes: 32 * 1024,
|
||||||
SignatureSize: 32,
|
SignatureSize: 32,
|
||||||
PngQuantizationColors: 256,
|
PngQuantizationColors: 256,
|
||||||
Quality: 80,
|
Quality: 80,
|
||||||
@@ -294,6 +296,7 @@ func configure() {
|
|||||||
intEnvConfig(&conf.MaxSrcDimension, "IMGPROXY_MAX_SRC_DIMENSION")
|
intEnvConfig(&conf.MaxSrcDimension, "IMGPROXY_MAX_SRC_DIMENSION")
|
||||||
megaIntEnvConfig(&conf.MaxSrcResolution, "IMGPROXY_MAX_SRC_RESOLUTION")
|
megaIntEnvConfig(&conf.MaxSrcResolution, "IMGPROXY_MAX_SRC_RESOLUTION")
|
||||||
intEnvConfig(&conf.MaxSrcFileSize, "IMGPROXY_MAX_SRC_FILE_SIZE")
|
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 {
|
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")
|
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.
|
**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:
|
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;
|
* `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.
|
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
|
## HEIC support
|
||||||
|
|
||||||
imgproxy supports HEIC only when using libvips 8.8.0+. Official imgproxy Docker image supports HEIC out of the box.
|
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)
|
downloadBufPool = newBufPool("download", conf.Concurrency, conf.DownloadBufferSize)
|
||||||
|
|
||||||
|
imagemeta.SetMaxSvgCheckRead(conf.MaxSvgCheckBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkDimensions(width, height int) error {
|
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
|
return nil, ErrFormat
|
||||||
}
|
}
|
||||||
|
@@ -1,17 +1,48 @@
|
|||||||
package imagemeta
|
package imagemeta
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/xml"
|
||||||
"io"
|
"io"
|
||||||
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
var maxSvgBytes int64 = 32 * 1024
|
||||||
// Register fake svg decoder. Since we need this only for type detecting, we can
|
|
||||||
// return fake image sizes
|
type svgHeader struct {
|
||||||
decodeMeta := func(io.Reader) (Meta, error) {
|
XMLName xml.Name
|
||||||
return &meta{format: "svg", width: 1, height: 1}, nil
|
}
|
||||||
}
|
|
||||||
RegisterFormat("<?xml ", decodeMeta)
|
func SetMaxSvgCheckRead(n int) {
|
||||||
RegisterFormat("<svg", decodeMeta)
|
atomic.StoreInt64(&maxSvgBytes, int64(n))
|
||||||
// We believe that file starting with HTML comment is SVG
|
}
|
||||||
RegisterFormat("<!--", decodeMeta)
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user