зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1666419: Assert IsSafeToRunScript. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D91391
This commit is contained in:
Родитель
f27594d62e
Коммит
359ca7017e
|
@ -9161,6 +9161,7 @@ nsresult nsContentUtils::NewXULOrHTMLElement(
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
AutoAllowLegacyScriptExecution exemption;
|
||||
AutoEntryScript aes(global, "create custom elements");
|
||||
JSContext* cx = aes.cx();
|
||||
ErrorResult rv;
|
||||
|
|
|
@ -268,6 +268,7 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
|
|||
return;
|
||||
}
|
||||
|
||||
AutoAllowLegacyScriptExecution exemption;
|
||||
mAutoEntryScript.emplace(globalObject, aExecutionReason, mIsMainThread);
|
||||
mAutoEntryScript->SetWebIDLCallerPrincipal(webIDLCallerPrincipal);
|
||||
nsIGlobalObject* incumbent = aCallback->IncumbentGlobalOrNull();
|
||||
|
|
|
@ -101,6 +101,8 @@ void DocumentL10n::TriggerInitialTranslation() {
|
|||
return;
|
||||
}
|
||||
|
||||
AutoAllowLegacyScriptExecution exemption;
|
||||
|
||||
nsTArray<RefPtr<Promise>> promises;
|
||||
|
||||
ErrorResult rv;
|
||||
|
@ -190,6 +192,8 @@ already_AddRefed<Promise> DocumentL10n::TranslateDocument(ErrorResult& aRv) {
|
|||
// back to top->bottom one.
|
||||
nonProtoElements.Reverse();
|
||||
|
||||
AutoAllowLegacyScriptExecution exemption;
|
||||
|
||||
nsTArray<RefPtr<Promise>> promises;
|
||||
|
||||
// 2.1.2. If we're not loading from cache, push the elements that
|
||||
|
|
|
@ -692,6 +692,8 @@ static bool doInvoke(NPObject* npobj, NPIdentifier method,
|
|||
return false;
|
||||
}
|
||||
|
||||
AutoAllowLegacyScriptExecution exemption;
|
||||
|
||||
// We're about to run script via JS_CallFunctionValue, so we need an
|
||||
// AutoEntryScript. NPAPI plugins are Gecko-specific and not in any spec.
|
||||
dom::AutoEntryScript aes(globalObject, "NPAPI doInvoke");
|
||||
|
|
|
@ -174,6 +174,7 @@ class Promise : public SupportsWeakPtr {
|
|||
// Mark a settled promise as already handled so that rejections will not
|
||||
// be reported as unhandled.
|
||||
void SetSettledPromiseIsHandled() {
|
||||
AutoAllowLegacyScriptExecution exemption;
|
||||
AutoEntryScript aes(mGlobal, "Set settled promise handled");
|
||||
JSContext* cx = aes.cx();
|
||||
JS::RootedObject promiseObj(cx, mPromiseObj);
|
||||
|
@ -315,6 +316,7 @@ class Promise : public SupportsWeakPtr {
|
|||
void MaybeSomething(T&& aArgument, MaybeFunc aFunc) {
|
||||
MOZ_ASSERT(PromiseObj()); // It was preserved!
|
||||
|
||||
AutoAllowLegacyScriptExecution exemption;
|
||||
AutoEntryScript aes(mGlobal, "Promise resolution or rejection");
|
||||
JSContext* cx = aes.cx();
|
||||
|
||||
|
|
|
@ -546,6 +546,9 @@ nsresult ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) {
|
|||
}
|
||||
|
||||
nsAutoMicroTask mt;
|
||||
|
||||
AutoAllowLegacyScriptExecution exemption;
|
||||
|
||||
AutoEntryScript aes(globalObject, "CompileModule", true);
|
||||
|
||||
bool oldProcessingScriptTag = context->GetProcessingScriptTag();
|
||||
|
@ -3223,6 +3226,7 @@ void ScriptLoader::GiveUpBytecodeEncoding() {
|
|||
// removal of all request from the current list and these large buffers would
|
||||
// be removed at the same time as the source object.
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject = GetScriptGlobalObject();
|
||||
AutoAllowLegacyScriptExecution exemption;
|
||||
Maybe<AutoEntryScript> aes;
|
||||
|
||||
if (globalObject) {
|
||||
|
|
|
@ -32,6 +32,25 @@ namespace dom {
|
|||
|
||||
static MOZ_THREAD_LOCAL(ScriptSettingsStackEntry*) sScriptSettingsTLS;
|
||||
|
||||
// Assert if it's not safe to run script. The helper class
|
||||
// AutoAllowLegacyScriptExecution allows to allow-list
|
||||
// legacy cases where it's actually not safe to run script.
|
||||
#ifdef DEBUG
|
||||
static void AssertIfNotSafeToRunScript() {
|
||||
// if it's safe to run script, then there is nothing to do here.
|
||||
if (nsContentUtils::IsSafeToRunScript()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// auto allowing legacy script execution is fine for now.
|
||||
if (AutoAllowLegacyScriptExecution::IsAllowed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(false, "is it safe to run script?");
|
||||
}
|
||||
#endif
|
||||
|
||||
class ScriptSettingsStack {
|
||||
public:
|
||||
static ScriptSettingsStackEntry* Top() { return sScriptSettingsTLS.get(); }
|
||||
|
@ -598,6 +617,9 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
|
|||
MOZ_ASSERT(aGlobalObject);
|
||||
|
||||
if (aIsMainThread) {
|
||||
#ifdef DEBUG
|
||||
AssertIfNotSafeToRunScript();
|
||||
#endif
|
||||
if (gRunToCompletionListeners > 0) {
|
||||
mDocShellEntryMonitor.emplace(cx(), aReason);
|
||||
}
|
||||
|
@ -751,4 +773,35 @@ void AutoSlowOperation::CheckForInterrupt() {
|
|||
}
|
||||
}
|
||||
|
||||
AutoAllowLegacyScriptExecution::AutoAllowLegacyScriptExecution() {
|
||||
#ifdef DEBUG
|
||||
// no need to do that dance if we are off the main thread,
|
||||
// because we only assert if we are on the main thread!
|
||||
if (!NS_IsMainThread()) {
|
||||
return;
|
||||
}
|
||||
sAutoAllowLegacyScriptExecution++;
|
||||
#endif
|
||||
}
|
||||
|
||||
AutoAllowLegacyScriptExecution::~AutoAllowLegacyScriptExecution() {
|
||||
#ifdef DEBUG
|
||||
// no need to do that dance if we are off the main thread,
|
||||
// because we only assert if we are on the main thread!
|
||||
if (!NS_IsMainThread()) {
|
||||
return;
|
||||
}
|
||||
sAutoAllowLegacyScriptExecution--;
|
||||
MOZ_ASSERT(sAutoAllowLegacyScriptExecution >= 0,
|
||||
"how can the stack guard produce a value less than 0?");
|
||||
#endif
|
||||
}
|
||||
|
||||
int AutoAllowLegacyScriptExecution::sAutoAllowLegacyScriptExecution = 0;
|
||||
|
||||
/*static*/
|
||||
bool AutoAllowLegacyScriptExecution::IsAllowed() {
|
||||
return sAutoAllowLegacyScriptExecution > 0;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -494,6 +494,22 @@ class MOZ_RAII AutoDisableJSInterruptCallback {
|
|||
bool mOld;
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper class which allows to allow-list legacy callers executing script
|
||||
* in the AutoEntryScript constructor. The goal is to remove these exceptions
|
||||
* one by one. Do not add a new one without review from a DOM peer.
|
||||
*/
|
||||
class MOZ_RAII AutoAllowLegacyScriptExecution {
|
||||
public:
|
||||
AutoAllowLegacyScriptExecution();
|
||||
~AutoAllowLegacyScriptExecution();
|
||||
|
||||
static bool IsAllowed();
|
||||
|
||||
private:
|
||||
static int sAutoAllowLegacyScriptExecution;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_ScriptSettings_h
|
||||
|
|
|
@ -823,6 +823,7 @@ nsresult mozJSComponentLoader::ObjectForLocation(
|
|||
aTableScript.set(script);
|
||||
|
||||
{ // Scope for AutoEntryScript
|
||||
AutoAllowLegacyScriptExecution exemption;
|
||||
|
||||
// We're going to run script via JS_ExecuteScript, so we need an
|
||||
// AutoEntryScript. This is Gecko-specific and not in any spec.
|
||||
|
|
|
@ -332,6 +332,9 @@ nsresult nsXPCWrappedJS::DelegatedQueryInterface(REFNSIID aIID,
|
|||
nsIGlobalObject* nativeGlobal = NativeGlobal(js::UncheckedUnwrap(obj));
|
||||
NS_ENSURE_TRUE(nativeGlobal, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(nativeGlobal->HasJSGlobal(), NS_ERROR_FAILURE);
|
||||
|
||||
AutoAllowLegacyScriptExecution exemption;
|
||||
|
||||
AutoEntryScript aes(nativeGlobal, "XPCWrappedJS QueryInterface",
|
||||
/* aIsMainThread = */ true);
|
||||
XPCCallContext ccx(aes.cx());
|
||||
|
@ -772,6 +775,9 @@ nsXPCWrappedJS::CallMethod(uint16_t methodIndex, const nsXPTMethodInfo* info,
|
|||
// definitely will be when we turn off XPConnect for the web.
|
||||
RootedObject obj(RootingCx(), GetJSObject());
|
||||
nsIGlobalObject* nativeGlobal = NativeGlobal(js::UncheckedUnwrap(obj));
|
||||
|
||||
AutoAllowLegacyScriptExecution exemption;
|
||||
|
||||
AutoEntryScript aes(nativeGlobal, "XPCWrappedJS method call",
|
||||
/* aIsMainThread = */ true);
|
||||
XPCCallContext ccx(aes.cx());
|
||||
|
|
Загрузка…
Ссылка в новой задаче