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/fxcrt/fx_stream.h" 17#include "third_party/base/ptr_util.h" 18 19class XFACodecFuzzer { 20 public: 21 static int Fuzz(const uint8_t* data, size_t size, FXCODEC_IMAGE_TYPE type) { 22 auto mgr = pdfium::MakeUnique<CCodec_ModuleMgr>(); 23 mgr->SetBmpModule(pdfium::MakeUnique<CCodec_BmpModule>()); 24 mgr->SetGifModule(pdfium::MakeUnique<CCodec_GifModule>()); 25 mgr->SetPngModule(pdfium::MakeUnique<CCodec_PngModule>()); 26 mgr->SetTiffModule(pdfium::MakeUnique<CCodec_TiffModule>()); 27 28 std::unique_ptr<CCodec_ProgressiveDecoder> decoder = 29 mgr->CreateProgressiveDecoder(); 30 CFX_RetainPtr<Reader> source(new Reader(data, size)); 31 FXCODEC_STATUS status = decoder->LoadImageInfo(source, type, nullptr, true); 32 if (status != FXCODEC_STATUS_FRAME_READY) 33 return 0; 34 35 std::unique_ptr<CFX_DIBitmap> bitmap(new CFX_DIBitmap); 36 bitmap->Create(decoder->GetWidth(), decoder->GetHeight(), FXDIB_Argb); 37 38 int32_t frames; 39 if (decoder->GetFrames(frames) != FXCODEC_STATUS_DECODE_READY || 40 frames == 0) 41 return 0; 42 43 status = decoder->StartDecode(bitmap.get(), 0, 0, bitmap->GetWidth(), 44 bitmap->GetHeight()); 45 while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) 46 status = decoder->ContinueDecode(); 47 48 return 0; 49 } 50 51 private: 52 class Reader : public IFX_SeekableReadStream { 53 public: 54 Reader(const uint8_t* data, size_t size) : m_data(data), m_size(size) {} 55 ~Reader() {} 56 57 bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override { 58 if (offset < 0 || static_cast<size_t>(offset) >= m_size) 59 return false; 60 if (offset + size > m_size) 61 size = m_size - offset; 62 if (size == 0) 63 return false; 64 65 memcpy(buffer, m_data + offset, size); 66 return true; 67 } 68 69 FX_FILESIZE GetSize() override { return static_cast<FX_FILESIZE>(m_size); } 70 71 private: 72 const uint8_t* const m_data; 73 size_t m_size; 74 }; 75}; 76 77#endif // TESTING_LIBFUZZER_XFA_CODEC_FUZZER_H_ 78