• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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