1 // Copyright 2016 The PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef TESTING_LIBFUZZER_XFA_CODEC_FUZZER_H_ 6 #define TESTING_LIBFUZZER_XFA_CODEC_FUZZER_H_ 7 8 #include <memory> 9 10 #include "core/fxcodec/codec/ccodec_bmpmodule.h" 11 #include "core/fxcodec/codec/ccodec_gifmodule.h" 12 #include "core/fxcodec/codec/ccodec_pngmodule.h" 13 #include "core/fxcodec/codec/ccodec_progressivedecoder.h" 14 #include "core/fxcodec/codec/ccodec_tiffmodule.h" 15 #include "core/fxcodec/fx_codec.h" 16 #include "core/fxge/dib/cfx_dibitmap.h" 17 #include "testing/fx_string_testhelpers.h" 18 #include "third_party/base/ptr_util.h" 19 20 // Support up to 64 MB. This prevents trivial OOM when MSAN is on and 21 // time outs. 22 const int kXFACodecFuzzerPixelLimit = 64000000; 23 24 class XFACodecFuzzer { 25 public: Fuzz(const uint8_t * data,size_t size,FXCODEC_IMAGE_TYPE type)26 static int Fuzz(const uint8_t* data, size_t size, FXCODEC_IMAGE_TYPE type) { 27 auto mgr = pdfium::MakeUnique<CCodec_ModuleMgr>(); 28 mgr->SetBmpModule(pdfium::MakeUnique<CCodec_BmpModule>()); 29 mgr->SetGifModule(pdfium::MakeUnique<CCodec_GifModule>()); 30 mgr->SetPngModule(pdfium::MakeUnique<CCodec_PngModule>()); 31 mgr->SetTiffModule(pdfium::MakeUnique<CCodec_TiffModule>()); 32 33 std::unique_ptr<CCodec_ProgressiveDecoder> decoder = 34 mgr->CreateProgressiveDecoder(); 35 auto source = pdfium::MakeRetain<CFX_BufferSeekableReadStream>(data, size); 36 FXCODEC_STATUS status = decoder->LoadImageInfo(source, type, nullptr, true); 37 if (status != FXCODEC_STATUS_FRAME_READY) 38 return 0; 39 40 // Skipping very large images, since they will take a long time and may lead 41 // to OOM. 42 FX_SAFE_UINT32 bitmap_size = decoder->GetHeight(); 43 bitmap_size *= decoder->GetWidth(); 44 bitmap_size *= 4; // From CFX_DIBitmap impl. 45 if (!bitmap_size.IsValid() || 46 bitmap_size.ValueOrDie() > kXFACodecFuzzerPixelLimit) { 47 return 0; 48 } 49 50 auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>(); 51 bitmap->Create(decoder->GetWidth(), decoder->GetHeight(), FXDIB_Argb); 52 53 size_t frames; 54 std::tie(status, frames) = decoder->GetFrames(); 55 if (status != FXCODEC_STATUS_DECODE_READY || frames == 0) 56 return 0; 57 58 status = decoder->StartDecode(bitmap, 0, 0, bitmap->GetWidth(), 59 bitmap->GetHeight()); 60 while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) 61 status = decoder->ContinueDecode(); 62 63 return 0; 64 } 65 }; 66 67 #endif // TESTING_LIBFUZZER_XFA_CODEC_FUZZER_H_ 68