diff options
author | Gaming4JC <g4jc@hyperbola.info> | 2020-08-03 10:44:39 -0400 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2020-08-30 09:36:51 +0000 |
commit | 9982c1f5cb3dfe361b9e9d21e5582a5e35d4c7fb (patch) | |
tree | 0f2307c192d928209ab930ad0d9d676a99747995 /dom/script/ScriptLoader.cpp | |
parent | fe912e94e44c4a6dfac1a75c265084f77adfd6ae (diff) | |
download | UXP-9982c1f5cb3dfe361b9e9d21e5582a5e35d4c7fb.tar UXP-9982c1f5cb3dfe361b9e9d21e5582a5e35d4c7fb.tar.gz UXP-9982c1f5cb3dfe361b9e9d21e5582a5e35d4c7fb.tar.lz UXP-9982c1f5cb3dfe361b9e9d21e5582a5e35d4c7fb.tar.xz UXP-9982c1f5cb3dfe361b9e9d21e5582a5e35d4c7fb.zip |
Issue #618 - Keep track of which modules in a graph have been fetched using a visited set
Ref: BZ 1365187
Diffstat (limited to 'dom/script/ScriptLoader.cpp')
-rw-r--r-- | dom/script/ScriptLoader.cpp | 93 |
1 files changed, 36 insertions, 57 deletions
diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index 7d5a19faf..7a3cd8fe3 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -501,7 +501,7 @@ ScriptLoader::ProcessFetchedModuleSource(ModuleLoadRequest* aRequest) } static nsresult -ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI>& aUrls); +ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI>* aUrlsOut); nsresult ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) @@ -577,8 +577,7 @@ ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) // Validate requested modules and treat failure to resolve module specifiers // the same as a parse error. - nsCOMArray<nsIURI> urls; - rv = ResolveRequestedModules(aRequest, urls); + rv = ResolveRequestedModules(aRequest, nullptr); if (NS_FAILED(rv)) { aRequest->ModuleErrored(); return NS_OK; @@ -665,33 +664,7 @@ ResolveModuleSpecifier(ModuleScript* aScript, } static nsresult -RequestedModuleIsInAncestorList(ModuleLoadRequest* aRequest, nsIURI* aURL, bool* aResult) -{ - const size_t ImportDepthLimit = 100; - - *aResult = false; - size_t depth = 0; - while (aRequest) { - if (depth++ == ImportDepthLimit) { - return NS_ERROR_FAILURE; - } - - bool equal; - nsresult rv = aURL->Equals(aRequest->mURI, &equal); - NS_ENSURE_SUCCESS(rv, rv); - if (equal) { - *aResult = true; - return NS_OK; - } - - aRequest = aRequest->mParent; - } - - return NS_OK; -} - -static nsresult -ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI> &aUrls) +ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI>* aUrlsOut) { ModuleScript* ms = aRequest->mModuleScript; @@ -728,11 +701,8 @@ ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI> &aUrls) return NS_ERROR_FAILURE; } - bool isAncestor; - nsresult rv = RequestedModuleIsInAncestorList(aRequest, uri, &isAncestor); - NS_ENSURE_SUCCESS(rv, rv); - if (!isAncestor) { - aUrls.AppendElement(uri.forget()); + if (aUrlsOut) { + aUrlsOut->AppendElement(uri.forget()); } } @@ -746,17 +716,33 @@ ScriptLoader::StartFetchingModuleDependencies(ModuleLoadRequest* aRequest) MOZ_ASSERT(!aRequest->mModuleScript->HasParseError()); MOZ_ASSERT(!aRequest->IsReadyToRun()); + auto visitedSet = aRequest->mVisitedSet; + MOZ_ASSERT(visitedSet->Contains(aRequest->mURI)); + aRequest->mProgress = ModuleLoadRequest::Progress::FetchingImports; nsCOMArray<nsIURI> urls; - nsresult rv = ResolveRequestedModules(aRequest, urls); + nsresult rv = ResolveRequestedModules(aRequest, &urls); if (NS_FAILED(rv)) { aRequest->ModuleErrored(); return; } - if (urls.Length() == 0) { - // There are no descendents to load so this request is ready. + // Remove already visited URLs from the list. Put unvisited URLs into the + // visited set. + int32_t i = 0; + while (i < urls.Count()) { + nsIURI* url = urls[i]; + if (visitedSet->Contains(url)) { + urls.RemoveObjectAt(i); + } else { + visitedSet->PutEntry(url); + i++; + } + } + + if (urls.Count() == 0) { + // There are no descendants to load so this request is ready. aRequest->DependenciesLoaded(); return; } @@ -779,21 +765,14 @@ ScriptLoader::StartFetchingModuleDependencies(ModuleLoadRequest* aRequest) } RefPtr<GenericPromise> -ScriptLoader::StartFetchingModuleAndDependencies(ModuleLoadRequest* aRequest, +ScriptLoader::StartFetchingModuleAndDependencies(ModuleLoadRequest* aParent, nsIURI* aURI) { MOZ_ASSERT(aURI); - RefPtr<ModuleLoadRequest> childRequest = - new ModuleLoadRequest(aRequest->mElement, aRequest->mJSVersion, - aRequest->mCORSMode, aRequest->mIntegrity, this); + RefPtr<ModuleLoadRequest> childRequest = new ModuleLoadRequest(aURI, aParent); - childRequest->mIsTopLevel = false; - childRequest->mURI = aURI; - childRequest->mIsInline = false; - childRequest->mReferrerPolicy = aRequest->mReferrerPolicy; - childRequest->mParent = aRequest; - aRequest->mImports.AppendElement(childRequest); + aParent->mImports.AppendElement(childRequest); RefPtr<GenericPromise> ready = childRequest->mReady.Ensure(__func__); @@ -1201,17 +1180,19 @@ CSPAllowsInlineScript(nsIScriptElement *aElement, nsIDocument *aDocument) ScriptLoadRequest* ScriptLoader::CreateLoadRequest(ScriptKind aKind, + nsIURI* aURI, nsIScriptElement* aElement, uint32_t aVersion, CORSMode aCORSMode, const SRIMetadata &aIntegrity) { if (aKind == ScriptKind::Classic) { - return new ScriptLoadRequest(aKind, aElement, aVersion, aCORSMode, + return new ScriptLoadRequest(aKind, aURI, aElement, + aVersion,aCORSMode, aIntegrity); } MOZ_ASSERT(aKind == ScriptKind::Module); - return new ModuleLoadRequest(aElement, aVersion, aCORSMode, aIntegrity, this); + return new ModuleLoadRequest(aURI, aElement, aVersion, aCORSMode, aIntegrity, this); } bool @@ -1343,9 +1324,8 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) } } - request = CreateLoadRequest(scriptKind, aElement, version, ourCORSMode, - sriMetadata); - request->mURI = scriptURI; + request = CreateLoadRequest(scriptKind, scriptURI, aElement, + version, ourCORSMode, sriMetadata); request->mIsInline = false; request->mReferrerPolicy = ourRefPolicy; @@ -1466,11 +1446,11 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) } // Inline scripts ignore ther CORS mode and are always CORS_NONE - request = CreateLoadRequest(scriptKind, aElement, version, CORS_NONE, + request = CreateLoadRequest(scriptKind, mDocument->GetDocumentURI(), aElement, + version, CORS_NONE, SRIMetadata()); // SRI doesn't apply request->mJSVersion = version; request->mIsInline = true; - request->mURI = mDocument->GetDocumentURI(); request->mLineNo = aElement->GetScriptLineNumber(); if (request->IsModuleRequest()) { @@ -2603,9 +2583,8 @@ ScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset, } RefPtr<ScriptLoadRequest> request = - CreateLoadRequest(ScriptKind::Classic, nullptr, 0, + CreateLoadRequest(ScriptKind::Classic, aURI, nullptr, 0, Element::StringToCORSMode(aCrossOrigin), sriMetadata); - request->mURI = aURI; request->mIsInline = false; request->mReferrerPolicy = aReferrerPolicy; |