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