summaryrefslogtreecommitdiffstats
path: root/js/src/shell
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:35:37 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:35:37 +0000
commita90a5cba08fdf6c0ceb95101c275108a152a3aed (patch)
tree532507288f3defd7f4dcf1af49698bcb76034855 /js/src/shell
parentAdding debian version 126.0.1-1. (diff)
downloadfirefox-a90a5cba08fdf6c0ceb95101c275108a152a3aed.tar.xz
firefox-a90a5cba08fdf6c0ceb95101c275108a152a3aed.zip
Merging upstream version 127.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/shell')
-rw-r--r--js/src/shell/ShellModuleObjectWrapper.cpp28
-rw-r--r--js/src/shell/js.cpp196
-rw-r--r--js/src/shell/jsoptparse.cpp20
-rw-r--r--js/src/shell/jsoptparse.h15
-rw-r--r--js/src/shell/jsrtfuzzing/jsrtfuzzing.cpp11
-rw-r--r--js/src/shell/moz.build7
6 files changed, 201 insertions, 76 deletions
diff --git a/js/src/shell/ShellModuleObjectWrapper.cpp b/js/src/shell/ShellModuleObjectWrapper.cpp
index 4e8c234e61..7a047ebaf4 100644
--- a/js/src/shell/ShellModuleObjectWrapper.cpp
+++ b/js/src/shell/ShellModuleObjectWrapper.cpp
@@ -85,6 +85,7 @@ using mozilla::Span;
DEFINE_NATIVE_CLASS_IMPL(CLASS)
DEFINE_CLASS(ModuleRequestObject)
+DEFINE_NATIVE_CLASS(ImportAttribute)
DEFINE_NATIVE_CLASS(ImportEntry)
DEFINE_NATIVE_CLASS(ExportEntry)
DEFINE_NATIVE_CLASS(RequestedModule)
@@ -281,6 +282,17 @@ bool SpanToArrayFilter(JSContext* cx, JS::Handle<JSObject*> owner,
return true;
}
+template <class T>
+bool SpanToNullableArrayFilter(JSContext* cx, JS::Handle<JSObject*> owner,
+ Span<const typename T::Target> from,
+ JS::MutableHandle<JS::Value> to) {
+ if (from.Length() == 0) {
+ to.setNull();
+ return true;
+ }
+ return SpanToArrayFilter<T>(cx, owner, from, to);
+}
+
template <class T, typename RawGetterT, typename FilterT>
bool ShellModuleNativeWrapperGetter(JSContext* cx, const JS::CallArgs& args,
RawGetterT rawGetter, FilterT filter) {
@@ -313,14 +325,22 @@ bool ShellModuleNativeWrapperGetter(JSContext* cx, const JS::CallArgs& args,
cx, args); \
}
+DEFINE_GETTER_FUNCTIONS(ImportAttribute, key, StringOrNullValue, IdentFilter);
+DEFINE_GETTER_FUNCTIONS(ImportAttribute, value, StringOrNullValue, IdentFilter);
+
+static const JSPropertySpec ShellImportAttributeWrapper_accessors[] = {
+ JS_PSG("key", ShellImportAttributeWrapper_keyGetter, 0),
+ JS_PSG("value", ShellImportAttributeWrapper_valueGetter, 0), JS_PS_END};
+
DEFINE_GETTER_FUNCTIONS(ModuleRequestObject, specifier, StringOrNullValue,
IdentFilter)
-DEFINE_GETTER_FUNCTIONS(ModuleRequestObject, attributes, ObjectOrNullValue,
- IdentFilter)
+DEFINE_NATIVE_GETTER_FUNCTIONS(
+ ModuleRequestObject, attributes,
+ SpanToNullableArrayFilter<ShellImportAttributeWrapper>);
static const JSPropertySpec ShellModuleRequestObjectWrapper_accessors[] = {
JS_PSG("specifier", ShellModuleRequestObjectWrapper_specifierGetter, 0),
- JS_PSG("assertions", ShellModuleRequestObjectWrapper_attributesGetter, 0),
+ JS_PSG("attributes", ShellModuleRequestObjectWrapper_attributesGetter, 0),
JS_PS_END};
DEFINE_GETTER_FUNCTIONS(ImportEntry, moduleRequest, ObjectOrNullValue,
@@ -469,6 +489,8 @@ static const JSPropertySpec ShellModuleObjectWrapper_accessors[] = {
DEFINE_CREATE(ModuleRequestObject, ShellModuleRequestObjectWrapper_accessors,
nullptr)
+DEFINE_NATIVE_CREATE(ImportAttribute, ShellImportAttributeWrapper_accessors,
+ nullptr)
DEFINE_NATIVE_CREATE(ImportEntry, ShellImportEntryWrapper_accessors, nullptr)
DEFINE_NATIVE_CREATE(ExportEntry, ShellExportEntryWrapper_accessors, nullptr)
DEFINE_NATIVE_CREATE(RequestedModule, ShellRequestedModuleWrapper_accessors,
diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp
index 178c394e1d..0acc38e282 100644
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -123,10 +123,10 @@
#include "js/CompilationAndEvaluation.h"
#include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions, JS::CompileOptions, JS::OwningCompileOptions, JS::DecodeOptions, JS::InstantiateOptions
#include "js/ContextOptions.h" // JS::ContextOptions{,Ref}
-#include "js/Debug.h"
-#include "js/Equality.h" // JS::SameValue
-#include "js/ErrorReport.h" // JS::PrintError
-#include "js/Exception.h" // JS::StealPendingExceptionStack
+#include "js/Debug.h" // JS::dbg::ShouldAvoidSideEffects
+#include "js/Equality.h" // JS::SameValue
+#include "js/ErrorReport.h" // JS::PrintError
+#include "js/Exception.h" // JS::StealPendingExceptionStack
#include "js/experimental/CodeCoverage.h" // js::EnableCodeCoverage
#include "js/experimental/CompileScript.h" // JS::NewFrontendContext, JS::DestroyFrontendContext, JS::HadFrontendErrors, JS::ConvertFrontendErrorsToRuntimeErrors, JS::CompileGlobalScriptToStencil, JS::CompileModuleScriptToStencil
#include "js/experimental/CTypes.h" // JS::InitCTypesClass
@@ -2599,13 +2599,19 @@ static bool Evaluate(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
- JSObject* obj = &v.toObject();
- if (obj->isUnqualifiedVarObj()) {
- JS_ReportErrorASCII(
- cx,
- "\"envChainObject\" passed to evaluate() should not be an "
- "unqualified variables object");
- return false;
+ RootedObject obj(cx, &v.toObject());
+ {
+ // This may be a CCW, so try to unwrap before checking
+ // if it is an unqualified variables object. We still append
+ // the original object to the environment chain however.
+ JSObject* unwrappedObj = js::UncheckedUnwrap(obj, cx);
+ if (unwrappedObj->isUnqualifiedVarObj()) {
+ JS_ReportErrorASCII(
+ cx,
+ "\"envChainObject\" passed to evaluate() should not be an "
+ "unqualified variables object");
+ return false;
+ }
}
if (!envChain.append(obj)) {
@@ -4566,7 +4572,7 @@ static void WatchdogMain(JSContext* cx) {
*/
sc->watchdogTimeout = Nothing();
{
- UnlockGuard<Mutex> unlock(guard);
+ UnlockGuard unlock(guard);
CancelExecution(cx);
}
@@ -5416,8 +5422,9 @@ static bool RegisterModule(JSContext* cx, unsigned argc, Value* vp) {
return false;
}
+ Rooted<UniquePtr<ImportAttributeVector>> attributes(cx);
RootedObject moduleRequest(
- cx, ModuleRequestObject::create(cx, specifier, nullptr));
+ cx, ModuleRequestObject::create(cx, specifier, &attributes));
if (!moduleRequest) {
return false;
}
@@ -9135,6 +9142,59 @@ static bool DecompressLZ4(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
+static bool SideEffectfulResolveObject_enumerate(
+ JSContext* cx, JS::HandleObject obj, JS::MutableHandleIdVector properties,
+ bool enumerableOnly) {
+ return properties.append(NameToId(cx->names().test));
+}
+
+static bool SideEffectfulResolveObject_resolve(JSContext* cx, HandleObject obj,
+ HandleId id, bool* resolvedp) {
+ *resolvedp = false;
+ if (JS::dbg::ShouldAvoidSideEffects(cx)) {
+ return false;
+ }
+
+ if (id == NameToId(cx->names().test)) {
+ RootedValue value(cx, JS::NumberValue(42));
+ if (!JS_DefinePropertyById(cx, obj, id, value, JSPROP_ENUMERATE)) {
+ return false;
+ }
+ *resolvedp = true;
+ }
+
+ return true;
+}
+
+static const JSClassOps SideEffectfulResolveObject_classOps = {
+ nullptr, // addProperty
+ nullptr, // delProperty
+ nullptr, // enumerate
+ SideEffectfulResolveObject_enumerate, // newEnumerate
+ SideEffectfulResolveObject_resolve, // resolve
+ nullptr, // mayResolve
+ nullptr, // finalize
+ nullptr, // call
+ nullptr, // construct
+ nullptr,
+};
+
+static const JSClass SideEffectfulResolveObject_class = {
+ "SideEffectfulResolveObject", 0, &SideEffectfulResolveObject_classOps};
+
+static bool CreateSideEffectfulResolveObject(JSContext* cx, unsigned argc,
+ JS::Value* vp) {
+ CallArgs args = CallArgsFromVp(argc, vp);
+
+ RootedObject obj(cx, JS_NewObject(cx, &SideEffectfulResolveObject_class));
+ if (!obj) {
+ return false;
+ }
+
+ args.rval().setObject(*obj);
+ return true;
+}
+
// clang-format off
static const JSFunctionSpecWithHelp shell_functions[] = {
JS_FN_HELP("options", Options, 0, 0,
@@ -9750,16 +9810,6 @@ JS_FN_HELP("createUserArrayBuffer", CreateUserArrayBuffer, 1, 0,
" or only when there are no other JavaScript frames on the stack\n"
" below it (false). If omitted, this is treated as 'true'."),
-#ifdef JS_HAS_INTL_API
- JS_FN_HELP("addIntlExtras", AddIntlExtras, 1, 0,
-"addIntlExtras(obj)",
-"Adds various not-yet-standardized Intl functions as properties on the\n"
-"provided object (this should generally be Intl itself). The added\n"
-"functions and their behavior are experimental: don't depend upon them\n"
-"unless you're willing to update your code if these experimental APIs change\n"
-"underneath you."),
-#endif // JS_HAS_INTL_API
-
#ifndef __wasi__
JS_FN_HELP("wasmCompileInSeparateProcess", WasmCompileInSeparateProcess, 1, 0,
"wasmCompileInSeparateProcess(buffer)",
@@ -9814,6 +9864,11 @@ JS_FN_HELP("createUserArrayBuffer", CreateUserArrayBuffer, 1, 0,
"decompressLZ4(bytes)",
" Return a decompressed copy of bytes using LZ4."),
+ JS_FN_HELP("createSideEffectfulResolveObject", CreateSideEffectfulResolveObject, 0, 0,
+"createSideEffectfulResolveObject()",
+" Return an object with a property 'obj.test == 42', backed by a resolve hook "
+" with the Debugger shouldAvoidSideEffects flag integration."),
+
JS_FS_HELP_END
};
// clang-format on
@@ -9911,6 +9966,20 @@ TestAssertRecoveredOnBailout,
" Returns an array of queued jobs."),
#endif
+#ifdef JS_HAS_INTL_API
+ // One of the extras is AddMozDateTimeFormatConstructor, which is not fuzzing
+ // safe, since it doesn't validate the custom format pattern.
+ //
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=1887585#c1
+ JS_FN_HELP("addIntlExtras", AddIntlExtras, 1, 0,
+"addIntlExtras(obj)",
+"Adds various not-yet-standardized Intl functions as properties on the\n"
+"provided object (this should generally be Intl itself). The added\n"
+"functions and their behavior are experimental: don't depend upon them\n"
+"unless you're willing to update your code if these experimental APIs change\n"
+"underneath you."),
+#endif // JS_HAS_INTL_API
+
JS_FS_HELP_END
};
// clang-format on
@@ -11340,13 +11409,6 @@ static int Shell(JSContext* cx, OptionParser* op) {
nocgc.emplace(cx);
}
- if (op->getBoolOption("fuzzing-safe")) {
- fuzzingSafe = true;
- } else {
- fuzzingSafe =
- (getenv("MOZ_FUZZING_SAFE") && getenv("MOZ_FUZZING_SAFE")[0] != '0');
- }
-
#ifdef DEBUG
if (op->getBoolOption("differential-testing")) {
JS::SetSupportDifferentialTesting(true);
@@ -11422,15 +11484,20 @@ static int Shell(JSContext* cx, OptionParser* op) {
fflush(stdout);
fflush(stderr);
// Send return code to parent and reset edge counters.
- struct {
- int status;
- uint32_t execHash;
- uint32_t execHashInputs;
- } s;
- s.status = (result & 0xff) << 8;
- s.execHash = cx->executionHash;
- s.execHashInputs = cx->executionHashInputs;
- MOZ_RELEASE_ASSERT(write(REPRL_CWFD, &s, 12) == 12);
+ int status = (result & 0xff) << 8;
+ if (js::SupportDifferentialTesting()) {
+ struct {
+ int status;
+ uint32_t execHash;
+ uint32_t execHashInputs;
+ } s;
+ s.status = status;
+ s.execHash = cx->executionHash;
+ s.execHashInputs = cx->executionHashInputs;
+ MOZ_RELEASE_ASSERT(write(REPRL_CWFD, &s, 12) == 12);
+ } else {
+ MOZ_RELEASE_ASSERT(write(REPRL_CWFD, &status, 4) == 4);
+ }
__sanitizer_cov_reset_edgeguards();
cx->executionHash = 1;
cx->executionHashInputs = 0;
@@ -11605,7 +11672,13 @@ static bool SetJSPrefToTrueForBool(const char* name) {
FOR_EACH_JS_PREF(CHECK_PREF)
#undef CHECK_PREF
- // Nothing matched, return false
+ // Nothing matched. If --fuzzing-safe is used, return true after printing a
+ // message, to continue execution without breaking fuzzing when a pref is
+ // removed.
+ if (fuzzingSafe) {
+ fprintf(stderr, "Warning: Ignoring unknown pref name: %s\n", name);
+ return true;
+ }
fprintf(stderr, "Invalid pref name: %s\n", name);
return false;
}
@@ -11625,7 +11698,13 @@ static bool SetJSPrefToValue(const char* name, size_t nameLen,
FOR_EACH_JS_PREF(CHECK_PREF)
#undef CHECK_PREF
- // Nothing matched, return false
+ // Nothing matched. If --fuzzing-safe is used, return true after printing a
+ // message, to continue execution without breaking fuzzing when a pref is
+ // removed.
+ if (fuzzingSafe) {
+ fprintf(stderr, "Warning: Ignoring unknown pref name: %s\n", name);
+ return true;
+ }
fprintf(stderr, "Invalid pref name: %s\n", name);
return false;
}
@@ -12043,10 +12122,9 @@ bool InitOptionParser(OptionParser& op) {
"Enable resizable ArrayBuffers and growable SharedArrayBuffers") ||
!op.addBoolOption('\0', "enable-uint8array-base64",
"Enable Uint8Array base64/hex methods") ||
+ !op.addBoolOption('\0', "enable-float16array", "Enable Float16Array") ||
!op.addBoolOption('\0', "enable-top-level-await",
"Enable top-level await") ||
- !op.addBoolOption('\0', "enable-class-static-blocks",
- "(no-op) Enable class static blocks") ||
!op.addBoolOption('\0', "enable-import-assertions",
"Enable import attributes with old assert syntax") ||
!op.addBoolOption('\0', "enable-import-attributes",
@@ -12092,10 +12170,6 @@ bool InitOptionParser(OptionParser& op) {
"Range analysis (default: on, off to disable)") ||
!op.addStringOption('\0', "ion-sink", "on/off",
"Sink code motion (default: off, on to enable)") ||
- !op.addStringOption('\0', "ion-optimization-levels", "on/off",
- "No-op for fuzzing") ||
- !op.addStringOption('\0', "ion-loop-unrolling", "on/off",
- "(NOP for fuzzers)") ||
!op.addStringOption(
'\0', "ion-instruction-reordering", "on/off",
"Instruction reordering (default: off, on to enable)") ||
@@ -12134,8 +12208,6 @@ bool InitOptionParser(OptionParser& op) {
"Wait for COUNT calls or iterations before compiling "
"at the normal optimization level (default: 1000)",
-1) ||
- !op.addIntOption('\0', "ion-full-warmup-threshold", "COUNT",
- "No-op for fuzzing", -1) ||
!op.addStringOption(
'\0', "ion-regalloc", "[mode]",
"Specify Ion register allocation:\n"
@@ -12199,9 +12271,6 @@ bool InitOptionParser(OptionParser& op) {
"Whether monomorphic inlining is used instead of trial inlining "
"always, never, or based on heuristics (default)") ||
!op.addBoolOption(
- '\0', "non-writable-jitcode",
- "(NOP for fuzzers) Allocate JIT code as non-writable memory.") ||
- !op.addBoolOption(
'\0', "no-sse3",
"Pretend CPU does not support SSE3 instructions and above "
"to test JIT codegen (no-op on platforms other than x86 and x64).") ||
@@ -12262,9 +12331,6 @@ bool InitOptionParser(OptionParser& op) {
"Disable GC parallel marking") ||
!op.addBoolOption('\0', "enable-parallel-marking",
"Enable GC parallel marking") ||
- !op.addIntOption(
- '\0', "marking-threads", "COUNT",
- "Set the number of threads used for parallel marking to COUNT.", 0) ||
!op.addStringOption('\0', "nursery-strings", "on/off",
"Allocate strings in the nursery") ||
!op.addStringOption('\0', "nursery-bigints", "on/off",
@@ -12391,10 +12457,21 @@ bool InitOptionParser(OptionParser& op) {
op.setArgTerminatesOptions("script", true);
op.setArgCapturesRest("scriptArgs");
+ // If --fuzzing-safe is used, print a warning for unknown shell flags instead
+ // of aborting execution.
+ op.setIgnoresUnknownOptions("fuzzing-safe", true);
+
return true;
}
bool SetGlobalOptionsPreJSInit(const OptionParser& op) {
+ if (op.getBoolOption("fuzzing-safe")) {
+ fuzzingSafe = true;
+ } else {
+ fuzzingSafe =
+ (getenv("MOZ_FUZZING_SAFE") && getenv("MOZ_FUZZING_SAFE")[0] != '0');
+ }
+
for (MultiStringRange args = op.getMultiStringOption("setpref");
!args.empty(); args.popFront()) {
if (!SetJSPref(args.front())) {
@@ -12434,6 +12511,9 @@ bool SetGlobalOptionsPreJSInit(const OptionParser& op) {
if (op.getBoolOption("enable-uint8array-base64")) {
JS::Prefs::setAtStartup_experimental_uint8array_base64(true);
}
+ if (op.getBoolOption("enable-float16array")) {
+ JS::Prefs::setAtStartup_experimental_float16array(true);
+ }
#endif
#ifdef ENABLE_JSON_PARSE_WITH_SOURCE
JS::Prefs::setAtStartup_experimental_json_parse_with_source(
@@ -12666,7 +12746,6 @@ bool SetContextOptions(JSContext* cx, const OptionParser& op) {
op.getBoolOption("enable-import-assertions");
enableImportAttributes = op.getBoolOption("enable-import-attributes") ||
enableImportAttributesAssertSyntax;
-
JS::ContextOptionsRef(cx)
.setSourcePragmas(enableSourcePragmas)
.setAsyncStack(enableAsyncStacks)
@@ -13302,11 +13381,6 @@ bool SetContextGCOptions(JSContext* cx, const OptionParser& op) {
}
JS_SetGCParameter(cx, JSGC_PARALLEL_MARKING_ENABLED, parallelMarking);
- int32_t markingThreads = op.getIntOption("marking-threads");
- if (markingThreads > 0) {
- JS_SetGCParameter(cx, JSGC_MARKING_THREAD_COUNT, markingThreads);
- }
-
JS_SetGCParameter(cx, JSGC_SLICE_TIME_BUDGET_MS, 5);
JS_SetGCParameter(cx, JSGC_PER_ZONE_GC_ENABLED, true);
diff --git a/js/src/shell/jsoptparse.cpp b/js/src/shell/jsoptparse.cpp
index 5632598d7d..b2805fb415 100644
--- a/js/src/shell/jsoptparse.cpp
+++ b/js/src/shell/jsoptparse.cpp
@@ -44,6 +44,12 @@ void OptionParser::setArgTerminatesOptions(const char* name, bool enabled) {
findArgument(name)->setTerminatesOptions(enabled);
}
+void OptionParser::setIgnoresUnknownOptions(const char* name, bool enabled) {
+ auto* opt = findOption(name);
+ MOZ_ASSERT(opt);
+ opt->setIgnoresUnknownOptions(enabled);
+}
+
void OptionParser::setArgCapturesRest(const char* name) {
MOZ_ASSERT(restArgument == -1,
"only one argument may be set to capture the rest");
@@ -349,10 +355,15 @@ OptionParser::Result OptionParser::handleArg(size_t argc, char** argv,
OptionParser::Result OptionParser::parseArgs(int inputArgc, char** argv) {
MOZ_ASSERT(inputArgc >= 0);
size_t argc = inputArgc;
+
// Permit a "no more options" capability, like |--| offers in many shell
// interfaces.
bool optionsAllowed = true;
+ // Whether unknown options should report a warning instead of an error. This
+ // is enabled by setIgnoresUnknownOptions and used for --fuzzing-safe.
+ bool ignoreUnknownOptions = false;
+
for (size_t i = 1; i < argc; ++i) {
char* arg = argv[i];
Result r;
@@ -370,6 +381,11 @@ OptionParser::Result OptionParser::parseArgs(int inputArgc, char** argv) {
/* Long option. */
opt = findOption(arg + 2);
if (!opt) {
+ if (ignoreUnknownOptions) {
+ fprintf(stderr, "Warning: Ignoring unknown shell flag: %s\n",
+ arg);
+ continue;
+ }
return error("Invalid long option: %s", arg);
}
}
@@ -384,6 +400,10 @@ OptionParser::Result OptionParser::parseArgs(int inputArgc, char** argv) {
}
}
+ if (opt->getIgnoresUnknownOptions()) {
+ ignoreUnknownOptions = true;
+ }
+
r = handleOption(opt, argc, argv, &i, &optionsAllowed);
} else {
/* Argument. */
diff --git a/js/src/shell/jsoptparse.h b/js/src/shell/jsoptparse.h
index 17e4878969..34f46fed48 100644
--- a/js/src/shell/jsoptparse.h
+++ b/js/src/shell/jsoptparse.h
@@ -69,21 +69,23 @@ struct Option {
const char* help;
OptionKind kind;
char shortflag;
- bool terminatesOptions;
+ bool terminatesOptions = false;
+ bool ignoresUnknownOptions = false;
Option(OptionKind kind, char shortflag, const char* longflag,
const char* help)
- : longflag(longflag),
- help(help),
- kind(kind),
- shortflag(shortflag),
- terminatesOptions(false) {}
+ : longflag(longflag), help(help), kind(kind), shortflag(shortflag) {}
virtual ~Option() = 0;
void setTerminatesOptions(bool enabled) { terminatesOptions = enabled; }
bool getTerminatesOptions() const { return terminatesOptions; }
+ void setIgnoresUnknownOptions(bool enabled) {
+ ignoresUnknownOptions = enabled;
+ }
+ bool getIgnoresUnknownOptions() const { return ignoresUnknownOptions; }
+
virtual bool isValued() const { return false; }
/* Only some valued options are variadic (like MultiStringOptions). */
@@ -293,6 +295,7 @@ class OptionParser {
void setDescription(const char* description) { descr = description; }
void setHelpOption(char shortflag, const char* longflag, const char* help);
void setArgTerminatesOptions(const char* name, bool enabled);
+ void setIgnoresUnknownOptions(const char* name, bool enabled);
void setArgCapturesRest(const char* name);
/* Arguments: no further arguments may be added after a variadic argument. */
diff --git a/js/src/shell/jsrtfuzzing/jsrtfuzzing.cpp b/js/src/shell/jsrtfuzzing/jsrtfuzzing.cpp
index 0b6f505fb6..ac6d706547 100644
--- a/js/src/shell/jsrtfuzzing/jsrtfuzzing.cpp
+++ b/js/src/shell/jsrtfuzzing/jsrtfuzzing.cpp
@@ -11,8 +11,13 @@
#include <stdio.h> // fflush, fprintf, fputs
-#include "FuzzerDefs.h"
-#include "FuzzingInterface.h"
+#ifdef LIBFUZZER
+# include "FuzzerDefs.h"
+#endif
+#ifdef AFLFUZZ
+# include "FuzzingInterface.h"
+#endif
+
#include "jsapi.h" // JS_ClearPendingException, JS_IsExceptionPending
#include "js/CompilationAndEvaluation.h" // JS::Evaluate
@@ -69,7 +74,7 @@ int js::shell::FuzzJSRuntimeStart(JSContext* cx, int* argc, char*** argv) {
#ifdef LIBFUZZER
fuzzer::FuzzerDriver(&shell::sArgc, &shell::sArgv, FuzzJSRuntimeFuzz);
#elif AFLFUZZ
- MOZ_CRASH("AFL is unsupported for JS runtime fuzzing integration");
+ afl_interface_raw(FuzzJSRuntimeFuzz);
#endif
return 0;
}
diff --git a/js/src/shell/moz.build b/js/src/shell/moz.build
index ed8551f1ec..f9ee1521d4 100644
--- a/js/src/shell/moz.build
+++ b/js/src/shell/moz.build
@@ -26,9 +26,10 @@ UNIFIED_SOURCES += [
if CONFIG["FUZZING_INTERFACES"]:
UNIFIED_SOURCES += ["jsrtfuzzing/jsrtfuzzing.cpp"]
- USE_LIBS += [
- "static:fuzzer",
- ]
+ if CONFIG["LIBFUZZER"]:
+ USE_LIBS += ["static:fuzzer"]
+ else:
+ USE_LIBS += ["static:fuzzer-interface"]
if CONFIG["FUZZING_JS_FUZZILLI"]:
OS_LIBS += ["rt"]