From 2aa4a82499d4becd2284cdb482213d541b8804dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 16:29:10 +0200 Subject: Adding upstream version 86.0.1. Signed-off-by: Daniel Baumann --- image/test/fuzzing/TestDecoders.cpp | 161 ++++++++++++++++++++++++++++++++++++ image/test/fuzzing/moz.build | 24 ++++++ 2 files changed, 185 insertions(+) create mode 100644 image/test/fuzzing/TestDecoders.cpp create mode 100644 image/test/fuzzing/moz.build (limited to 'image/test/fuzzing') diff --git a/image/test/fuzzing/TestDecoders.cpp b/image/test/fuzzing/TestDecoders.cpp new file mode 100644 index 0000000000..97e37cf6a0 --- /dev/null +++ b/image/test/fuzzing/TestDecoders.cpp @@ -0,0 +1,161 @@ +/* -*- 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; \ + } + +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; + } + + 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 main-thread-only code. + RefPtr surface; + nsCOMPtr runnable = + new DecodeToSurfaceRunnableFuzzing(surface, inputStream, mimeType); + thread->Dispatch(runnable, nsIThread::DISPATCH_SYNC); + + 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"); +} + +int FuzzingInitImage(int* argc, char*** argv) { + Preferences::SetBool("image.avif.enabled", true); + + 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); diff --git a/image/test/fuzzing/moz.build b/image/test/fuzzing/moz.build new file mode 100644 index 0000000000..24af56396f --- /dev/null +++ b/image/test/fuzzing/moz.build @@ -0,0 +1,24 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +Library("FuzzingImage") + +SOURCES += [ + "TestDecoders.cpp", +] + +FINAL_LIBRARY = "xul-gtest" + +include("/ipc/chromium/chromium-config.mozbuild") + +LOCAL_INCLUDES += [ + "/dom/base", + "/gfx/2d", + "/image", + "/image/test/gtest", +] + +LOCAL_INCLUDES += CONFIG["SKIA_INCLUDES"] -- cgit v1.2.3