Bug 1913305 - Add test. r=mtigley
[gecko.git] / js / src / fuzz-tests / tests.cpp
blob4b903b6f8a92aa688ea2e3465ad7fc746f957efd
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/. */
7 #include "fuzz-tests/tests.h"
9 #include <stdio.h>
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"
20 #ifdef LIBFUZZER
21 # include "FuzzerDefs.h"
22 #endif
24 using namespace mozilla;
26 JS::PersistentRootedObject gGlobal;
27 JSContext* gCx = nullptr;
29 static const JSClass* getGlobalClass() {
30 static const JSClass c = {
31 "global",
32 JSCLASS_GLOBAL_FLAGS,
33 &JS::DefaultGlobalClassOps,
35 return &c;
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);
46 static bool jsfuzz_init(JSContext** cx, JS::PersistentRootedObject* global) {
47 *cx = JS_NewContext(8L * 1024 * 1024);
48 if (!*cx) {
49 return false;
52 const size_t MAX_STACK_SIZE = 500000;
54 JS_SetNativeStackQuota(*cx, MAX_STACK_SIZE);
56 js::UseInternalJobQueues(*cx);
57 if (!JS::InitSelfHostedCode(*cx)) {
58 return false;
60 global->init(*cx);
61 *global = jsfuzz_createGlobal(*cx, nullptr);
62 if (!*global) {
63 return false;
65 JS::EnterRealm(*cx, *global);
66 return true;
69 static void jsfuzz_uninit(JSContext* cx) {
70 if (cx) {
71 JS::LeaveRealm(cx, nullptr);
72 JS_DestroyContext(cx);
73 cx = nullptr;
77 int main(int argc, char* argv[]) {
78 // Override prefs for fuzz-tests.
79 JS::Prefs::setAtStartup_weakrefs(true);
80 JS::Prefs::setAtStartup_experimental_weakrefs_expose_cleanupSome(true);
82 if (!JS_Init()) {
83 fprintf(stderr, "Error: Call to jsfuzz_init() failed\n");
84 return 1;
87 if (!jsfuzz_init(&gCx, &gGlobal)) {
88 fprintf(stderr, "Error: Call to jsfuzz_init() failed\n");
89 return 1;
92 const char* fuzzerEnv = getenv("FUZZER");
93 if (!fuzzerEnv) {
94 fprintf(stderr,
95 "Must specify fuzzing target in FUZZER environment variable\n");
96 return 1;
99 std::string moduleNameStr(getenv("FUZZER"));
101 FuzzerFunctions funcs =
102 FuzzerRegistry::getInstance().getModuleFunctions(moduleNameStr);
103 FuzzerInitFunc initFunc = funcs.first;
104 FuzzerTestingFunc testingFunc = funcs.second;
105 if (initFunc) {
106 int ret = initFunc(&argc, &argv);
107 if (ret) {
108 fprintf(stderr, "Fuzzing Interface: Error: Initialize callback failed\n");
109 return ret;
113 if (!testingFunc) {
114 fprintf(stderr, "Fuzzing Interface: Error: No testing callback found\n");
115 return 1;
118 #ifdef LIBFUZZER
119 fuzzer::FuzzerDriver(&argc, &argv, testingFunc);
120 #elif AFLFUZZ
121 testingFunc(nullptr, 0);
122 #endif
124 jsfuzz_uninit(gCx);
126 JS_ShutDown();
128 return 0;