From 4085ee9340373b806a74654ff46586cc6d99d096 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Sat, 20 Dec 2025 15:03:10 +0100 Subject: [PATCH] Handle PNG named *.webp Fixes #14288 --- resources/images/codec.go | 22 ++++++++++++++++++++-- tpl/images/images_integration_test.go | 23 +++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/resources/images/codec.go b/resources/images/codec.go index 2bd93b579..7fe1ccf5b 100644 --- a/resources/images/codec.go +++ b/resources/images/codec.go @@ -132,7 +132,7 @@ func (d *Codec) EncodeTo(conf ImageConfig, w io.Writer, img image.Image) error { func (d *Codec) DecodeFormat(f Format, r io.Reader) (image.Image, error) { switch f { case JPEG, PNG: - // TODO(bep) we reworked this decode/encode setup to get full WebP support in v0.153.0. + // We reworked this decode/encode setup to get full WebP support in v0.153.0. // In the first take of that we used f to decide whether to call png.Decode or jpeg.Decode here, // but testing it on some sites, it seems that it's not uncommon to store JPEGs with PNG extensions and vice versa. // So, to reduce some noise in that release, we fallback to the standard library here, @@ -153,7 +153,25 @@ func (d *Codec) DecodeFormat(f Format, r io.Reader) (image.Image, error) { case BMP: return bmp.Decode(r) case WEBP: - return d.webp.Decode(r) + img, err := d.webp.Decode(r) + if err == nil { + return img, nil + } + if rs, ok := r.(io.ReadSeeker); ok { + // See issue 14288. Turns out it's not uncommon to e.g. name their PNG files with a WEBP extension. + // With the old Go's webp decoder, this didn't fail (it looked for the file header), + // but now some error has surfaced. + // To reduce some noise, we try to reset and decode again using the standard library. + _, err2 := rs.Seek(0, io.SeekStart) + if err2 != nil { + return nil, err + } + img, _, err2 = image.Decode(rs) + if err2 == nil { + return img, nil + } + } + return nil, err default: return nil, errors.New("format not supported") } diff --git a/tpl/images/images_integration_test.go b/tpl/images/images_integration_test.go index c6226f611..b8edb22f3 100644 --- a/tpl/images/images_integration_test.go +++ b/tpl/images/images_integration_test.go @@ -165,3 +165,26 @@ Brightnes method: /qr_hu_d5f06fd7594d0594.png Brightnes func: /qr_hu_d5f06fd7594d0594.png `) } + +func TestPNGNamedWebpIssue14288(t *testing.T) { + t.Parallel() + + files := ` +-- assets/qr.webp -- +sourcefilename: testdata/images_golden/funcs/qr-level-high_scale-6.png +-- layouts/home.html -- +{{ $img := resources.Get "qr.webp" }} +images.Config: {{ (images.Config "assets/qr.webp").Width }} +Resize to 100x100: {{ ($img.Resize "100x100" ).Width }} +Brightnes method: {{ ($img.Filter (images.Brightness 12) ).RelPermalink }} +Brightnes func: {{ ($img | images.Filter (images.Brightness 12) ).RelPermalink }} +` + + b := hugolib.Test(t, files) + b.AssertFileContent("public/index.html", ` +images.Config: 222 +Resize to 100x100: 100 +Brightnes method: /qr_hu_d5f06fd7594d0594.webp +Brightnes func: /qr_hu_d5f06fd7594d0594.webp +`) +} -- 2.39.5