diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /tools/fuzzing/interface | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tools/fuzzing/interface')
-rw-r--r-- | tools/fuzzing/interface/FuzzingInterface.cpp | 30 | ||||
-rw-r--r-- | tools/fuzzing/interface/FuzzingInterface.h | 115 | ||||
-rw-r--r-- | tools/fuzzing/interface/FuzzingInterfaceStream.cpp | 54 | ||||
-rw-r--r-- | tools/fuzzing/interface/FuzzingInterfaceStream.h | 90 | ||||
-rw-r--r-- | tools/fuzzing/interface/harness/FuzzerRunner.cpp | 91 | ||||
-rw-r--r-- | tools/fuzzing/interface/harness/FuzzerRunner.h | 24 | ||||
-rw-r--r-- | tools/fuzzing/interface/harness/FuzzerTestHarness.h | 256 | ||||
-rw-r--r-- | tools/fuzzing/interface/harness/moz.build | 16 | ||||
-rw-r--r-- | tools/fuzzing/interface/moz.build | 32 |
9 files changed, 708 insertions, 0 deletions
diff --git a/tools/fuzzing/interface/FuzzingInterface.cpp b/tools/fuzzing/interface/FuzzingInterface.cpp new file mode 100644 index 0000000000..f06ca68656 --- /dev/null +++ b/tools/fuzzing/interface/FuzzingInterface.cpp @@ -0,0 +1,30 @@ +/* -*- 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/. */ + +/* + * Common code for the unified fuzzing interface + */ + +#include <stdarg.h> +#include <stdlib.h> +#include "FuzzingInterface.h" + +namespace mozilla { + +#ifdef JS_STANDALONE +static bool fuzzing_verbose = !!getenv("MOZ_FUZZ_LOG"); +void fuzzing_log(const char* aFmt, ...) { + if (fuzzing_verbose) { + va_list ap; + va_start(ap, aFmt); + vfprintf(stderr, aFmt, ap); + va_end(ap); + } +} +#else +LazyLogModule gFuzzingLog("nsFuzzing"); +#endif + +} // namespace mozilla diff --git a/tools/fuzzing/interface/FuzzingInterface.h b/tools/fuzzing/interface/FuzzingInterface.h new file mode 100644 index 0000000000..792f0809ec --- /dev/null +++ b/tools/fuzzing/interface/FuzzingInterface.h @@ -0,0 +1,115 @@ +/* -*- 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/. */ + +/* + * Interface definitions for the unified fuzzing interface + */ + +#ifndef FuzzingInterface_h__ +#define FuzzingInterface_h__ + +#include <fstream> + +#ifdef LIBFUZZER +# include "FuzzerExtFunctions.h" +#endif + +#include "FuzzerRegistry.h" +#include "mozilla/Assertions.h" + +#ifndef JS_STANDALONE +# include "mozilla/Logging.h" +#endif + +namespace mozilla { + +#ifdef JS_STANDALONE +void fuzzing_log(const char* aFmt, ...); +# define MOZ_LOG_EXPAND_ARGS(...) __VA_ARGS__ + +# define FUZZING_LOG(args) fuzzing_log(MOZ_LOG_EXPAND_ARGS args); +#else +extern LazyLogModule gFuzzingLog; + +# define FUZZING_LOG(args) \ + MOZ_LOG(mozilla::gFuzzingLog, mozilla::LogLevel::Verbose, args) +#endif // JS_STANDALONE + +typedef int (*FuzzingTestFuncRaw)(const uint8_t*, size_t); + +#ifdef AFLFUZZ + +static int afl_interface_raw(const char* testFile, + FuzzingTestFuncRaw testFunc) { + char* buf = NULL; + + while (__AFL_LOOP(1000)) { + std::ifstream is; + is.open(testFile, std::ios::binary); + is.seekg(0, std::ios::end); + int len = is.tellg(); + is.seekg(0, std::ios::beg); + MOZ_RELEASE_ASSERT(len >= 0); + if (!len) { + is.close(); + continue; + } + buf = (char*)realloc(buf, len); + MOZ_RELEASE_ASSERT(buf); + is.read(buf, len); + is.close(); + testFunc((uint8_t*)buf, (size_t)len); + } + + free(buf); + + return 0; +} + +# define MOZ_AFL_INTERFACE_COMMON() \ + char* testFilePtr = getenv("MOZ_FUZZ_TESTFILE"); \ + if (!testFilePtr) { \ + fprintf(stderr, \ + "Must specify testfile in MOZ_FUZZ_TESTFILE environment " \ + "variable.\n"); \ + return 1; \ + } \ + /* Make a copy of testFilePtr so the testing function can safely call \ + * getenv \ + */ \ + std::string testFile(testFilePtr); + +# define MOZ_AFL_INTERFACE_RAW(initFunc, testFunc, moduleName) \ + static int afl_fuzz_##moduleName(const uint8_t* data, size_t size) { \ + MOZ_RELEASE_ASSERT(data == NULL && size == 0); \ + MOZ_AFL_INTERFACE_COMMON(); \ + return ::mozilla::afl_interface_raw(testFile.c_str(), testFunc); \ + } \ + static void __attribute__((constructor)) AFLRegister##moduleName() { \ + ::mozilla::FuzzerRegistry::getInstance().registerModule( \ + #moduleName, initFunc, afl_fuzz_##moduleName); \ + } +#else +# define MOZ_AFL_INTERFACE_RAW(initFunc, testFunc, moduleName) /* Nothing */ +#endif // AFLFUZZ + +#ifdef LIBFUZZER +# define MOZ_LIBFUZZER_INTERFACE_RAW(initFunc, testFunc, moduleName) \ + static void __attribute__((constructor)) LibFuzzerRegister##moduleName() { \ + ::mozilla::FuzzerRegistry::getInstance().registerModule( \ + #moduleName, initFunc, testFunc); \ + } +#else +# define MOZ_LIBFUZZER_INTERFACE_RAW(initFunc, testFunc, \ + moduleName) /* Nothing */ +#endif + +#define MOZ_FUZZING_INTERFACE_RAW(initFunc, testFunc, moduleName) \ + MOZ_LIBFUZZER_INTERFACE_RAW(initFunc, testFunc, moduleName); \ + MOZ_AFL_INTERFACE_RAW(initFunc, testFunc, moduleName); + +} // namespace mozilla + +#endif // FuzzingInterface_h__ diff --git a/tools/fuzzing/interface/FuzzingInterfaceStream.cpp b/tools/fuzzing/interface/FuzzingInterfaceStream.cpp new file mode 100644 index 0000000000..f2c5c891e9 --- /dev/null +++ b/tools/fuzzing/interface/FuzzingInterfaceStream.cpp @@ -0,0 +1,54 @@ +/* -*- 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/. */ + +/* + * Interface implementation for the unified fuzzing interface + */ + +#include "nsIFile.h" +#include "nsIPrefService.h" +#include "nsIProperties.h" + +#include "FuzzingInterfaceStream.h" + +#include "mozilla/Assertions.h" + +#ifndef JS_STANDALONE +# include "nsNetUtil.h" +#endif + +namespace mozilla { + +#ifdef AFLFUZZ + +void afl_interface_stream(const char* testFile, + FuzzingTestFuncStream testFunc) { + nsresult rv; + nsCOMPtr<nsIProperties> dirService = + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID); + MOZ_RELEASE_ASSERT(dirService != nullptr); + nsCOMPtr<nsIFile> file; + rv = dirService->Get(NS_OS_CURRENT_WORKING_DIR, NS_GET_IID(nsIFile), + getter_AddRefs(file)); + MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv)); + file->AppendNative(nsDependentCString(testFile)); + while (__AFL_LOOP(1000)) { + nsCOMPtr<nsIInputStream> inputStream; + rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), file); + MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv)); + if (!NS_InputStreamIsBuffered(inputStream)) { + nsCOMPtr<nsIInputStream> bufStream; + rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream), + inputStream.forget(), 1024); + MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv)); + inputStream = bufStream; + } + testFunc(inputStream.forget()); + } +} + +#endif + +} // namespace mozilla diff --git a/tools/fuzzing/interface/FuzzingInterfaceStream.h b/tools/fuzzing/interface/FuzzingInterfaceStream.h new file mode 100644 index 0000000000..1542020794 --- /dev/null +++ b/tools/fuzzing/interface/FuzzingInterfaceStream.h @@ -0,0 +1,90 @@ +/* -*- 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/. */ + +/* + * Interface definitions for the unified fuzzing interface with streaming + * support + */ + +#ifndef FuzzingInterfaceStream_h__ +#define FuzzingInterfaceStream_h__ + +#ifdef JS_STANDALONE +# error "FuzzingInterfaceStream.h cannot be used in JS standalone builds." +#endif + +#include "gtest/gtest.h" +#include "nsComponentManagerUtils.h" +#include "nsCOMPtr.h" +#include "nsIInputStream.h" + +#include "nsDirectoryServiceDefs.h" +#include "nsStreamUtils.h" +#include "nsStringStream.h" + +#include <fstream> + +#include "FuzzingInterface.h" + +namespace mozilla { + +typedef int (*FuzzingTestFuncStream)(nsCOMPtr<nsIInputStream>); + +#ifdef AFLFUZZ +void afl_interface_stream(const char* testFile, FuzzingTestFuncStream testFunc); + +# define MOZ_AFL_INTERFACE_COMMON(initFunc) \ + if (initFunc) initFunc(NULL, NULL); \ + char* testFilePtr = getenv("MOZ_FUZZ_TESTFILE"); \ + if (!testFilePtr) { \ + fprintf(stderr, \ + "Must specify testfile in MOZ_FUZZ_TESTFILE environment " \ + "variable.\n"); \ + return; \ + } \ + /* Make a copy of testFilePtr so the testing function can safely call \ + * getenv \ + */ \ + std::string testFile(testFilePtr); + +# define MOZ_AFL_INTERFACE_STREAM(initFunc, testFunc, moduleName) \ + TEST(AFL, moduleName) \ + { \ + MOZ_AFL_INTERFACE_COMMON(initFunc); \ + ::mozilla::afl_interface_stream(testFile.c_str(), testFunc); \ + } +#else +# define MOZ_AFL_INTERFACE_STREAM(initFunc, testFunc, moduleName) /* Nothing \ + */ +#endif + +#ifdef LIBFUZZER +# define MOZ_LIBFUZZER_INTERFACE_STREAM(initFunc, testFunc, moduleName) \ + static int LibFuzzerTest##moduleName(const uint8_t* data, size_t size) { \ + if (size > INT32_MAX) return 0; \ + nsCOMPtr<nsIInputStream> stream; \ + nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), \ + Span((const char*)data, size), \ + NS_ASSIGNMENT_DEPEND); \ + MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv)); \ + testFunc(stream.forget()); \ + return 0; \ + } \ + static void __attribute__((constructor)) LibFuzzerRegister##moduleName() { \ + ::mozilla::FuzzerRegistry::getInstance().registerModule( \ + #moduleName, initFunc, LibFuzzerTest##moduleName); \ + } +#else +# define MOZ_LIBFUZZER_INTERFACE_STREAM(initFunc, testFunc, \ + moduleName) /* Nothing */ +#endif + +#define MOZ_FUZZING_INTERFACE_STREAM(initFunc, testFunc, moduleName) \ + MOZ_LIBFUZZER_INTERFACE_STREAM(initFunc, testFunc, moduleName); \ + MOZ_AFL_INTERFACE_STREAM(initFunc, testFunc, moduleName); + +} // namespace mozilla + +#endif // FuzzingInterfaceStream_h__ diff --git a/tools/fuzzing/interface/harness/FuzzerRunner.cpp b/tools/fuzzing/interface/harness/FuzzerRunner.cpp new file mode 100644 index 0000000000..fc2094aa59 --- /dev/null +++ b/tools/fuzzing/interface/harness/FuzzerRunner.cpp @@ -0,0 +1,91 @@ +/* -*- 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 <cstdlib> + +#include "FuzzerRunner.h" +#include "mozilla/Attributes.h" +#include "prenv.h" + +#include "FuzzerTestHarness.h" + +namespace mozilla { + +// We use a static var 'fuzzerRunner' defined in nsAppRunner.cpp. +// fuzzerRunner is initialized to nullptr but if this file is linked in, +// then fuzzerRunner will be set here indicating that +// we want to call into either LibFuzzer's main or the AFL entrypoint. +class _InitFuzzer { + public: + _InitFuzzer() { fuzzerRunner = new FuzzerRunner(); } + void InitXPCOM() { mScopedXPCOM = new ScopedXPCOM("Fuzzer"); } + void DeinitXPCOM() { + if (mScopedXPCOM) delete mScopedXPCOM; + mScopedXPCOM = nullptr; + } + + private: + ScopedXPCOM* mScopedXPCOM; +} InitLibFuzzer; + +static void DeinitXPCOM() { InitLibFuzzer.DeinitXPCOM(); } + +int FuzzerRunner::Run(int* argc, char*** argv) { + /* + * libFuzzer uses exit() calls in several places instead of returning, + * so the destructor of ScopedXPCOM is not called in some cases. + * For fuzzing, this does not make a difference, but in debug builds + * when running a single testcase, this causes an assertion when destroying + * global linked lists. For this reason, we allocate ScopedXPCOM on the heap + * using the global InitLibFuzzer class, combined with an atexit call to + * destroy the ScopedXPCOM instance again. + */ + InitLibFuzzer.InitXPCOM(); + std::atexit(DeinitXPCOM); + + const char* fuzzerEnv = getenv("FUZZER"); + + if (!fuzzerEnv) { + fprintf(stderr, + "Must specify fuzzing target in FUZZER environment variable\n"); + exit(1); + } + + std::string moduleNameStr(fuzzerEnv); + FuzzerFunctions funcs = + FuzzerRegistry::getInstance().getModuleFunctions(moduleNameStr); + FuzzerInitFunc initFunc = funcs.first; + FuzzerTestingFunc testingFunc = funcs.second; + if (initFunc) { + int ret = initFunc(argc, argv); + if (ret) { + fprintf(stderr, "Fuzzing Interface: Error: Initialize callback failed\n"); + exit(1); + } + } + + if (!testingFunc) { + fprintf(stderr, "Fuzzing Interface: Error: No testing callback found\n"); + exit(1); + } + +#ifdef LIBFUZZER + int ret = mFuzzerDriver(argc, argv, testingFunc); +#else + // For AFL, testingFunc points to the entry function we need. + int ret = testingFunc(NULL, 0); +#endif + + InitLibFuzzer.DeinitXPCOM(); + return ret; +} + +#ifdef LIBFUZZER +void FuzzerRunner::setParams(LibFuzzerDriver aDriver) { + mFuzzerDriver = aDriver; +} +#endif + +} // namespace mozilla diff --git a/tools/fuzzing/interface/harness/FuzzerRunner.h b/tools/fuzzing/interface/harness/FuzzerRunner.h new file mode 100644 index 0000000000..6b19e751cd --- /dev/null +++ b/tools/fuzzing/interface/harness/FuzzerRunner.h @@ -0,0 +1,24 @@ +/* -*- 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 "FuzzerRegistry.h" + +namespace mozilla { + +class FuzzerRunner { + public: + int Run(int* argc, char*** argv); + +#ifdef LIBFUZZER + void setParams(LibFuzzerDriver aDriver); + + private: + LibFuzzerDriver mFuzzerDriver; +#endif +}; + +extern FuzzerRunner* fuzzerRunner; + +} // namespace mozilla diff --git a/tools/fuzzing/interface/harness/FuzzerTestHarness.h b/tools/fuzzing/interface/harness/FuzzerTestHarness.h new file mode 100644 index 0000000000..d7bb1064cf --- /dev/null +++ b/tools/fuzzing/interface/harness/FuzzerTestHarness.h @@ -0,0 +1,256 @@ +/* -*- 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/. */ + +/* + * Test harness for XPCOM objects, providing a scoped XPCOM initializer, + * nsCOMPtr, nsRefPtr, do_CreateInstance, do_GetService, ns(Auto|C|)String, + * and stdio.h/stdlib.h. + */ + +#ifndef FuzzerTestHarness_h__ +#define FuzzerTestHarness_h__ + +#include "mozilla/ArrayUtils.h" +#include "mozilla/Attributes.h" + +#include "prenv.h" +#include "nsComponentManagerUtils.h" +#include "nsServiceManagerUtils.h" +#include "nsCOMPtr.h" +#include "nsString.h" +#include "nsAppDirectoryServiceDefs.h" +#include "nsDirectoryServiceDefs.h" +#include "nsDirectoryServiceUtils.h" +#include "nsIDirectoryService.h" +#include "nsIFile.h" +#include "nsIObserverService.h" +#include "nsIServiceManager.h" +#include "nsXULAppAPI.h" +#include "mozilla/AppShutdown.h" +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> + +namespace { + +static uint32_t gFailCount = 0; + +/** + * Prints the given failure message and arguments using printf, prepending + * "TEST-UNEXPECTED-FAIL " for the benefit of the test harness and + * appending "\n" to eliminate having to type it at each call site. + */ +MOZ_FORMAT_PRINTF(1, 2) void fail(const char* msg, ...) { + va_list ap; + + printf("TEST-UNEXPECTED-FAIL | "); + + va_start(ap, msg); + vprintf(msg, ap); + va_end(ap); + + putchar('\n'); + ++gFailCount; +} + +//----------------------------------------------------------------------------- + +class ScopedXPCOM final : public nsIDirectoryServiceProvider2 { + public: + NS_DECL_ISUPPORTS + + explicit ScopedXPCOM(const char* testName, + nsIDirectoryServiceProvider* dirSvcProvider = nullptr) + : mDirSvcProvider(dirSvcProvider) { + mTestName = testName; + printf("Running %s tests...\n", mTestName); + + nsresult rv = NS_InitXPCOM(&mServMgr, nullptr, this); + if (NS_FAILED(rv)) { + fail("NS_InitXPCOM returned failure code 0x%" PRIx32, + static_cast<uint32_t>(rv)); + mServMgr = nullptr; + return; + } + } + + ~ScopedXPCOM() { + // If we created a profile directory, we need to remove it. + if (mProfD) { + mozilla::AppShutdown::AdvanceShutdownPhase( + mozilla::ShutdownPhase::AppShutdownNetTeardown); + mozilla::AppShutdown::AdvanceShutdownPhase( + mozilla::ShutdownPhase::AppShutdownTeardown); + mozilla::AppShutdown::AdvanceShutdownPhase( + mozilla::ShutdownPhase::AppShutdown); + mozilla::AppShutdown::AdvanceShutdownPhase( + mozilla::ShutdownPhase::AppShutdownQM); + mozilla::AppShutdown::AdvanceShutdownPhase( + mozilla::ShutdownPhase::AppShutdownTelemetry); + + if (NS_FAILED(mProfD->Remove(true))) { + NS_WARNING("Problem removing profile directory"); + } + + mProfD = nullptr; + } + + if (mServMgr) { + NS_RELEASE(mServMgr); + nsresult rv = NS_ShutdownXPCOM(nullptr); + if (NS_FAILED(rv)) { + fail("XPCOM shutdown failed with code 0x%" PRIx32, + static_cast<uint32_t>(rv)); + exit(1); + } + } + + printf("Finished running %s tests.\n", mTestName); + } + + already_AddRefed<nsIFile> GetProfileDirectory() { + if (mProfD) { + nsCOMPtr<nsIFile> copy = mProfD; + return copy.forget(); + } + + // Create a unique temporary folder to use for this test. + // Note that runcppunittests.py will run tests with a temp + // directory as the cwd, so just put something under that. + nsCOMPtr<nsIFile> profD; + nsresult rv = NS_GetSpecialDirectory(NS_OS_CURRENT_PROCESS_DIR, + getter_AddRefs(profD)); + NS_ENSURE_SUCCESS(rv, nullptr); + + rv = profD->Append(u"cpp-unit-profd"_ns); + NS_ENSURE_SUCCESS(rv, nullptr); + + rv = profD->CreateUnique(nsIFile::DIRECTORY_TYPE, 0755); + NS_ENSURE_SUCCESS(rv, nullptr); + + mProfD = profD; + return profD.forget(); + } + + already_AddRefed<nsIFile> GetGREDirectory() { + if (mGRED) { + nsCOMPtr<nsIFile> copy = mGRED; + return copy.forget(); + } + + char* env = PR_GetEnv("MOZ_XRE_DIR"); + nsCOMPtr<nsIFile> greD; + if (env) { + NS_NewLocalFile(NS_ConvertUTF8toUTF16(env), false, getter_AddRefs(greD)); + } + + mGRED = greD; + return greD.forget(); + } + + already_AddRefed<nsIFile> GetGREBinDirectory() { + if (mGREBinD) { + nsCOMPtr<nsIFile> copy = mGREBinD; + return copy.forget(); + } + + nsCOMPtr<nsIFile> greD = GetGREDirectory(); + if (!greD) { + return greD.forget(); + } + greD->Clone(getter_AddRefs(mGREBinD)); + +#ifdef XP_MACOSX + nsAutoCString leafName; + mGREBinD->GetNativeLeafName(leafName); + if (leafName.EqualsLiteral("Resources")) { + mGREBinD->SetNativeLeafName("MacOS"_ns); + } +#endif + + nsCOMPtr<nsIFile> copy = mGREBinD; + return copy.forget(); + } + + //////////////////////////////////////////////////////////////////////////// + //// nsIDirectoryServiceProvider + + NS_IMETHODIMP GetFile(const char* aProperty, bool* _persistent, + nsIFile** _result) override { + // If we were supplied a directory service provider, ask it first. + if (mDirSvcProvider && NS_SUCCEEDED(mDirSvcProvider->GetFile( + aProperty, _persistent, _result))) { + return NS_OK; + } + + // Otherwise, the test harness provides some directories automatically. + if (0 == strcmp(aProperty, NS_APP_USER_PROFILE_50_DIR) || + 0 == strcmp(aProperty, NS_APP_USER_PROFILE_LOCAL_50_DIR) || + 0 == strcmp(aProperty, NS_APP_PROFILE_LOCAL_DIR_STARTUP)) { + nsCOMPtr<nsIFile> profD = GetProfileDirectory(); + NS_ENSURE_TRUE(profD, NS_ERROR_FAILURE); + + nsCOMPtr<nsIFile> clone; + nsresult rv = profD->Clone(getter_AddRefs(clone)); + NS_ENSURE_SUCCESS(rv, rv); + + *_persistent = true; + clone.forget(_result); + return NS_OK; + } else if (0 == strcmp(aProperty, NS_GRE_DIR)) { + nsCOMPtr<nsIFile> greD = GetGREDirectory(); + NS_ENSURE_TRUE(greD, NS_ERROR_FAILURE); + + *_persistent = true; + greD.forget(_result); + return NS_OK; + } else if (0 == strcmp(aProperty, NS_GRE_BIN_DIR)) { + nsCOMPtr<nsIFile> greBinD = GetGREBinDirectory(); + NS_ENSURE_TRUE(greBinD, NS_ERROR_FAILURE); + + *_persistent = true; + greBinD.forget(_result); + return NS_OK; + } + + return NS_ERROR_FAILURE; + } + + //////////////////////////////////////////////////////////////////////////// + //// nsIDirectoryServiceProvider2 + + NS_IMETHODIMP GetFiles(const char* aProperty, + nsISimpleEnumerator** _enum) override { + // If we were supplied a directory service provider, ask it first. + nsCOMPtr<nsIDirectoryServiceProvider2> provider = + do_QueryInterface(mDirSvcProvider); + if (provider && NS_SUCCEEDED(provider->GetFiles(aProperty, _enum))) { + return NS_OK; + } + + return NS_ERROR_FAILURE; + } + + private: + const char* mTestName; + nsIServiceManager* mServMgr; + nsCOMPtr<nsIDirectoryServiceProvider> mDirSvcProvider; + nsCOMPtr<nsIFile> mProfD; + nsCOMPtr<nsIFile> mGRED; + nsCOMPtr<nsIFile> mGREBinD; +}; + +NS_IMPL_QUERY_INTERFACE(ScopedXPCOM, nsIDirectoryServiceProvider, + nsIDirectoryServiceProvider2) + +NS_IMETHODIMP_(MozExternalRefCountType) +ScopedXPCOM::AddRef() { return 2; } + +NS_IMETHODIMP_(MozExternalRefCountType) +ScopedXPCOM::Release() { return 1; } + +} // namespace + +#endif // FuzzerTestHarness_h__ diff --git a/tools/fuzzing/interface/harness/moz.build b/tools/fuzzing/interface/harness/moz.build new file mode 100644 index 0000000000..0eff84c8aa --- /dev/null +++ b/tools/fuzzing/interface/harness/moz.build @@ -0,0 +1,16 @@ +# -*- 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("fuzzer-runner") + +SOURCES += [ + "FuzzerRunner.cpp", +] +EXPORTS += [ + "FuzzerRunner.h", +] + +FINAL_LIBRARY = "xul" diff --git a/tools/fuzzing/interface/moz.build b/tools/fuzzing/interface/moz.build new file mode 100644 index 0000000000..8a51007174 --- /dev/null +++ b/tools/fuzzing/interface/moz.build @@ -0,0 +1,32 @@ +# -*- 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("fuzzer-interface") + +EXPORTS += [ + "FuzzingInterface.h", +] + +SOURCES += [ + "FuzzingInterface.cpp", +] + +if CONFIG["JS_STANDALONE"]: + FINAL_LIBRARY = "js" +else: + EXPORTS += [ + "FuzzingInterfaceStream.h", + ] + + SOURCES += [ + "FuzzingInterfaceStream.cpp", + ] + + DIRS += [ + "harness", + ] + + FINAL_LIBRARY = "xul-gtest" |