diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index 4627b04ba365b..a71dbcd08e566 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -73,6 +73,8 @@ #include "nsJSUtils.h" #include "nsILoadInfo.h" #include "js/ColumnNumber.h" +#include "js/GCVector.h" +#include "js/Value.h" #define WEBAPPS_PERM_NAME "webapps-manage" @@ -462,7 +464,12 @@ NS_IMPL_ISUPPORTS(nsScriptSecurityManager, nsIScriptSecurityManager) bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction( - JSContext* cx, JS::RuntimeCode aKind, JS::Handle aCode) { + JSContext* cx, JS::RuntimeCode aKind, JS::Handle aCodeString, + JS::CompilationType aCompilationType, + JS::Handle> aParameterStrings, + JS::Handle aBodyString, + JS::Handle> aParameterArgs, + JS::Handle aBodyArg, bool* aOutCanCompileStrings) { MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext()); nsCOMPtr subjectPrincipal = nsContentUtils::SubjectPrincipal(); @@ -477,13 +484,14 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction( if (contextForbidsEval) { nsAutoJSString scriptSample; if (aKind == JS::RuntimeCode::JS && - NS_WARN_IF(!scriptSample.init(cx, aCode))) { + NS_WARN_IF(!scriptSample.init(cx, aCodeString))) { return false; } if (!nsContentSecurityUtils::IsEvalAllowed( cx, subjectPrincipal->IsSystemPrincipal(), scriptSample)) { - return false; + *aOutCanCompileStrings = false; + return true; } } @@ -503,6 +511,7 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction( } if (!csp) { + *aOutCanCompileStrings = true; return true; } } @@ -522,7 +531,8 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction( nsresult rv = csp->GetAllowsEval(&reportViolation, &evalOK); if (NS_FAILED(rv)) { NS_WARNING("CSP: failed to get allowsEval"); - return true; + *aOutCanCompileStrings = true; + return true; } } else { if (NS_FAILED(csp->GetAllowsWasmEval(&reportViolation, &evalOK))) { @@ -545,8 +555,7 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction( auto caller = JSCallingLocation::Get(cx); nsAutoJSString scriptSample; if (aKind == JS::RuntimeCode::JS && - NS_WARN_IF(!scriptSample.init(cx, aCode))) { - JS_ClearPendingException(cx); + NS_WARN_IF(!scriptSample.init(cx, aCodeString))) { return false; } uint16_t violationType = @@ -559,7 +568,8 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction( caller.mLine, caller.mColumn, u""_ns, u""_ns); } - return evalOK; + *aOutCanCompileStrings = evalOK; + return true; } diff --git a/caps/nsScriptSecurityManager.h b/caps/nsScriptSecurityManager.h index 1ea43d4dc01c6..604409cb6c5a9 100644 --- a/caps/nsScriptSecurityManager.h +++ b/caps/nsScriptSecurityManager.h @@ -28,6 +28,7 @@ class SystemPrincipal; namespace JS { enum class RuntimeCode; +enum class CompilationType; } @@ -91,9 +92,13 @@ class nsScriptSecurityManager final : public nsIScriptSecurityManager { virtual ~nsScriptSecurityManager(); - static bool ContentSecurityPolicyPermitsJSAction(JSContext* cx, - JS::RuntimeCode kind, - JS::Handle aCode); + static bool ContentSecurityPolicyPermitsJSAction( + JSContext* aCx, JS::RuntimeCode aKind, JS::Handle aCodeString, + JS::CompilationType aCompilationType, + JS::Handle> aParameterStrings, + JS::Handle aBodyString, + JS::Handle> aParameterArgs, + JS::Handle aBodyArg, bool* aOutCanCompileStrings); static bool JSPrincipalsSubsume(JSPrincipals* first, JSPrincipals* second); diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index 663b83575f1a1..b165ccf298cd1 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -26,8 +26,10 @@ #include "jsfriendapi.h" #include "js/friend/ErrorMessages.h" #include "js/ContextOptions.h" +#include "js/GCVector.h" #include "js/Initialization.h" #include "js/LocaleSensitive.h" +#include "js/Value.h" #include "js/WasmFeatures.h" #include "mozilla/ArrayUtils.h" #include "mozilla/Atomics.h" @@ -499,8 +501,13 @@ class LogViolationDetailsRunnable final : public WorkerMainThreadRunnable { ~LogViolationDetailsRunnable() = default; }; -bool ContentSecurityPolicyAllows(JSContext* aCx, JS::RuntimeCode aKind, - JS::Handle aCode) { +bool ContentSecurityPolicyAllows( + JSContext* aCx, JS::RuntimeCode aKind, JS::Handle aCodeString, + JS::CompilationType aCompilationType, + JS::Handle> aParameterStrings, + JS::Handle aBodyString, + JS::Handle> aParameterArgs, + JS::Handle aBodyArg, bool* aOutCanCompileStrings) { WorkerPrivate* worker = GetWorkerPrivateFromContext(aCx); worker->AssertIsOnWorkerThread(); @@ -509,14 +516,14 @@ bool ContentSecurityPolicyAllows(JSContext* aCx, JS::RuntimeCode aKind, uint16_t violationType; nsAutoJSString scriptSample; if (aKind == JS::RuntimeCode::JS) { - if (NS_WARN_IF(!scriptSample.init(aCx, aCode))) { - JS_ClearPendingException(aCx); + if (NS_WARN_IF(!scriptSample.init(aCx, aCodeString))) { return false; } if (!nsContentSecurityUtils::IsEvalAllowed( aCx, worker->UsesSystemPrincipal(), scriptSample)) { - return false; + *aOutCanCompileStrings = false; + return true; } evalOK = worker->IsEvalAllowed(); @@ -542,7 +549,8 @@ bool ContentSecurityPolicyAllows(JSContext* aCx, JS::RuntimeCode aKind, } } - return evalOK; + *aOutCanCompileStrings = evalOK; + return true; } void CTypesActivityCallback(JSContext* aCx, JS::CTypesActivityType aType) { diff --git a/js/public/Principals.h b/js/public/Principals.h index 786b558eab8a5..45b427f36b671 100644 --- a/js/public/Principals.h +++ b/js/public/Principals.h @@ -77,6 +77,7 @@ typedef bool (*JSSubsumesOp)(JSPrincipals* first, JSPrincipals* second); namespace JS { enum class RuntimeCode { JS, WASM }; +enum class CompilationType { DirectEval, IndirectEval, Function, Undefined }; } @@ -89,8 +90,22 @@ enum class RuntimeCode { JS, WASM }; -typedef bool (*JSCSPEvalChecker)(JSContext* cx, JS::RuntimeCode kind, - JS::HandleString code); + + + + + + + + + +typedef bool (*JSCSPEvalChecker)( + JSContext* cx, JS::RuntimeCode kind, JS::Handle codeString, + JS::CompilationType compilationType, + JS::Handle> parameterStrings, + JS::Handle bodyString, + JS::Handle> parameterArgs, + JS::Handle bodyArg, bool* outCanCompileStrings); diff --git a/js/src/builtin/Eval.cpp b/js/src/builtin/Eval.cpp index b5aae332575a4..ab8c3e945ea9f 100644 --- a/js/src/builtin/Eval.cpp +++ b/js/src/builtin/Eval.cpp @@ -257,7 +257,17 @@ static bool EvalKernel(JSContext* cx, HandleValue v, EvalType evalType, } - if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::JS, str)) { + JS::RootedVector parameterStrings(cx); + JS::RootedVector parameterArgs(cx); + bool canCompileStrings = false; + if (!cx->isRuntimeCodeGenEnabled( + JS::RuntimeCode::JS, str, + evalType == DIRECT_EVAL ? JS::CompilationType::DirectEval + : JS::CompilationType::IndirectEval, + parameterStrings, str, parameterArgs, v, &canCompileStrings)) { + return false; + } + if (!canCompileStrings) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_EVAL); return false; diff --git a/js/src/builtin/ShadowRealm.cpp b/js/src/builtin/ShadowRealm.cpp index 26fa019ede444..a02fd613218dc 100644 --- a/js/src/builtin/ShadowRealm.cpp +++ b/js/src/builtin/ShadowRealm.cpp @@ -196,7 +196,16 @@ static bool PerformShadowRealmEval(JSContext* cx, Handle sourceText, MOZ_ASSERT(callerRealm != evalRealm); - if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::JS, sourceText)) { + JS::RootedVector parameterStrings(cx); + JS::RootedVector parameterArgs(cx); + bool canCompileStrings = false; + if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::JS, sourceText, + JS::CompilationType::Undefined, + parameterStrings, nullptr, parameterArgs, + NullHandleValue, &canCompileStrings)) { + return false; + } + if (!canCompileStrings) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_SHADOWREALM); return false; diff --git a/js/src/jsapi-tests/testDynamicCodeBrandChecks.cpp b/js/src/jsapi-tests/testDynamicCodeBrandChecks.cpp index ee96357faf4cb..bb0e177cfad1b 100644 --- a/js/src/jsapi-tests/testDynamicCodeBrandChecks.cpp +++ b/js/src/jsapi-tests/testDynamicCodeBrandChecks.cpp @@ -92,3 +92,184 @@ BEGIN_TEST(testDynamicCodeBrandChecks_CustomHostGetCodeForEval) { return true; } END_TEST(testDynamicCodeBrandChecks_CustomHostGetCodeForEval) + + + + +const char* customTypesSnippet = + "function TrustedType(aTrustedCode) { this.trustedCode = aTrustedCode; };" + "TrustedType.prototype.toString = function() { return this.trustedCode; };" + "function CreateFakeTrustedType(aTrustedCode, aString) {" + " let fake = new TrustedType(aTrustedCode);" + " fake.toString = () => { return aString; };" + " return fake;" + "};"; + +BEGIN_TEST(testDynamicCodeBrandChecks_CustomHostEnsureCanCompileStrings) { + JSSecurityCallbacks securityCallbacksWithCustomHostEnsureCanCompileStrings = { + StringifiedObjectsMatchTrustedCodeProperties, + ExtractTrustedCodeStringProperty, + nullptr + }; + JS_SetSecurityCallbacks( + cx, &securityCallbacksWithCustomHostEnsureCanCompileStrings); + JS::RootedValue v(cx); + + EXEC(customTypesSnippet); + + + EVAL("eval('5*8');", &v); + CHECK(v.isNumber() && v.toNumber() == 40); + EVAL("(new Function('a', 'b', 'return a * b'))(6, 7);", &v); + CHECK(v.isNumber() && v.toNumber() == 42); + + + EVAL("eval(new TrustedType('5*8'));", &v); + CHECK(v.isNumber() && v.toNumber() == 40); + EVAL( + "(new Function(new TrustedType('a'), new TrustedType('b'), new " + "TrustedType('return a * b')))(6, 7);", + &v); + CHECK(v.isNumber() && v.toNumber() == 42); + + + + CHECK(!execDontReport( + "new Function(CreateFakeTrustedType('a', 'c'), 'b', 'return b');", + __FILE__, __LINE__)); + cx->clearPendingException(); + CHECK(!execDontReport( + "new Function('a', CreateFakeTrustedType('b', 'c'), 'return a');", + __FILE__, __LINE__)); + cx->clearPendingException(); + CHECK( + !execDontReport("new Function('a', 'b', CreateFakeTrustedType('return a " + "* b', 'return a + b'));", + __FILE__, __LINE__)); + cx->clearPendingException(); + + + + CHECK(!execDontReport("new Function('a', 'b', new TrustedType(undefined));", + __FILE__, __LINE__)); + cx->clearPendingException(); + + + + + EVAL("eval(CreateFakeTrustedType('5*8', '6*7'));", &v); + CHECK(v.isNumber() && v.toNumber() == 40); + EVAL("eval(new TrustedType(undefined));", &v); + CHECK(v.isObject()); + JS::RootedObject obj(cx, &v.toObject()); + JS::RootedValue trustedCode(cx); + CHECK(JS_GetProperty(cx, obj, "trustedCode", &trustedCode)); + CHECK(trustedCode.isUndefined()); + + return true; +} + + + + + +static bool StringifiedObjectsMatchTrustedCodeProperties( + JSContext* aCx, JS::RuntimeCode aKind, JS::Handle aCodeString, + JS::CompilationType aCompilationType, + JS::Handle> aParameterStrings, + JS::Handle aBodyString, + JS::Handle> aParameterArgs, + JS::Handle aBodyArg, bool* aOutCanCompileStrings) { + bool isTrusted = true; + auto comparePropertyAndString = [&aCx, &isTrusted]( + JS::Handle aValue, + JS::Handle aString) { + if (!aValue.isObject()) { + + return true; + } + JS::RootedObject obj(aCx, &aValue.toObject()); + + JS::RootedString trustedCode(aCx); + if (!ExtractTrustedCodeStringProperty(aCx, obj, &trustedCode)) { + + return false; + } + if (!trustedCode) { + + JS_ReportErrorASCII(aCx, "test failed, trustedCode property is undefined"); + return false; + } + bool equals; + if (!EqualStrings(aCx, trustedCode, aString, &equals)) { + + return false; + } + if (!equals) { + isTrusted = false; + } + return true; + }; + if (!comparePropertyAndString(aBodyArg, aBodyString)) { + + return false; + } + if (isTrusted) { + MOZ_ASSERT(aParameterArgs.length() == aParameterStrings.length()); + for (size_t index = 0; index < aParameterArgs.length(); index++) { + if (!comparePropertyAndString(aParameterArgs[index], + aParameterStrings[index])) { + + return false; + } + if (!isTrusted) { + break; + } + } + } + + *aOutCanCompileStrings = isTrusted; + return true; +} + +END_TEST(testDynamicCodeBrandChecks_CustomHostEnsureCanCompileStrings) + +BEGIN_TEST(testDynamicCodeBrandChecks_RejectObjectForEval) { + JSSecurityCallbacks securityCallbacksRejectObjectBody = { + DisallowObjectsAndFailOtherwise, + ExtractTrustedCodeStringProperty, + nullptr + }; + + JS_SetSecurityCallbacks(cx, &securityCallbacksRejectObjectBody); + JS::RootedValue v(cx); + + EXEC(customTypesSnippet); + + + CHECK(!execDontReport("eval('5*8))", __FILE__, __LINE__)); + cx->clearPendingException(); + CHECK(!execDontReport("eval(new TrustedType('5*8'))", __FILE__, __LINE__)); + cx->clearPendingException(); + + return true; +} + +static bool DisallowObjectsAndFailOtherwise( + JSContext* aCx, JS::RuntimeCode aKind, JS::Handle aCodeString, + JS::CompilationType aCompilationType, + JS::Handle> aParameterStrings, + JS::Handle aBodyString, + JS::Handle> aParameterArgs, + JS::Handle aBodyArg, bool* aOutCanCompileStrings) { + if (aBodyArg.isObject()) { + + *aOutCanCompileStrings = false; + return true; + } + + JS_ReportErrorASCII(aCx, "aBodyArg is not an Object"); + return false; +} + +END_TEST(testDynamicCodeBrandChecks_RejectObjectForEval) diff --git a/js/src/vm/JSContext.cpp b/js/src/vm/JSContext.cpp index 73864248e9b3c..5f80cfb189c71 100644 --- a/js/src/vm/JSContext.cpp +++ b/js/src/vm/JSContext.cpp @@ -1233,15 +1233,24 @@ bool JSContext::isThrowingDebuggeeWouldRun() { JSEXN_DEBUGGEEWOULDRUN; } -bool JSContext::isRuntimeCodeGenEnabled(JS::RuntimeCode kind, - HandleString code) { +bool JSContext::isRuntimeCodeGenEnabled( + JS::RuntimeCode kind, JS::Handle codeString, + JS::CompilationType compilationType, + JS::Handle> parameterStrings, + JS::Handle bodyString, + JS::Handle> parameterArgs, + JS::Handle bodyArg, bool* outCanCompileStrings) { if (JSCSPEvalChecker allows = runtime()->securityCallbacks->contentSecurityPolicyAllows) { - return allows(this, kind, code); + return allows(this, kind, codeString, compilationType, parameterStrings, + bodyString, parameterArgs, bodyArg, outCanCompileStrings); } + + + *outCanCompileStrings = true; return true; } diff --git a/js/src/vm/JSContext.h b/js/src/vm/JSContext.h index cb8a9c71fc28c..30524d88fdf8b 100644 --- a/js/src/vm/JSContext.h +++ b/js/src/vm/JSContext.h @@ -803,7 +803,13 @@ struct JS_PUBLIC_API JSContext : public JS::RootingContext, - bool isRuntimeCodeGenEnabled(JS::RuntimeCode kind, js::HandleString code); + bool isRuntimeCodeGenEnabled( + JS::RuntimeCode kind, JS::Handle codeString, + JS::CompilationType compilationType, + JS::Handle> parameterStrings, + JS::Handle bodyString, + JS::Handle> parameterArgs, + JS::Handle bodyArg, bool* outCanCompileStrings); bool getCodeForEval(JS::HandleObject code, diff --git a/js/src/vm/JSFunction.cpp b/js/src/vm/JSFunction.cpp index 5e67a0b2e0af4..81c5d1a747c7b 100644 --- a/js/src/vm/JSFunction.cpp +++ b/js/src/vm/JSFunction.cpp @@ -1346,19 +1346,32 @@ static bool CreateDynamicFunction(JSContext* cx, const CallArgs& args, return false; } + JS::RootedVector parameterStrings(cx); + JS::RootedVector parameterArgs(cx); if (args.length() > 1) { RootedString str(cx); unsigned n = args.length() - 1; + if (!parameterStrings.reserve(n) || !parameterArgs.reserve(n)) { + return false; + } for (unsigned i = 0; i < n; i++) { + if (!parameterArgs.append(args[i])) { + return false; + } + str = ToString(cx, args[i]); if (!str) { return false; } + if (!parameterStrings.append(str)) { + return false; + } + if (!sb.append(str)) { return false; @@ -1386,10 +1399,13 @@ static bool CreateDynamicFunction(JSContext* cx, const CallArgs& args, return false; } + JS::RootedValue bodyArg(cx); + RootedString bodyString(cx); if (args.length() > 0) { - RootedString body(cx, ToString(cx, args[args.length() - 1])); - if (!body || !sb.append(body)) { + bodyArg = args[args.length() - 1]; + bodyString = ToString(cx, bodyArg); + if (!bodyString || !sb.append(bodyString)) { return false; } } @@ -1410,7 +1426,14 @@ static bool CreateDynamicFunction(JSContext* cx, const CallArgs& args, } - if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::JS, functionText)) { + bool canCompileStrings = false; + if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::JS, functionText, + JS::CompilationType::Function, + parameterStrings, bodyString, parameterArgs, + bodyArg, &canCompileStrings)) { + return false; + } + if (!canCompileStrings) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_FUNCTION); return false; diff --git a/js/src/wasm/WasmJS.cpp b/js/src/wasm/WasmJS.cpp index c5ebd9ea9a41e..8b31bd6a6fe28 100644 --- a/js/src/wasm/WasmJS.cpp +++ b/js/src/wasm/WasmJS.cpp @@ -1619,7 +1619,16 @@ bool WasmModuleObject::construct(JSContext* cx, unsigned argc, Value* vp) { return false; } - if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) { + JS::RootedVector parameterStrings(cx); + JS::RootedVector parameterArgs(cx); + bool canCompileStrings = false; + if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr, + JS::CompilationType::Undefined, + parameterStrings, nullptr, parameterArgs, + NullHandleValue, &canCompileStrings)) { + return false; + } + if (!canCompileStrings) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_WASM, "WebAssembly.Module"); return false; @@ -4437,7 +4446,16 @@ static bool WebAssembly_compile(JSContext* cx, unsigned argc, Value* vp) { CallArgs callArgs = CallArgsFromVp(argc, vp); - if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) { + JS::RootedVector parameterStrings(cx); + JS::RootedVector parameterArgs(cx); + bool canCompileStrings = false; + if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr, + JS::CompilationType::Undefined, + parameterStrings, nullptr, parameterArgs, + NullHandleValue, &canCompileStrings)) { + return RejectWithPendingException(cx, promise, callArgs); + } + if (!canCompileStrings) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_WASM, "WebAssembly.compile"); return RejectWithPendingException(cx, promise, callArgs); @@ -4521,7 +4539,16 @@ static bool WebAssembly_instantiate(JSContext* cx, unsigned argc, Value* vp) { return false; } } else { - if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) { + JS::RootedVector parameterStrings(cx); + JS::RootedVector parameterArgs(cx); + bool canCompileStrings = false; + if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr, + JS::CompilationType::Undefined, + parameterStrings, nullptr, parameterArgs, + NullHandleValue, &canCompileStrings)) { + return RejectWithPendingException(cx, promise, callArgs); + } + if (!canCompileStrings) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_WASM, "WebAssembly.instantiate"); @@ -5114,7 +5141,16 @@ static bool WebAssembly_compileStreaming(JSContext* cx, unsigned argc, CallArgs callArgs = CallArgsFromVp(argc, vp); - if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) { + JS::RootedVector parameterStrings(cx); + JS::RootedVector parameterArgs(cx); + bool canCompileStrings = false; + if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr, + JS::CompilationType::Undefined, + parameterStrings, nullptr, parameterArgs, + NullHandleValue, &canCompileStrings)) { + return RejectWithPendingException(cx, resultPromise, callArgs); + } + if (!canCompileStrings) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_WASM, "WebAssembly.compileStreaming"); @@ -5147,7 +5183,16 @@ static bool WebAssembly_instantiateStreaming(JSContext* cx, unsigned argc, CallArgs callArgs = CallArgsFromVp(argc, vp); - if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) { + JS::RootedVector parameterStrings(cx); + JS::RootedVector parameterArgs(cx); + bool canCompileStrings = false; + if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr, + JS::CompilationType::Undefined, + parameterStrings, nullptr, parameterArgs, + NullHandleValue, &canCompileStrings)) { + return RejectWithPendingException(cx, resultPromise, callArgs); + } + if (!canCompileStrings) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_WASM, "WebAssembly.instantiateStreaming"); diff --git a/js/src/wasm/WasmModule.cpp b/js/src/wasm/WasmModule.cpp index e01b11c0a120c..afe8131ebc288 100644 --- a/js/src/wasm/WasmModule.cpp +++ b/js/src/wasm/WasmModule.cpp @@ -206,7 +206,16 @@ JSObject* Module::createObject(JSContext* cx) const { return nullptr; } - if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) { + JS::RootedVector parameterStrings(cx); + JS::RootedVector parameterArgs(cx); + bool canCompileStrings = false; + if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr, + JS::CompilationType::Undefined, + parameterStrings, nullptr, parameterArgs, + NullHandleValue, &canCompileStrings)) { + return nullptr; + } + if (!canCompileStrings) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_WASM, "WebAssembly.Module"); return nullptr;