From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- image/test/fuzzing/TestDecoders.cpp | 180 ++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 image/test/fuzzing/TestDecoders.cpp (limited to 'image/test/fuzzing/TestDecoders.cpp') diff --git a/image/test/fuzzing/TestDecoders.cpp b/image/test/fuzzing/TestDecoders.cpp new file mode 100644 index 0000000000..8515ff43c6 --- /dev/null +++ b/image/test/fuzzing/TestDecoders.cpp @@ -0,0 +1,180 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" + +#include "Common.h" +#include "imgIContainer.h" +#include "imgITools.h" +#include "ImageOps.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/Preferences.h" +#include "nsComponentManagerUtils.h" +#include "nsCOMPtr.h" +#include "nsIInputStream.h" +#include "nsIRunnable.h" +#include "nsIThread.h" +#include "mozilla/RefPtr.h" +#include "nsString.h" +#include "nsThreadUtils.h" + +#include "FuzzingInterfaceStream.h" + +using namespace mozilla; +using namespace mozilla::gfx; +using namespace mozilla::image; + +// Prevents x being optimized away if it has no side-effects. +// If optimized away, tools like ASan wouldn't be able to detect +// faulty memory accesses. +#define DUMMY_IF(x) \ + if (x) { \ + volatile int v; \ + v = 0; \ + (void)v; \ + } + +class DecodeToSurfaceRunnableFuzzing : public Runnable { + public: + DecodeToSurfaceRunnableFuzzing(RefPtr& aSurface, + nsIInputStream* aInputStream, + const char* mimeType) + : mozilla::Runnable("DecodeToSurfaceRunnableFuzzing"), + mSurface(aSurface), + mInputStream(aInputStream), + mMimeType(mimeType) {} + + NS_IMETHOD Run() override { + Go(); + return NS_OK; + } + + void Go() { + mSurface = ImageOps::DecodeToSurface(mInputStream.forget(), mMimeType, + imgIContainer::DECODE_FLAGS_DEFAULT); + if (!mSurface) return; + + if (mSurface->GetType() == SurfaceType::DATA) { + if (mSurface->GetFormat() == SurfaceFormat::OS_RGBX || + mSurface->GetFormat() == SurfaceFormat::OS_RGBA) { + DUMMY_IF(IntSize(1, 1) == mSurface->GetSize()); + DUMMY_IF(IsSolidColor(mSurface, BGRAColor::Green(), 1)); + } + } + } + + private: + RefPtr& mSurface; + nsCOMPtr mInputStream; + nsAutoCString mMimeType; +}; + +static int RunDecodeToSurfaceFuzzing(nsCOMPtr inputStream, + const char* mimeType) { + uint64_t len; + inputStream->Available(&len); + if (len <= 0) { + return 0; + } + + // Ensure CMS state is initialized on the main thread. + gfxPlatform::GetCMSMode(); + + nsCOMPtr thread; + nsresult rv = + NS_NewNamedThread("Decoder Test", getter_AddRefs(thread), nullptr); + MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv)); + + // We run the DecodeToSurface tests off-main-thread to ensure that + // DecodeToSurface doesn't require any other main-thread-only code. + RefPtr surface; + nsCOMPtr runnable = + new DecodeToSurfaceRunnableFuzzing(surface, inputStream, mimeType); + NS_DispatchAndSpinEventLoopUntilComplete("RunDecodeToSurfaceFuzzing"_ns, + thread, runnable.forget()); + + thread->Shutdown(); + + // Explicitly release the SourceSurface on the main thread. + surface = nullptr; + + return 0; +} + +static int RunDecodeToSurfaceFuzzingJPEG(nsCOMPtr inputStream) { + return RunDecodeToSurfaceFuzzing(inputStream, "image/jpeg"); +} + +static int RunDecodeToSurfaceFuzzingGIF(nsCOMPtr inputStream) { + return RunDecodeToSurfaceFuzzing(inputStream, "image/gif"); +} + +static int RunDecodeToSurfaceFuzzingICO(nsCOMPtr inputStream) { + return RunDecodeToSurfaceFuzzing(inputStream, "image/ico"); +} + +static int RunDecodeToSurfaceFuzzingBMP(nsCOMPtr inputStream) { + return RunDecodeToSurfaceFuzzing(inputStream, "image/bmp"); +} + +static int RunDecodeToSurfaceFuzzingPNG(nsCOMPtr inputStream) { + return RunDecodeToSurfaceFuzzing(inputStream, "image/png"); +} + +static int RunDecodeToSurfaceFuzzingWebP(nsCOMPtr inputStream) { + return RunDecodeToSurfaceFuzzing(inputStream, "image/webp"); +} + +static int RunDecodeToSurfaceFuzzingAVIF(nsCOMPtr inputStream) { + return RunDecodeToSurfaceFuzzing(inputStream, "image/avif"); +} + +#ifdef MOZ_JXL +static int RunDecodeToSurfaceFuzzingJXL(nsCOMPtr inputStream) { + return RunDecodeToSurfaceFuzzing(inputStream, "image/jxl"); +} +#endif + +int FuzzingInitImage(int* argc, char*** argv) { + Preferences::SetBool("image.avif.sequence.enabled", true); +#ifdef MOZ_JXL + Preferences::SetBool("image.jxl.enabled", true); +#endif + + nsCOMPtr imgTools = + do_CreateInstance("@mozilla.org/image/tools;1"); + if (imgTools == nullptr) { + std::cerr << "Initializing image tools failed" << std::endl; + return 1; + } + + return 0; +} + +MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingJPEG, + ImageJPEG); + +MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingGIF, + ImageGIF); + +MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingICO, + ImageICO); + +MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingBMP, + ImageBMP); + +MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingPNG, + ImagePNG); + +MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingWebP, + ImageWebP); + +MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingAVIF, + ImageAVIF); + +#ifdef MOZ_JXL +MOZ_FUZZING_INTERFACE_STREAM(FuzzingInitImage, RunDecodeToSurfaceFuzzingJXL, + ImageJXL); +#endif -- cgit v1.2.3