Test that an SVG served as AVIF is refused, and that each source format loads
check / check (push) Waiting to run
check / check (push) Waiting to run
An SVG starting with an XML comment holding "ftypavis" passes the first-bytes check for AVIF; resized as PNG, it is answered 200 with the SVG rendered. The new server test asks for it through both image routes, resized and as orig, and wants 415 for each. The new processor test checks that an image in each of the six source formats loads and is saved again in its own format. Model: opus-5-5
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
package imageprocessor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestImageProcessor_LoadsEachSourceFormat verifies that an image in each of
|
||||
// the six source formats, saved by the processor itself, is loaded and saved
|
||||
// again in its own format (orig).
|
||||
func TestImageProcessor_LoadsEachSourceFormat(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
proc := New(Params{})
|
||||
|
||||
for _, format := range []Format{
|
||||
FormatJPEG, FormatPNG, FormatGIF, FormatWebP, FormatAVIF, FormatJXL,
|
||||
} {
|
||||
saved, err := proc.Process(t.Context(),
|
||||
bytes.NewReader(createTestPNG(t, 20, 20)), &Request{Format: format})
|
||||
if err != nil {
|
||||
t.Fatalf("saving the test image as %s: %v", format, err)
|
||||
}
|
||||
|
||||
source, err := io.ReadAll(saved.Content)
|
||||
if err != nil {
|
||||
t.Fatalf("reading the %s image: %v", format, err)
|
||||
}
|
||||
|
||||
result, err := proc.Process(t.Context(), bytes.NewReader(source),
|
||||
&Request{Format: FormatOriginal})
|
||||
if err != nil {
|
||||
t.Errorf("orig of the %s image: %v", format, err)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
t.Logf("orig of the %s image: %s", format, result.ContentType)
|
||||
|
||||
if result.ContentType != FormatToMIME(format) {
|
||||
t.Errorf("orig of the %s image is %s, want %s",
|
||||
format, result.ContentType, FormatToMIME(format))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"sneak.berlin/go/pixa/internal/encurl"
|
||||
"sneak.berlin/go/pixa/internal/imgcache"
|
||||
)
|
||||
|
||||
// svgServedAsAVIF is an SVG whose first bytes pass the first-bytes check for
|
||||
// AVIF: its XML comment puts "ftypavis" at bytes 4 to 11, where an AVIF file
|
||||
// has its ftyp box and brand. libvips would load it as SVG.
|
||||
const svgServedAsAVIF = `<!--ftypavis--><svg xmlns="http://www.w3.org/2000/svg" ` +
|
||||
`width="64" height="48"><rect width="64" height="48"/></svg>`
|
||||
|
||||
// TestImageProxyRefusesSVGServedAsAVIF requests svgServedAsAVIF, which the
|
||||
// upstream answers as image/avif, through both image routes, resized as PNG
|
||||
// and in its own format (orig). Each request is answered 415, as for an SVG
|
||||
// source, never with an image.
|
||||
func TestImageProxyRefusesSVGServedAsAVIF(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
upstream := httptest.NewServer(http.HandlerFunc(
|
||||
func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "image/avif")
|
||||
_, _ = io.WriteString(w, svgServedAsAVIF)
|
||||
}))
|
||||
t.Cleanup(upstream.Close)
|
||||
|
||||
s, _, _ := startImageProxy(t, upstream)
|
||||
|
||||
generator, err := encurl.NewGenerator(testSigningKey)
|
||||
if err != nil {
|
||||
t.Fatalf("encurl.NewGenerator: %v", err)
|
||||
}
|
||||
|
||||
targets := []string{
|
||||
"/v1/image/" + upstreamHost + "/drawing.avif/32x24.png",
|
||||
"/v1/image/" + upstreamHost + "/drawing.avif/64x48.orig",
|
||||
}
|
||||
|
||||
for _, format := range []imgcache.ImageFormat{
|
||||
imgcache.FormatPNG, imgcache.FormatOriginal,
|
||||
} {
|
||||
token, err := generator.Generate(&encurl.Payload{
|
||||
SourceHost: upstreamHost, SourcePath: "/drawing.avif",
|
||||
Width: 32, Height: 24, Format: format,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("encurl Generate: %v", err)
|
||||
}
|
||||
|
||||
targets = append(targets, "/v1/e/"+token+"/drawing."+string(format))
|
||||
}
|
||||
|
||||
for _, target := range targets {
|
||||
rec := httptest.NewRecorder()
|
||||
s.ServeHTTP(rec, httptest.NewRequestWithContext(
|
||||
t.Context(), http.MethodGet, target, nil))
|
||||
t.Logf("GET %s: %d, Content-Type %s, body %q",
|
||||
target, rec.Code, rec.Header().Get("Content-Type"), rec.Body.String())
|
||||
|
||||
if rec.Code != http.StatusUnsupportedMediaType ||
|
||||
!strings.Contains(rec.Body.String(), "unsupported source format") {
|
||||
t.Errorf("GET %s: %d %q, want %d unsupported source format",
|
||||
target, rec.Code, rec.Body.String(), http.StatusUnsupportedMediaType)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user