Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some more error cases found by Go Fuzz #25

Merged
merged 1 commit into from
Jul 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 32 additions & 9 deletions helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import (
"encoding"
"errors"
"fmt"
"io"
"math"
"runtime"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -182,9 +184,8 @@ func (vc) convertAPEXToSeconds(ctx valueConverterContext, v any) any {
}

func (c vc) convertBytesToStringDelimBy(ctx valueConverterContext, v any, delim string) any {
bb, ok := v.([]byte)
bb, ok := typeAssert[[]byte](ctx, v)
if !ok {
ctx.warnf("expected []byte, got %T", v)
return ""
}
var buff bytes.Buffer
Expand Down Expand Up @@ -212,12 +213,12 @@ func (c vc) convertDegreesToDecimal(ctx valueConverterContext, v any) any {
}

func (vc) convertNumbersToSpaceLimited(ctx valueConverterContext, v any) any {
var sb strings.Builder
nums, ok := v.([]any)
nums, ok := typeAssert[[]any](ctx, v)
if !ok {
ctx.warnf("expected []any, got %T", v)
return ""
}

var sb strings.Builder
for i, n := range nums {
if i > 0 {
sb.WriteString(" ")
Expand All @@ -228,16 +229,19 @@ func (vc) convertNumbersToSpaceLimited(ctx valueConverterContext, v any) any {
}

func (c vc) convertBinaryData(ctx valueConverterContext, v any) any {
b := v.([]byte)
b, ok := typeAssert[[]byte](ctx, v)
if !ok {
return ""
}
return fmt.Sprintf("(Binary data %d bytes)", len(b))
}

func (c vc) convertRatsToSpaceLimited(ctx valueConverterContext, v any) any {
nums, ok := v.([]any)
nums, ok := typeAssert[[]any](ctx, v)
if !ok {
ctx.warnf("expected []any, got %T", v)
return ""
}

var sb strings.Builder
for i, n := range nums {
if i > 0 {
Expand All @@ -263,7 +267,11 @@ func (c vc) convertRatsToSpaceLimited(ctx valueConverterContext, v any) any {
}

func (vc) convertStringToInt(ctx valueConverterContext, v any) any {
s := printableString(v.(string))
s, ok := typeAssert[string](ctx, v)
if !ok {
return 0
}
s = printableString(s)
i, _ := strconv.Atoi(s)
return i
}
Expand Down Expand Up @@ -404,3 +412,18 @@ func trimBytesNulls(b []byte) []byte {
}
return b[lo : hi+1]
}

func printStackTrace(w io.Writer) {
buf := make([]byte, 1<<16)
runtime.Stack(buf, true)
fmt.Fprintf(w, "%s", buf)
}

func typeAssert[T any](ctx valueConverterContext, v any) (T, bool) {
vv, ok := v.(T)
if !ok {
ctx.warnf("expected %T, got %T", vv, v)
return vv, false
}
return vv, true
}
47 changes: 40 additions & 7 deletions imagemeta.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"
"math"
"os"
"strings"
"time"
)
Expand Down Expand Up @@ -51,12 +52,21 @@ func Decode(opts Options) (err error) {
if errp := r.(error); errp != nil {
if isInvalidFormatErrorCandidate(errp) {
err = newInvalidFormatError(errp)
} else if errp != errStop {
panic(errp)
} else {
err = errp
}
}
}

if err == ErrStopWalking {
err = nil
return
}

if err == errStop {
err = nil
}

if err == nil {
if base != nil {
err = base.streamErr()
Expand Down Expand Up @@ -153,12 +163,30 @@ func Decode(opts Options) (err error) {
dec = &imageDecoderPNG{baseStreamingDecoder: base}
}

err = dec.decode()
if err != nil {
if err == ErrStopWalking {
return nil
}
if opts.Timeout > 0 {
errc := make(chan error, 1)
go func() {
defer func() {
if r := recover(); r != nil {
if errp := r.(error); errp != nil {
errc <- errp
}
}
}()
select {
case <-time.After(opts.Timeout):
printStackTrace(os.Stderr)
errc <- fmt.Errorf("timed out after %s", opts.Timeout)
case errc <- dec.decode():
}
}()

err = <-errc

} else {
err = dec.decode()
}

return
}

Expand Down Expand Up @@ -197,6 +225,11 @@ type Options struct {

// Warnf will be called for each warning.
Warnf func(string, ...any)

// Timeout is the maximum time the decoder will spend on reading metadata.
// Mostly useful for testing.
// If set to 0, the decoder will not time out.
Timeout time.Duration
}

// TagInfo contains information about a tag.
Expand Down
3 changes: 2 additions & 1 deletion imagemeta_fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"testing"
"time"

"github.com/bep/imagemeta"
)
Expand Down Expand Up @@ -63,7 +64,7 @@ func FuzzDecodeTIFF(f *testing.F) {

func fuzzDecodeBytes(t *testing.T, imageBytes []byte, f imagemeta.ImageFormat) error {
r := bytes.NewReader(imageBytes)
err := imagemeta.Decode(imagemeta.Options{R: r, ImageFormat: f, Sources: imagemeta.EXIF | imagemeta.IPTC | imagemeta.XMP})
err := imagemeta.Decode(imagemeta.Options{R: r, ImageFormat: f, Sources: imagemeta.EXIF | imagemeta.IPTC | imagemeta.XMP, Timeout: 10 * time.Second})
if err != nil {
if !imagemeta.IsInvalidFormat(err) {
t.Fatalf("unknown error in Decode: %v %T", err, err)
Expand Down
8 changes: 8 additions & 0 deletions metadecoder_exif.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func newMetaDecoderEXIF(r io.Reader, byteOrder binary.ByteOrder, thumbnailOffset
func newMetaDecoderEXIFFromStreamReader(s *streamReader, thumbnailOffset int64, opts Options) *metaDecoderEXIF {
return &metaDecoderEXIF{
thumbnailOffset: thumbnailOffset,
seenIFDs: map[string]struct{}{},
streamReader: s,
opts: opts,
valueConverterCtx: valueConverterContext{
Expand All @@ -135,6 +136,7 @@ type exifType uint16
type metaDecoderEXIF struct {
*streamReader
thumbnailOffset int64
seenIFDs map[string]struct{}
valueConverterCtx valueConverterContext
opts Options
}
Expand Down Expand Up @@ -287,6 +289,12 @@ func (e *metaDecoderEXIF) decodeTag(namespace string) error {
}

ifd, isIFDPointer := exifIFDPointers[tagID]
if isIFDPointer {
if _, ok := e.seenIFDs[ifd]; ok {
return nil
}
e.seenIFDs[ifd] = struct{}{}
}

typ := exifType(dataType)

Expand Down
2 changes: 2 additions & 0 deletions testdata/fuzz/FuzzDecodeJPG/273e7c1d91609a4a
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xff\xed\x00\x1cPhotoshop 3.0\x008BIM\x04\x04\x00\x00\x00\x00\x00\x00\xff\xe2\fXICC_PROFILE\x00\x01\x01\x00\x00\fHLino\x02\x10\x00\x00mntrRGB XYZ \a\xce\x00\x02\x00\t\x00\x06\x001\x00\x00acspMSFT\x00\x00\x00\x00IEC sRGB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\xf6\xd6\x00\x01\x00\x00\x00\x00\xd3-HP \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11cprt\x00\x00\x01P\x00\x00\x003desc\x00\x00\x01\x84\x00\x00\x00lwtpt\x00\x00\x01\xf0\x00\x00\x00\x14bkpt\x00\x00\x02\x04\x00\x00\x00\x14rXYZ\x00\x00\x02\x18\x00\x00\x00\x14gXYZ\x00\x00\x02,\x00\x00\x00\x14bXYZ\x00\x00\x02@\x00\x00\x00\x14dmnd\x00\x00\x02T\x00\x00\x00pdmdd\x00\x00\x02\xc4\x00\x00\x00\x88vued\x00\x00\x03L\x00\x00\x00\x86view\x00\x00\x03\xd4\x00\x00\x00$lumi\x00\x00\x03\xf8\x00\x00\x00\x14meas\x00\x00\x04\f\x00\x00\x00$tech\x00\x00\x040\x00\x00\x00\frTRC\x00\x00\x04<\x00\x00\b\fgTRC\x00\x00\x04<\x00\x00\b\fbTRC\x00\x00\x04<\x00\x00\b\ftext\x00\x00\x00\x00Copyright (c) 1998 Hewlett-Packard Company\x00\x00desc\x00\x00\x00\x00\x00\x00\x00\x12sRGB IEC61966-2.1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12sRGB IEC61966-2.1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00XYZ \x00\x00\x00\x00\x00\x00\xf3Q\x00\x01\x00\x00\x00\x01\x16\xccXYZ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00XYZ \x00\x00\x00\x00\x00\x00o\xa2\x00\x008\xf5\x00\x00\x03\x90XYZ \x00\x00\x00\x00\x00\x00b\x99\x00\x00\xb7\x85\x00\x00\x18\xdaXYZ \x00\x00\x00\x00\x00\x00$\xa0\x00\x00\x0f\x84\x00\x00\xb6\xcfdesc\x00\x00\x00\x00\x00\x00\x00\x16IEC http://www.iec.ch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16IEC http://www.iec.ch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00desc\x00\x00\x00\x00\x00\x00\x00.IEC 61966-2.1 Default RGB colour space - sRGB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.IEC 61966-2.1 Default RGB colour space - sRGB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00desc\x00\x00\x00\x00\x00\x00\x00,Reference Viewing Condition in IEC61966-2.1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,Reference Viewing Condition in\xa4\x00\x00\x0061966-2.1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00view\x00\x00\x00\x00\x00\x13\xa4\xfe\x00\x14_.\x00\x10\xcf\x14\x00\x03\xed\xcc\x00\x04\x13\v\x00\x03\\\x9e\x00\x00\x00\x01XYZ \x00\x00\x00\x00\x00L\tV\x00P\x00\x00\x00W\x1f\xe7meas\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x8f\x00\x00\x00\x02sig \x00\x00\x00\x00CRT curv\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x05\x00\n\x00\x0f\x00\x14\x00\x19\x00\x1e\x00#\x00(\x00-\x002\x007\x00;\x00@\x00E\x00J\x00O\x00T\x00Y\x00^\x00c\x00h\x00m\x00r\x00w\x00|\x00\x81\x00\x86\x00\x8b\x00\x90\x00\x95\x00\x9a\x00\x9f\x00\xa4\x00\xa9\x00\xae\x00\xb2\x00\xb7\x00\xbc\x00\xc1\x00\xc6\x00\xcb\x00\xd0\x00\xd5\x00\xdb\x00\xe0\x00\xe5\x00\xeb\x00\xf0\x00\xf6\x00\xfb\x01\x01\x01\a\x01\r\x01\x13\x01\x19\x01\x1f\x01%\x01+\x012\x018\x01>\x01E\x01L\x01R\x01Y\x01`\x01g\x01n\x01u\x01|\x01\x83\x01\x8b\x01\x92\x01\x9a\x01\xa1\x01\xa9\x01\xb1\x01\xb9\x01\xc1\x01\xc9\x01\xd1\x01\xd9\x01\xe1\x01\xe9\x01\xf2\x01\xfa\x02\x03\x02\f\x02\x14\x02\x1d\x02&\x02/\x028\x02A\x02K\x02T\x02]\x02g\x02q\x02z\x02\x84\x02\x8e\x02\x98\x02\xa2\x02\xac\x02\xb6\x02\xc1\x02\xcb\x02\xd5\x02\xe0\x02\xeb\x02\xf5\x03\x00\x03\v\x03\x16\x03!\x03-\x038\x03C\x03O\x03Z\x03f\x03r\x03~\x03\x8a\x03\x96\x03\xa2\x03\xae\x03\xba\x03\xc7\x03\xd3\x03\xe0\x03\xec\x03\xf9\x04\x06\x04\x13\x04 \x04-\x04;\x04H\x04U\x04c\x04q\x04~\x04\x8c\x04\x9a\x04\xa8\x04\xb6\x04\xc4\x04\xd3\x04\xe1\x04\xf0\x04\xfe\x05\r\x05\x1c\x05+\x05:\x05I\x05X\x05g\x05w\x05\x86\x05\x96\x05\xa6\x05\xb5\x05\xc5\x05\xd5\x05\xe5\x05\xf6\x06\x06\x06\x16\x06'\x067\x06H\x06Y\x06j\x06{\x06\x8c\x06\x9d\x06\xaf\x06\xc0\x06\xd1\x06\xe3\x06\xf5\a\a\a\x19\a+\a=\aO\aa\at\a\x86\a\x99\a\xac\a\xbf\a\xd2\a\xe5\a\xf8\b\v\b\x1f\b2\bF\bZ\bn\b\x82\b\x96\b\xaa\b\xbe\b\xd2\b\xe7\b\xfb\t\x10\t%\t:\tO\td\ty\t\x8f\t\xa4\t\xba\t\xcf\t\xe5\t\xfb\n\x11\n'\n=\nT\nj\n\x81\n\x98\n\xae\n\xc5\n\xdc\n\xf3\v\v\v\"\v9\vQ\vi\v\x80\v\x98\v\xb0\v\xc8\v\xe1\v\xf9\f\x12\f*\fC\f\\\fu\f\x8e\f\xa7\f\xc0\f\xd9\f\xf3\r\r\r&\r@\rZ\rt\r\x8e\r\xa9\r\xc3\r\xde\r\xf8\x0e\x13\x0e.\x0eI\x0ed\x0e\x7f\x0e\x9b\x0e\xb6\x0e\xd2\x0e\xee\x0f\t\x0f%\x0fA\x0f^\x0fz\x0f\x96\x0f\xb3\x0f\xcf\x0f\xec\x10\t\x10&\x10C\x10a\x10~\x10\x9b\x10\xb9\x10\xd7\x10\xf5\x11\x13\x111\x11O\x11m\x11\x8c\x11\xaa\x11\xc9\x11\xe8\x12\a\x12&\x12E\x12d\x12\x84\x12\xa3\x12\xc3\x12\xe3\x13\x03\x13#\x13C\x13c\x13\x83\x13\xa4\x13\xc5\x13\xe5\x14\x06\x14'\x14I\x14j\x14\x8b\x14\xad\x14\xce\x14\xf0\x15\x12\x154\x15V\x15x\x15\x9b\x15\xbd\x15\xe0\x16\x03\x16&\x16I\x16l\x16\x8f\x16\xb2\x16\xd6\x16\xfa\x17\x1d\x17A\x17e\x17\x89\x17\xae\x17\xd2\x17\xf7\x18\x1b\x18@\x18e\x18\x8a\x18\xaf\x18\xd5\x18\xfa\x19 \x19E\x19k\x19\x91\x19\xb7\x19\xdd\x1a\x04\x1a*\x1aQ\x1aw\x1a\x9e\x1a\xc5\x1a\xec\x1b\x14\x1b;\x1bc\x1b\x8a\x1b\xb2\x1b\xda\x1c\x02\x1c*\x1cR\x1c{\x1c\xa3\x1c\xcc\x1c\xf5\x1d\x1e\x1dG\x1dp\x1d\x99\x1d\xc3\x1d\xec\x1e\x16\x1e@\x1ej\x1e\x94\x1e\xbe\x1e\xe9\x1f\x13\x1f>\x1fi\x1f\x94\x1f\xbf\x1f\xea \x15 A l \x98 \xc4 \xf0!\x1c!H!u!\xa1!\xce!\xfb\"'\"U\"\x82\"\xaf\"\xdd#\n#8#f#\x94#\xc2#\xf0$\x1f$M$|$\xab$\xda%\t%8%h%\x97%\xc7%\xf7&'&W&\x87&\xb7&\xe8'\x18'I'z'\xab'\xdc(\r(?(q(\xa2(\xd4)\x06)8)k)\x9d)\xd0*\x02*5*h*\x9b*\xcf+\x02+6+i+\x9d+\xd1,\x05,9,n,\xa2,\xd7-\f-A-v-\xab-\xe1.\x16.L.\x82.\xb7.\xee/$/Z/\x91/\xc7/\xfe050l0\xa40\xdb1\x121J1\x821\xba1\xf22*2c2\x9b2\xd43\r3F3\x7f3\xb83\xf14+4e4\x9e4\xd85\x135M5\x875\xc25\xfd676r6\xae6\xe97$7`7\x9c7\xd78\x148P8\x8c8\xc89\x059B9\x7f9\xbc9\xf9:6:t:\xb2:\xef;-;k;\xaa;\xe8<'<e<\xa4<\xe3=\"=a=\xa1=\xe0> >`>\xa0>\xe0?!?a?\xa2?\xe2@#@d@\xa6@\xe7A)AjA\xacA\xeeB0BrB\xb5B\xf7C:C}C\xc0D\x03DGD\x8aD\xceE\x12EUE\x9aE\xdeF\"FgF\xabF\xf0G5G{G\xc0H\x05HKH\x91H\xd7I\x1dIcI\xa9I\xf0J7J}J\xc4K\fKSK\x9aK\xe2L*LrL\xbaM\x02MJM\x93M\xdcN%NnN\xb7O\x00OIO\x93O\xddP'PqP\xbbQ\x06QPQ\x9bQ\xe6R1R|R\xc7S\x13S_S\xaaS\xf6TBT\x8fT\xdbU(UuU\xc2V\x0fV\\V\xa9V\xf7WDW\x92W\xe0X/X}X\xcbY\x1aYiY\xb8Z\aZVZ\xa6Z\xf5[E[\x95[\xe5\\5\\\x86\\\xd6]']x]\xc9^\x1a^l^\xbd_\x0f_a_\xb3`\x05`W`\xaa`\xfcaOa\xa2a\xf5bIb\x9cb\xf0cCc\x97c\xebd@d\x94d\xe9e=e\x92e\xe7f=f\x92f\xe8g=g\x93g\xe9h?h\x96h\xeciCi\x9ai\xf1jHj\x9fj\xf7kOk\xa7k\xfflWl\xafm\bm`m\xb9n\x12nkn\xc4o\x1eoxo\xd1p+p\x86p\xe0q:q\x95q\xf0rKr\xa6s\x01s]s\xb8t\x14tpt\xccu(u\x85u\xe1v>v\x9bv\xf8wVw\xb3x\x11xnx\xccy*y\x89y\xe7zFz\xa5{\x04{c{\xc2|!|\x81|\xe1}A}\xa1~\x01~b~\xc2\x7f#\x7f\x84\x7f\xe5\x80G\x80\xa8\x81\n\x81k\x81͂0\x82\x92\x82\xf4\x83W\x83\xba\x84\x1d\x84\x80\x84\xe3\x85G\x85\xab\x86\x0e\x86r\x86ׇ;\x87\x9f\x88\x04\x88i\x88Ή3\x89\x99\x89\xfe\x8ad\x8aʋ0\x8b\x96\x8b\xfc\x8cc\x8cʍ1\x8d\x98\x8d\xff\x8ef\x8eΏ6\x8f\x9e\x90\x06\x90n\x90֑?\x91\xa8\x92\x11\x92z\x92\xe3\x93M\x93\xb6\x94 \x94\x8a\x94\xf4\x95_\x95ɖ4\x96\x9f\x97\n\x97u\x97\xe0\x98L\x98\xb8\x99$\x99\x90\x99\xfc\x9ah\x9a՛B\x9b\xaf\x9c\x1c\x9c\x89\x9c\xf7\x9dd\x9dҞ@\x9e\xae\x9f\x1d\x9f\x8b\x9f\xfa\xa0i\xa0ءG\xa1\xb6\xa2&\xa2\x96\xa3\x06\xa3v\xa3\xe6\xa4V\xa4ǥ8\xa5\xa9\xa6\x1a\xa6\x8b\xa6\xfd\xa7n\xa7\xe0\xa8R\xa8ĩ7\xa9\xa9\xaa\x1c\xaa\x8f\xab\x02\xabu\xab\xe9\xac\\\xacЭD\xad\xb8\xae-\xae\xa1\xaf\x16\xaf\x8b\xb0\x00\xb0u\xb0\xea\xb1`\xb1ֲK\xb2³8\xb3\xae\xb4%\xb4\x9c\xb5\x13\xb5\x8a\xb6\x01\xb6y\xb6\xf0\xb7h\xb7\xe0\xb8Y\xb8ѹJ\xb9º;\xba\xb5\xbb.\xbb\xa7\xbc!\xbc\x9b\xbd\x15\xbd\x8f\xbe\n\xbe\x84\xbe\xff\xbfz\xbf\xf5\xc0p\xc0\xec\xc1g\xc1\xe3\xc2_\xc2\xdb\xc3X\xc3\xd4\xc4Q\xc4\xce\xc5K\xc5\xc8\xc6F\xc6\xc3\xc7Aǿ\xc8=ȼ\xc9:ɹ\xca8ʷ\xcb6˶\xcc5̵\xcd5͵\xce6ζ\xcf7ϸ\xd09к\xd1<Ѿ\xd2?\xd2\xc1\xd3D\xd3\xc6\xd4I\xd4\xcb\xd5N\xd5\xd1\xd6U\xd6\xd8\xd7\\\xd7\xe0\xd8d\xd8\xe8\xd9l\xd9\xf1\xdav\xda\xfbۀ\xdc\x05܊\xdd\x10ݖ\xde\x1cޢ\xdf)߯\xe06\xe0\xbd\xe1D\xe1\xcc\xe2S\xe2\xdb\xe3c\xe3\xeb\xe4s\xe4\xfc\xe5\x84\xe6\r\xe6\x96\xe7\x1f\xe7\xa9\xe82\xe8\xbc\xe9F\xe9\xd0\xea[\xea\xe5\xebp\xeb\xfb\xec\x86\xed\x11\xed\x9c\xee(\xee\xb4\xef@\xef\xcc\xf0X\xf0\xe5\xf1r\xf1\xff\xf2\x8c\xf3\x19\xf3\xa7\xf44\xf4\xc2\xf5P\xf5\xde\xf6m\xf6\xfb\xf7\x8a\xf8\x19\xf8\xa8\xf98\xf9\xc7\xfaW\xfa\xe7\xfbw\xfc\a\xfc\x98\xfd)\xfd\xba\xfeK\xfe\xdc\xffm\xff\xff\xff\xe1\x00\xd6Exif\x00\x00MM\x00*\x00\x00\x00\b\x00\b\x01\x12\x00\x03\x00\x00\x00\x01\x00\x01\x00\x00\x01\x1a\x00\x05\x00\x00\x00\x01\x00\x00\x00b\x01\x1b\x00\x05\x00\x00\x00\x01\x00\x00\x00j\x01(\x00\x03\x00\x00\x00\x01\x00\x02\x00\x00\x011\x00\x02\x00\x00\x00\x1e\x00\x00\x00r\x012\x00\x02\x00\x00\x00\x14\x00\x00\x00\x90\x87i\x00\x04\x00\x00\x00\x01\x00\x00\x00 IEC\x00\x00\x00\x00H\x00\x00\x00\x01\x00\x00\x00H\x00\x00\x00\x01Adobe Photoshop CS2 Macintosh\x002007:05:10 19:04:16\x00\x00\x03\xa0\x01\x00\x03\x00\x00\x00\x01\x00\x01\x00\x00\xa0\x02\x00\x04\x00\x00\x00\x01\x00\x00\x02\xbb\xa0\x03\x00\x04\x00\x00\x00\x01\x00\x00\x02\xbe\x00\x00\x00\x00\xff\xdb\x00C\x00\b\x06\x06\a\x06\x05\b\a\a\a\t\t\b\n\f\x14\r\f\v\v\f\x19\x12\x13\x0f\x14\x1d\x1a\x1f\x1e\x1d\x1a\x1c\x1c $.' \",#\x1c\x1c(7),01444\x1f'9=82<.342\xff\xdb\x00C\x01\t\t\t\f\v\f\x18\r\r\x182!\x1c!22222222222222222222222222222222222222222222222222\xff\xc0\x00\x11\b\x00\b\x00\b\x03\x01\"\x00\x02\x11\x01\x03\x11\x01\xff\xc4\x00\x15\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\xff\xc4\x00\x1f\x10\x00\x01\x04\x02\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x03\x11\x04!\x05\x06\x12\x13a\xff\xc4\x00\x14\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xff\xc4\x00\x18\x11\x00\x03\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x11\x02\x03\xff\xda\x00\f\x03\x01\x00\x02\x11\x03\x11\x00?\x00\xbc\x9f\xb2K\xc8;\xd0\xfe7?\x1f6\x19LF\x18\x88\xf1u\xec\x10\xf3\xa3\xa1u\xf6\x91\x11\x06\xba4\"\x90\xff\xd9")
2 changes: 2 additions & 0 deletions testdata/fuzz/FuzzDecodeJPG/773dee179fd633e0

Large diffs are not rendered by default.

Loading