Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/image/test/fuzzing/TestDecoders.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "gtest/gtest.h"
7
8
#include "Common.h"
9
#include "imgIContainer.h"
10
#include "imgITools.h"
11
#include "ImageOps.h"
12
#include "mozilla/gfx/2D.h"
13
#include "nsComponentManagerUtils.h"
14
#include "nsCOMPtr.h"
15
#include "nsIInputStream.h"
16
#include "nsIRunnable.h"
17
#include "nsIStringStream.h"
18
#include "nsIThread.h"
19
#include "mozilla/RefPtr.h"
20
#include "nsString.h"
21
#include "nsThreadUtils.h"
22
23
#include "FuzzingInterfaceStream.h"
24
25
using namespace mozilla;
26
using namespace mozilla::gfx;
27
using namespace mozilla::image;
28
29
static std::string mimeType = "";
30
31
// Prevents x being optimized away if it has no side-effects.
32
// If optimized away, tools like ASan wouldn't be able to detect
33
// faulty memory accesses.
34
0
#define DUMMY_IF(x) if (x) { volatile int v; v=0; }
35
36
class DecodeToSurfaceRunnableFuzzing : public Runnable
37
{
38
public:
39
  DecodeToSurfaceRunnableFuzzing(RefPtr<SourceSurface>& aSurface,
40
                          nsIInputStream* aInputStream)
41
    : mozilla::Runnable("DecodeToSurfaceRunnableFuzzing")
42
    , mSurface(aSurface)
43
    , mInputStream(aInputStream)
44
0
  { }
45
46
  NS_IMETHOD Run() override
47
0
  {
48
0
    Go();
49
0
    return NS_OK;
50
0
  }
51
52
  void Go()
53
0
  {
54
0
    mSurface =
55
0
      ImageOps::DecodeToSurface(mInputStream.forget(),
56
0
                                nsDependentCString(mimeType.c_str()),
57
0
                                imgIContainer::DECODE_FLAGS_DEFAULT);
58
0
    if (!mSurface)
59
0
      return;
60
0
61
0
    if (mSurface->GetType() == SurfaceType::DATA) {
62
0
      if (mSurface->GetFormat() == SurfaceFormat::B8G8R8X8 ||
63
0
          mSurface->GetFormat() == SurfaceFormat::B8G8R8A8) {
64
0
        DUMMY_IF(IntSize(1,1) == mSurface->GetSize());
65
0
        DUMMY_IF(IsSolidColor(mSurface, BGRAColor::Green(), 1));
66
0
      }
67
0
    }
68
0
  }
69
70
private:
71
  RefPtr<SourceSurface>& mSurface;
72
  nsCOMPtr<nsIInputStream> mInputStream;
73
};
74
75
static int
76
RunDecodeToSurfaceFuzzing(nsCOMPtr<nsIInputStream> inputStream)
77
0
{
78
0
  uint64_t len;
79
0
  inputStream->Available(&len);
80
0
  if (len <= 0) {
81
0
      return 0;
82
0
  }
83
0
84
0
  nsCOMPtr<nsIThread> thread;
85
0
  nsresult rv = NS_NewThread(getter_AddRefs(thread), nullptr);
86
0
  MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
87
0
88
0
  // We run the DecodeToSurface tests off-main-thread to ensure that
89
0
  // DecodeToSurface doesn't require any main-thread-only code.
90
0
  RefPtr<SourceSurface> surface;
91
0
  nsCOMPtr<nsIRunnable> runnable =
92
0
    new DecodeToSurfaceRunnableFuzzing(surface, inputStream);
93
0
  thread->Dispatch(runnable, nsIThread::DISPATCH_SYNC);
94
0
95
0
  thread->Shutdown();
96
0
97
0
  // Explicitly release the SourceSurface on the main thread.
98
0
  surface = nullptr;
99
0
100
0
  return 0;
101
0
}
102
103
0
int FuzzingInitImage(int *argc, char ***argv) {
104
0
    nsCOMPtr<imgITools> imgTools =
105
0
      do_CreateInstance("@mozilla.org/image/tools;1");
106
0
    if (imgTools == nullptr) {
107
0
      std::cerr << "Initializing image tools failed" << std::endl;
108
0
      return 1;
109
0
    }
110
0
111
0
    char* mimeTypePtr = getenv("MOZ_FUZZ_IMG_MIMETYPE");
112
0
    if (!mimeTypePtr) {
113
0
      std::cerr << "Must specify mime-type in MOZ_FUZZ_IMG_MIMETYPE environment variable." << std::endl;
114
0
      return 1;
115
0
    }
116
0
117
0
    mimeType = std::string(mimeTypePtr);
118
0
    int ret = strncmp(mimeType.c_str(), "image/", strlen("image/"));
119
0
120
0
    if (ret) {
121
0
      std::cerr << "MOZ_FUZZ_IMG_MIMETYPE should start with 'image/', e.g. 'image/gif'. Return: " << ret << std::endl;
122
0
      return 1;
123
0
    }
124
0
    return 0;
125
0
}
126
127
MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzing, Image);