зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1789543 - Part 3: Trigger missing chrome/resource URL error handling with original JSM URL when fallback to ESMified URL also fails. r=yulia
Depends on D156763 Differential Revision: https://phabricator.services.mozilla.com/D156764
This commit is contained in:
Родитель
ce2d3ed35b
Коммит
e8ade43d3f
|
@ -10,6 +10,8 @@
|
|||
#include "js/loader/LoadContextBase.h"
|
||||
#include "js/loader/ModuleLoaderBase.h"
|
||||
|
||||
#include "SkipCheckForBrokenURLOrZeroSized.h"
|
||||
|
||||
class mozJSModuleLoader;
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -103,6 +105,8 @@ class ComponentLoadContext : public JS::loader::LoadContextBase {
|
|||
// before being passed to the module loader.
|
||||
nsresult mRv;
|
||||
|
||||
SkipCheckForBrokenURLOrZeroSized mSkipCheck;
|
||||
|
||||
// The exception thrown during compiling a module script. These fields are
|
||||
// used temporarily before being passed to the module loader.
|
||||
JS::PersistentRooted<JS::Value> mExceptionValue;
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_loader_SkipCheckForBrokenURLOrZeroSized_h
|
||||
#define mozilla_loader_SkipCheckForBrokenURLOrZeroSized_h
|
||||
|
||||
#include <stdint.h> // uint8_t
|
||||
|
||||
namespace mozilla {
|
||||
namespace loader {
|
||||
|
||||
// Represents the `aSkipCheckForBrokenURLOrZeroSized` parameter for
|
||||
// `NS_NewChannel` function.
|
||||
enum class SkipCheckForBrokenURLOrZeroSized : uint8_t { No, Yes };
|
||||
|
||||
} // namespace loader
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_loader_SkipCheckForBrokenURLOrZeroSized_h
|
|
@ -45,6 +45,7 @@ EXPORTS.mozilla.loader += [
|
|||
"AutoMemMap.h",
|
||||
"ComponentModuleLoader.h",
|
||||
"ScriptCacheActors.h",
|
||||
"SkipCheckForBrokenURLOrZeroSized.h",
|
||||
]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
|
|
|
@ -289,10 +289,25 @@ mozJSModuleLoader::mozJSModuleLoader()
|
|||
|
||||
class MOZ_STACK_CLASS ModuleLoaderInfo {
|
||||
public:
|
||||
explicit ModuleLoaderInfo(const nsACString& aLocation)
|
||||
: mLocation(&aLocation), mIsModule(false) {}
|
||||
explicit ModuleLoaderInfo(const nsACString& aLocation,
|
||||
SkipCheckForBrokenURLOrZeroSized aSkipCheck =
|
||||
SkipCheckForBrokenURLOrZeroSized::No)
|
||||
: mLocation(&aLocation), mIsModule(false), mSkipCheck(aSkipCheck) {}
|
||||
explicit ModuleLoaderInfo(JS::loader::ModuleLoadRequest* aRequest)
|
||||
: mLocation(nullptr), mURI(aRequest->mURI), mIsModule(true) {}
|
||||
: mLocation(nullptr),
|
||||
mURI(aRequest->mURI),
|
||||
mIsModule(true),
|
||||
mSkipCheck(aRequest->GetComponentLoadContext()->mSkipCheck) {}
|
||||
|
||||
SkipCheckForBrokenURLOrZeroSized getSkipCheckForBrokenURLOrZeroSized() const {
|
||||
return mSkipCheck;
|
||||
}
|
||||
|
||||
void resetChannelWithCheckForBrokenURLOrZeroSized() {
|
||||
MOZ_ASSERT(mSkipCheck == SkipCheckForBrokenURLOrZeroSized::Yes);
|
||||
mSkipCheck = SkipCheckForBrokenURLOrZeroSized::No;
|
||||
mScriptChannel = nullptr;
|
||||
}
|
||||
|
||||
nsIIOService* IOService() {
|
||||
MOZ_ASSERT(mIOService);
|
||||
|
@ -325,14 +340,7 @@ class MOZ_STACK_CLASS ModuleLoaderInfo {
|
|||
nsresult EnsureScriptChannel() {
|
||||
BEGIN_ENSURE(ScriptChannel, IOService, URI);
|
||||
|
||||
// The JSM may already be ESM-ified, and in that case the load is expected
|
||||
// to fail. Suppress the error message, the crash, and also the telemetry
|
||||
// event for the failure.
|
||||
//
|
||||
// If this load fails, it will be redirected to `.sys.mjs` URL
|
||||
// in TryFallbackToImportESModule, and the check is performed there.
|
||||
bool skipCheckForBrokenURLOrZeroSized = !IsModule();
|
||||
|
||||
// Skip check for missing URL when handling JSM-to-ESM fallback.
|
||||
return NS_NewChannel(
|
||||
getter_AddRefs(mScriptChannel), mURI,
|
||||
nsContentUtils::GetSystemPrincipal(),
|
||||
|
@ -342,7 +350,7 @@ class MOZ_STACK_CLASS ModuleLoaderInfo {
|
|||
/* aPerformanceStorage = */ nullptr,
|
||||
/* aLoadGroup = */ nullptr, /* aCallbacks = */ nullptr,
|
||||
nsIRequest::LOAD_NORMAL, mIOService, /* aSandboxFlags = */ 0,
|
||||
skipCheckForBrokenURLOrZeroSized);
|
||||
mSkipCheck == SkipCheckForBrokenURLOrZeroSized::Yes);
|
||||
}
|
||||
|
||||
nsIURI* ResolvedURI() {
|
||||
|
@ -374,6 +382,7 @@ class MOZ_STACK_CLASS ModuleLoaderInfo {
|
|||
nsCOMPtr<nsIChannel> mScriptChannel;
|
||||
nsCOMPtr<nsIURI> mResolvedURI;
|
||||
const bool mIsModule;
|
||||
SkipCheckForBrokenURLOrZeroSized mSkipCheck;
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
|
@ -1394,7 +1403,14 @@ nsresult mozJSModuleLoader::Import(JSContext* aCx, const nsACString& aLocation,
|
|||
MarkerInnerWindowIdFromJSContext(aCx)),
|
||||
aLocation);
|
||||
|
||||
ModuleLoaderInfo info(aLocation);
|
||||
// The JSM may already be ESM-ified, and in that case the load is expected
|
||||
// to fail. Suppress the error message, the crash, and also the telemetry
|
||||
// event for the failure.
|
||||
//
|
||||
// If this load fails, it will be redirected to `.sys.mjs` URL
|
||||
// in TryFallbackToImportESModule, and if the redirect also fails,
|
||||
// the load is performed again below, with the check enabled.
|
||||
ModuleLoaderInfo info(aLocation, SkipCheckForBrokenURLOrZeroSized::Yes);
|
||||
|
||||
nsresult rv;
|
||||
ModuleEntry* mod;
|
||||
|
@ -1467,8 +1483,23 @@ nsresult mozJSModuleLoader::Import(JSContext* aCx, const nsACString& aLocation,
|
|||
}
|
||||
|
||||
if (rv == NS_ERROR_FILE_NOT_FOUND) {
|
||||
return TryFallbackToImportESModule(aCx, aLocation, aModuleGlobal,
|
||||
aModuleExports, aIgnoreExports);
|
||||
rv = TryFallbackToImportESModule(aCx, aLocation, aModuleGlobal,
|
||||
aModuleExports, aIgnoreExports);
|
||||
|
||||
if (rv == NS_ERROR_FILE_NOT_FOUND) {
|
||||
// Both JSM and ESM are not found, with the check inside necko
|
||||
// skipped (See EnsureScriptChannel and mSkipCheck).
|
||||
//
|
||||
// Perform the load again with the check enabled, so that
|
||||
// logging, crash-on-autonation, and telemetry event happen.
|
||||
if (NS_SUCCEEDED(info.EnsureURI()) &&
|
||||
!LocationIsRealFile(info.URI())) {
|
||||
info.resetChannelWithCheckForBrokenURLOrZeroSized();
|
||||
(void)ReadScript(info);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Something failed, but we don't know what it is, guess.
|
||||
|
@ -1526,7 +1557,10 @@ nsresult mozJSModuleLoader::TryFallbackToImportESModule(
|
|||
}
|
||||
|
||||
JS::RootedObject moduleNamespace(aCx);
|
||||
nsresult rv = ImportESModule(aCx, mjsLocation, &moduleNamespace);
|
||||
// The fallback can fail if the URL was not for ESMified JSM. Suppress the
|
||||
// error message, the crash, and also the telemetry event for the failure.
|
||||
nsresult rv = ImportESModule(aCx, mjsLocation, &moduleNamespace,
|
||||
SkipCheckForBrokenURLOrZeroSized::Yes);
|
||||
if (rv == NS_ERROR_FILE_NOT_FOUND) {
|
||||
// The error for ESModule shouldn't be exposed if the file does not exist.
|
||||
if (JS_IsExceptionPending(aCx)) {
|
||||
|
@ -1605,7 +1639,9 @@ nsresult mozJSModuleLoader::TryCachedFallbackToImportESModule(
|
|||
|
||||
nsresult mozJSModuleLoader::ImportESModule(
|
||||
JSContext* aCx, const nsACString& aLocation,
|
||||
JS::MutableHandleObject aModuleNamespace) {
|
||||
JS::MutableHandleObject aModuleNamespace,
|
||||
SkipCheckForBrokenURLOrZeroSized
|
||||
aSkipCheck /* = SkipCheckForBrokenURLOrZeroSized::No */) {
|
||||
using namespace JS::loader;
|
||||
|
||||
MOZ_ASSERT(mModuleLoader);
|
||||
|
@ -1643,6 +1679,7 @@ nsresult mozJSModuleLoader::ImportESModule(
|
|||
CORS_NONE, dom::ReferrerPolicy::No_referrer, principal);
|
||||
|
||||
RefPtr<ComponentLoadContext> context = new ComponentLoadContext();
|
||||
context->mSkipCheck = aSkipCheck;
|
||||
|
||||
RefPtr<VisitedURLSet> visitedSet =
|
||||
ModuleLoadRequest::NewVisitedSetForTopLevelImport(uri);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "nsClassHashtable.h"
|
||||
#include "jsapi.h"
|
||||
#include "js/experimental/JSStencil.h"
|
||||
#include "SkipCheckForBrokenURLOrZeroSized.h"
|
||||
|
||||
#include "xpcpublic.h"
|
||||
|
||||
|
@ -75,8 +76,11 @@ class mozJSModuleLoader final : public nsIMemoryReporter {
|
|||
bool aIgnoreExports = false);
|
||||
|
||||
// Load an ES6 module and all its dependencies.
|
||||
nsresult ImportESModule(JSContext* aCx, const nsACString& aResourceURI,
|
||||
JS::MutableHandleObject aModuleNamespace);
|
||||
nsresult ImportESModule(
|
||||
JSContext* aCx, const nsACString& aResourceURI,
|
||||
JS::MutableHandleObject aModuleNamespace,
|
||||
mozilla::loader::SkipCheckForBrokenURLOrZeroSized aSkipCheck =
|
||||
mozilla::loader::SkipCheckForBrokenURLOrZeroSized::No);
|
||||
|
||||
// Fallback from Import to ImportESModule.
|
||||
nsresult TryFallbackToImportESModule(JSContext* aCx,
|
||||
|
|
Загрузка…
Ссылка в новой задаче