tests.cpp (3134B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "fuzz-tests/tests.h" 8 9 #include <stdio.h> 10 11 #include "js/AllocPolicy.h" 12 #include "js/GlobalObject.h" 13 #include "js/Initialization.h" 14 #include "js/Prefs.h" 15 #include "js/RealmOptions.h" 16 #include "js/RootingAPI.h" 17 #include "js/Stack.h" 18 #include "vm/JSContext.h" 19 20 #ifdef LIBFUZZER 21 # include "FuzzerDefs.h" 22 #endif 23 24 using namespace mozilla; 25 26 MOZ_RUNINIT JS::PersistentRootedObject gGlobal; 27 JSContext* gCx = nullptr; 28 29 static const JSClass* getGlobalClass() { 30 static const JSClass c = { 31 "global", 32 JSCLASS_GLOBAL_FLAGS, 33 &JS::DefaultGlobalClassOps, 34 }; 35 return &c; 36 } 37 38 static JSObject* jsfuzz_createGlobal(JSContext* cx, JSPrincipals* principals) { 39 /* Create the global object. */ 40 JS::RealmOptions options; 41 options.creationOptions().setSharedMemoryAndAtomicsEnabled(true); 42 return JS_NewGlobalObject(cx, getGlobalClass(), principals, 43 JS::FireOnNewGlobalHook, options); 44 } 45 46 static bool jsfuzz_init(JSContext** cx, JS::PersistentRootedObject* global) { 47 *cx = JS_NewContext(8L * 1024 * 1024); 48 if (!*cx) { 49 return false; 50 } 51 52 const size_t MAX_STACK_SIZE = 500000; 53 54 JS_SetNativeStackQuota(*cx, MAX_STACK_SIZE); 55 56 js::UseInternalJobQueues(*cx); 57 if (!JS::InitSelfHostedCode(*cx)) { 58 return false; 59 } 60 global->init(*cx); 61 *global = jsfuzz_createGlobal(*cx, nullptr); 62 if (!*global) { 63 return false; 64 } 65 JS::EnterRealm(*cx, *global); 66 return true; 67 } 68 69 static void jsfuzz_uninit(JSContext* cx) { 70 if (cx) { 71 JS::LeaveRealm(cx, nullptr); 72 JS_DestroyContext(cx); 73 cx = nullptr; 74 } 75 } 76 77 int main(int argc, char* argv[]) { 78 // Override prefs for fuzz-tests. 79 JS::Prefs::setAtStartup_experimental_weakrefs_expose_cleanupSome(true); 80 81 if (!JS_Init()) { 82 fprintf(stderr, "Error: Call to jsfuzz_init() failed\n"); 83 return 1; 84 } 85 86 if (!jsfuzz_init(&gCx, &gGlobal)) { 87 fprintf(stderr, "Error: Call to jsfuzz_init() failed\n"); 88 return 1; 89 } 90 91 const char* fuzzerEnv = getenv("FUZZER"); 92 if (!fuzzerEnv) { 93 fprintf(stderr, 94 "Must specify fuzzing target in FUZZER environment variable\n"); 95 return 1; 96 } 97 98 std::string moduleNameStr(getenv("FUZZER")); 99 100 FuzzerFunctions funcs = 101 FuzzerRegistry::getInstance().getModuleFunctions(moduleNameStr); 102 FuzzerInitFunc initFunc = funcs.first; 103 FuzzerTestingFunc testingFunc = funcs.second; 104 if (initFunc) { 105 int ret = initFunc(&argc, &argv); 106 if (ret) { 107 fprintf(stderr, "Fuzzing Interface: Error: Initialize callback failed\n"); 108 return ret; 109 } 110 } 111 112 if (!testingFunc) { 113 fprintf(stderr, "Fuzzing Interface: Error: No testing callback found\n"); 114 return 1; 115 } 116 117 #ifdef LIBFUZZER 118 fuzzer::FuzzerDriver(&argc, &argv, testingFunc); 119 #elif AFLFUZZ 120 testingFunc(nullptr, 0); 121 #endif 122 123 jsfuzz_uninit(gCx); 124 125 JS_ShutDown(); 126 127 return 0; 128 }