Home | History | Annotate | Download | only in libfuzzer
      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 
     19 class 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