From f5e3b3cb8a05a39b68c6556d42be488a8a983467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Sun, 21 Jul 2024 17:36:03 +0200 Subject: [PATCH] One more fuzz error fix --- imagedecoder_png.go | 7 ++++++- imagemeta.go | 16 ++++++++++++++-- metadecoder_exif.go | 2 +- testdata/fuzz/FuzzDecodePNG/419ad6feeb3d533e | 2 ++ 4 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 testdata/fuzz/FuzzDecodePNG/419ad6feeb3d533e diff --git a/imagedecoder_png.go b/imagedecoder_png.go index fcbd89c..ec65c39 100644 --- a/imagedecoder_png.go +++ b/imagedecoder_png.go @@ -61,10 +61,15 @@ func (e *imageDecoderPNG) decode() error { if sources.Has(IPTC) { sources = sources.Remove(IPTC) + dataLen := int(chunkLength) - int(profileNameLength) + if dataLen < 0 { + return newInvalidFormatErrorf("invalid data length %d", dataLen) + } + // TODO(bep) According to the spec, this should always return Latin-1 encoded text. // The image editors out there does not seem to care much about this. // See https://github.com/bep/imagemeta/issues/19 - data, err := decompressZTXt(e.readBytesVolatile(int(chunkLength) - int(profileNameLength))) + data, err := decompressZTXt(e.readBytesVolatile(dataLen)) if err != nil { return newInvalidFormatError(fmt.Errorf("decompressing zTXt: %w", err)) } diff --git a/imagemeta.go b/imagemeta.go index 002f74f..8845f24 100644 --- a/imagemeta.go +++ b/imagemeta.go @@ -49,12 +49,18 @@ func Decode(opts Options) (err error) { defer func() { if r := recover(); r != nil { - if errp := r.(error); errp != nil { + if errp, ok := r.(error); ok { if isInvalidFormatErrorCandidate(errp) { err = newInvalidFormatError(errp) } else { err = errp + if err != errStop { + printStackTrace(os.Stderr) + } } + } else { + err = fmt.Errorf("unknown panic: %v", r) + printStackTrace(os.Stderr) } } @@ -168,8 +174,14 @@ func Decode(opts Options) (err error) { go func() { defer func() { if r := recover(); r != nil { - if errp := r.(error); errp != nil { + if errp, ok := r.(error); ok { + if errp != errStop { + printStackTrace(os.Stderr) + } errc <- errp + } else { + errc <- fmt.Errorf("unknown panic: %v", r) + printStackTrace(os.Stderr) } } }() diff --git a/metadecoder_exif.go b/metadecoder_exif.go index f75815f..0a8ffb9 100644 --- a/metadecoder_exif.go +++ b/metadecoder_exif.go @@ -300,7 +300,7 @@ func (e *metaDecoderEXIF) decodeTag(namespace string) error { size, ok := exifTypeSize[typ] if !ok { - return fmt.Errorf("%w: unknown EXIF type %d", errInvalidFormat, typ) + return newInvalidFormatErrorf("unknown EXIF type %d", typ) } valLen := size * count diff --git a/testdata/fuzz/FuzzDecodePNG/419ad6feeb3d533e b/testdata/fuzz/FuzzDecodePNG/419ad6feeb3d533e new file mode 100644 index 0000000..b2ff9b7 --- /dev/null +++ b/testdata/fuzz/FuzzDecodePNG/419ad6feeb3d533e @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("00000000\x00\x00\x00\x10zTXtRaw profile type iptc\x00")