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_FUZZERS_XFA_CODEC_FUZZER_H_ 6 #define TESTING_FUZZERS_XFA_CODEC_FUZZER_H_ 7 8 #include <memory> 9 10 #include "core/fxcodec/fx_codec.h" 11 #include "core/fxcodec/progressivedecoder.h" 12 #include "core/fxcrt/cfx_readonlymemorystream.h" 13 #include "core/fxge/dib/cfx_dibitmap.h" 14 #include "third_party/base/ptr_util.h" 15 #include "third_party/base/span.h" 16 17 // Support up to 64 MB. This prevents trivial OOM when MSAN is on and 18 // time outs. 19 const int kXFACodecFuzzerPixelLimit = 64000000; 20 21 class XFACodecFuzzer { 22 public: Fuzz(const uint8_t * data,size_t size,FXCODEC_IMAGE_TYPE type)23 static int Fuzz(const uint8_t* data, size_t size, FXCODEC_IMAGE_TYPE type) { 24 auto* mgr = fxcodec::ModuleMgr::GetInstance(); 25 std::unique_ptr<ProgressiveDecoder> decoder = 26 mgr->CreateProgressiveDecoder(); 27 auto source = pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>( 28 pdfium::make_span(data, size)); 29 CFX_DIBAttribute attr; 30 FXCODEC_STATUS status = decoder->LoadImageInfo(source, type, &attr, true); 31 if (status != FXCODEC_STATUS_FRAME_READY) 32 return 0; 33 34 // Skipping very large images, since they will take a long time and may lead 35 // to OOM. 36 FX_SAFE_UINT32 bitmap_size = decoder->GetHeight(); 37 bitmap_size *= decoder->GetWidth(); 38 bitmap_size *= 4; // From CFX_DIBitmap impl. 39 if (!bitmap_size.IsValid() || 40 bitmap_size.ValueOrDie() > kXFACodecFuzzerPixelLimit) { 41 return 0; 42 } 43 44 auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>(); 45 bitmap->Create(decoder->GetWidth(), decoder->GetHeight(), FXDIB_Argb); 46 47 size_t frames; 48 std::tie(status, frames) = decoder->GetFrames(); 49 if (status != FXCODEC_STATUS_DECODE_READY || frames == 0) 50 return 0; 51 52 status = decoder->StartDecode(bitmap, 0, 0, bitmap->GetWidth(), 53 bitmap->GetHeight()); 54 while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) 55 status = decoder->ContinueDecode(); 56 57 return 0; 58 } 59 }; 60 61 #endif // TESTING_FUZZERS_XFA_CODEC_FUZZER_H_ 62