From ee785714861198a53fe717985e7edceaed104f84 Mon Sep 17 00:00:00 2001 From: Yoav Weiss Date: Tue, 10 Dec 2024 10:33:11 +0100 Subject: [PATCH] Align with HTML and remove support for external importmaps https://bugs.webkit.org/show_bug.cgi?id=284286 Reviewed by NOBODY (OOPS!). This PR removes support for external import maps and ensures they throw an error instead. That would align WebKit's behavior with the HTML standard and other browsers. It also imports a new WPT test that validates the standard requirement this fixes, as well as adjusts relevant WPT results. This adjustment results in some progressions and some regressions. The regressions would be fixed as part of https://github.com/WebKit/standards-positions/issues/381. Upstream commit: https://github.com/web-platform-tests/wpt/commit/ef413686d128045b02cfa4d8de7422c931660bdb * LayoutTests/imported/w3c/web-platform-tests/import-maps/external-import-map-errors-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/import-maps/external-import-map-errors.html: Added. * LayoutTests/imported/w3c/web-platform-tests/import-maps/w3c-import.log: * Source/WebCore/Sources.txt: remove LoadableImportMap * Source/WebCore/WebCore.xcodeproj/project.pbxproj: remove LoadableImportMap * Source/WebCore/dom/LoadableClassicScript.cpp: remove LoadableImportMap logic * Source/WebCore/dom/LoadableImportMap.cpp: Removed. * Source/WebCore/dom/LoadableImportMap.h: Removed. (WebCore::ScriptElement::prepareScript): Fire an error event if an importmap script has a source. (WebCore::ScriptElement::executePendingScript): remove loadableImportMap logic (WebCore::ScriptElement::requestImportMap): Deleted. * Source/WebCore/dom/ScriptElement.h: Remove `requestImportMap`. --- .../external-import-map-errors-expected.txt | 5 ++ .../external-import-map-errors.html | 40 +++++++++++++ .../import-maps/w3c-import.log | 1 + Source/WebCore/Sources.txt | 1 - .../WebCore/WebCore.xcodeproj/project.pbxproj | 6 -- Source/WebCore/dom/LoadableClassicScript.cpp | 1 - Source/WebCore/dom/LoadableImportMap.cpp | 56 ------------------ Source/WebCore/dom/LoadableImportMap.h | 57 ------------------- Source/WebCore/dom/ScriptElement.cpp | 48 ++-------------- Source/WebCore/dom/ScriptElement.h | 1 - 10 files changed, 51 insertions(+), 165 deletions(-) create mode 100644 LayoutTests/imported/w3c/web-platform-tests/import-maps/external-import-map-errors-expected.txt create mode 100644 LayoutTests/imported/w3c/web-platform-tests/import-maps/external-import-map-errors.html delete mode 100644 Source/WebCore/dom/LoadableImportMap.cpp delete mode 100644 Source/WebCore/dom/LoadableImportMap.h diff --git a/LayoutTests/imported/w3c/web-platform-tests/import-maps/external-import-map-errors-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/import-maps/external-import-map-errors-expected.txt new file mode 100644 index 0000000000000..eb201e667f008 --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/import-maps/external-import-map-errors-expected.txt @@ -0,0 +1,5 @@ + +PASS Test that an external import map fires an error event +PASS Test that an external import map fires an error event, regardless of attribute order +PASS Test that an external import map in markup fires an error event + diff --git a/LayoutTests/imported/w3c/web-platform-tests/import-maps/external-import-map-errors.html b/LayoutTests/imported/w3c/web-platform-tests/import-maps/external-import-map-errors.html new file mode 100644 index 0000000000000..ea2a1c058755d --- /dev/null +++ b/LayoutTests/imported/w3c/web-platform-tests/import-maps/external-import-map-errors.html @@ -0,0 +1,40 @@ + + + + + + + + diff --git a/LayoutTests/imported/w3c/web-platform-tests/import-maps/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/import-maps/w3c-import.log index 4b24493e7b04c..d11166410f0f8 100644 --- a/LayoutTests/imported/w3c/web-platform-tests/import-maps/w3c-import.log +++ b/LayoutTests/imported/w3c/web-platform-tests/import-maps/w3c-import.log @@ -19,6 +19,7 @@ List of files: /LayoutTests/imported/w3c/web-platform-tests/import-maps/bare-specifiers.sub.html /LayoutTests/imported/w3c/web-platform-tests/import-maps/data-url-specifiers.sub.html /LayoutTests/imported/w3c/web-platform-tests/import-maps/dynamic-integrity.html +/LayoutTests/imported/w3c/web-platform-tests/import-maps/external-import-map-errors.html /LayoutTests/imported/w3c/web-platform-tests/import-maps/http-url-like-specifiers.sub.html /LayoutTests/imported/w3c/web-platform-tests/import-maps/import-maps-base-url.sub.html /LayoutTests/imported/w3c/web-platform-tests/import-maps/module-map-key.html diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt index 0520888db2758..9bdf4a5916ef0 100644 --- a/Source/WebCore/Sources.txt +++ b/Source/WebCore/Sources.txt @@ -1295,7 +1295,6 @@ dom/InternalObserverTake.cpp dom/KeyboardEvent.cpp dom/LiveNodeList.cpp dom/LoadableClassicScript.cpp -dom/LoadableImportMap.cpp dom/LoadableModuleScript.cpp dom/LoadableScript.cpp dom/MessageChannel.cpp diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj index a75db9fbbd7d9..6cd8c1be414ad 100644 --- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj +++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj @@ -6070,7 +6070,6 @@ E3565B7B1DC2D6C900217DBD /* JSEventCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = E34EE49F1DC2D57500EAA9D3 /* JSEventCustom.h */; settings = {ATTRIBUTES = (Private, ); }; }; E35802B61DC8435D00A9773C /* DOMJITIDLTypeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = E35802B51DC8435800A9773C /* DOMJITIDLTypeFilter.h */; settings = {ATTRIBUTES = (Private, ); }; }; E3582C282527F66900D1B790 /* WebCoreJITOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = E3582C262527F66800D1B790 /* WebCoreJITOperations.h */; settings = {ATTRIBUTES = (Private, ); }; }; - E35B8C6228DD204100293D90 /* LoadableImportMap.h in Headers */ = {isa = PBXBuildFile; fileRef = E35B8C5E28DD202D00293D90 /* LoadableImportMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; E35B907F23F60A50000011FF /* LocalizedDeviceModel.h in Headers */ = {isa = PBXBuildFile; fileRef = E35B907C23F60677000011FF /* LocalizedDeviceModel.h */; settings = {ATTRIBUTES = (Private, ); }; }; E364321C25D37A6700F90E2A /* ModuleScriptLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = E364321A25D37A6600F90E2A /* ModuleScriptLoader.h */; settings = {ATTRIBUTES = (Private, ); }; }; E36A00E429CF7B8600AC4E8A /* TextTrackRepresentationCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 526724F21CB2FDF60075974D /* TextTrackRepresentationCocoa.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -20305,8 +20304,6 @@ E35802B51DC8435800A9773C /* DOMJITIDLTypeFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITIDLTypeFilter.h; sourceTree = ""; }; E3582C242527F66800D1B790 /* WebCoreJITOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebCoreJITOperations.cpp; sourceTree = ""; }; E3582C262527F66800D1B790 /* WebCoreJITOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreJITOperations.h; sourceTree = ""; }; - E35B8C5E28DD202D00293D90 /* LoadableImportMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadableImportMap.h; sourceTree = ""; }; - E35B8C5F28DD202D00293D90 /* LoadableImportMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadableImportMap.cpp; sourceTree = ""; }; E35B907C23F60677000011FF /* LocalizedDeviceModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalizedDeviceModel.h; sourceTree = ""; }; E35B907E23F60677000011FF /* LocalizedDeviceModel.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LocalizedDeviceModel.mm; sourceTree = ""; }; E364321A25D37A6600F90E2A /* ModuleScriptLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleScriptLoader.h; sourceTree = ""; }; @@ -38354,8 +38351,6 @@ CD814C3D2996FAE8005A780A /* LiveNodeListInlines.h */, E3B2F0E31D7F35EC00B0C9D1 /* LoadableClassicScript.cpp */, E3B2F0E41D7F35EC00B0C9D1 /* LoadableClassicScript.h */, - E35B8C5F28DD202D00293D90 /* LoadableImportMap.cpp */, - E35B8C5E28DD202D00293D90 /* LoadableImportMap.h */, E307DED21D81E4ED00141CAF /* LoadableModuleScript.cpp */, E307DED31D81E4ED00141CAF /* LoadableModuleScript.h */, E3B2F0E91D7F3D3C00B0C9D1 /* LoadableScript.cpp */, @@ -42390,7 +42385,6 @@ BC7FA6210D1F0CBD00DB22A9 /* LiveNodeList.h in Headers */, CD814C3E2996FAE8005A780A /* LiveNodeListInlines.h in Headers */, E3B2F0F01D7F4CB500B0C9D1 /* LoadableClassicScript.h in Headers */, - E35B8C6228DD204100293D90 /* LoadableImportMap.h in Headers */, E307DED51D81E4F200141CAF /* LoadableModuleScript.h in Headers */, E3B2F0ED1D7F4CA300B0C9D1 /* LoadableScript.h in Headers */, E3B2F0EE1D7F4CA900B0C9D1 /* LoadableScriptClient.h in Headers */, diff --git a/Source/WebCore/dom/LoadableClassicScript.cpp b/Source/WebCore/dom/LoadableClassicScript.cpp index da7ee16d03181..581a691cd6f34 100644 --- a/Source/WebCore/dom/LoadableClassicScript.cpp +++ b/Source/WebCore/dom/LoadableClassicScript.cpp @@ -29,7 +29,6 @@ #include "DefaultResourceLoadPriority.h" #include "Element.h" #include "FetchIdioms.h" -#include "LoadableImportMap.h" #include "LoadableScriptError.h" #include "ScriptElement.h" #include "ScriptSourceCode.h" diff --git a/Source/WebCore/dom/LoadableImportMap.cpp b/Source/WebCore/dom/LoadableImportMap.cpp deleted file mode 100644 index 2f0ba8ff86afb..0000000000000 --- a/Source/WebCore/dom/LoadableImportMap.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2022 Apple, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "LoadableImportMap.h" - -#include "DefaultResourceLoadPriority.h" -#include "Element.h" -#include "FetchIdioms.h" -#include "ScriptElement.h" -#include "ScriptSourceCode.h" -#include "SubresourceIntegrity.h" -#include -#include - -namespace WebCore { - -Ref LoadableImportMap::create(const AtomString& nonce, const AtomString& integrityMetadata, ReferrerPolicy policy, const AtomString& crossOriginMode, const AtomString& initiatorType, bool isInUserAgentShadowTree, bool isAsync) -{ - return adoptRef(*new LoadableImportMap(nonce, integrityMetadata, policy, crossOriginMode, initiatorType, isInUserAgentShadowTree, isAsync)); -} - -LoadableImportMap::LoadableImportMap(const AtomString& nonce, const AtomString& integrity, ReferrerPolicy policy, const AtomString& crossOriginMode, const AtomString& initiatorType, bool isInUserAgentShadowTree, bool isAsync) - : LoadableNonModuleScriptBase(nonce, integrity, policy, RequestPriority::Auto, crossOriginMode, "utf-8"_s, initiatorType, isInUserAgentShadowTree, isAsync) -{ -} - -void LoadableImportMap::execute(ScriptElement& scriptElement) -{ - ASSERT(!m_error); - scriptElement.registerImportMap(ScriptSourceCode(protectedCachedScript().get(), JSC::SourceProviderSourceType::ImportMap, *this)); -} - -} diff --git a/Source/WebCore/dom/LoadableImportMap.h b/Source/WebCore/dom/LoadableImportMap.h deleted file mode 100644 index 1410d7894b936..0000000000000 --- a/Source/WebCore/dom/LoadableImportMap.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2022 Apple, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include "CachedResourceClient.h" -#include "CachedResourceHandle.h" -#include "CachedScript.h" -#include "Document.h" -#include "LoadableClassicScript.h" -#include "ReferrerPolicy.h" -#include - -namespace WebCore { - -// A CachedResourceHandle alone does not prevent the underlying CachedResource -// from purging its data buffer. This class holds a client until this class is -// destroyed in order to guarantee that the data buffer will not be purged. -class LoadableImportMap final : public LoadableNonModuleScriptBase { -public: - static Ref create(const AtomString& nonce, const AtomString& integrity, ReferrerPolicy, const AtomString& crossOriginMode, const AtomString& initiatorType, bool isInUserAgentShadowTree, bool isAsync); - - ScriptType scriptType() const final { return ScriptType::ImportMap; } - - void execute(ScriptElement&) final; - -private: - LoadableImportMap(const AtomString& nonce, const AtomString& integrity, ReferrerPolicy, const AtomString& crossOriginMode, const AtomString& initiatorType, bool isInUserAgentShadowTree, bool isAsync); -}; - -} - -SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::LoadableImportMap) - static bool isType(const WebCore::LoadableScript& script) { return script.isImportMap(); } -SPECIALIZE_TYPE_TRAITS_END() diff --git a/Source/WebCore/dom/ScriptElement.cpp b/Source/WebCore/dom/ScriptElement.cpp index 626c584ad3fb1..ff5d19df913aa 100644 --- a/Source/WebCore/dom/ScriptElement.cpp +++ b/Source/WebCore/dom/ScriptElement.cpp @@ -42,7 +42,6 @@ #include "IgnoreDestructiveWriteCountIncrementer.h" #include "InlineClassicScript.h" #include "LoadableClassicScript.h" -#include "LoadableImportMap.h" #include "LoadableModuleScript.h" #include "LocalFrame.h" #include "MIMETypeRegistry.h" @@ -266,11 +265,11 @@ bool ScriptElement::prepareScript(const TextPosition& scriptStartPosition) } frame->script().setAcquiringImportMaps(); if (hasSourceAttribute()) { - if (!requestImportMap(*frame, sourceAttributeValue())) - return false; - potentiallyBlockRendering(); - } else - frame->script().setPendingImportMaps(); + element->document().eventLoop().queueTask(TaskSource::DOMManipulation, [this, element] { + dispatchErrorEvent(); + }); + return false; + } break; } } @@ -419,39 +418,6 @@ bool ScriptElement::requestModuleScript(const TextPosition& scriptStartPosition) return true; } -bool ScriptElement::requestImportMap(LocalFrame& frame, const String& sourceURL) -{ - Ref element = this->element(); - Ref document = element->document(); - - ASSERT(element->isConnected()); - ASSERT(!m_loadableScript); - if (!StringView(sourceURL).containsOnly>()) { - Ref script = LoadableImportMap::create(element->nonce(), element->attributeWithoutSynchronization(HTMLNames::integrityAttr), referrerPolicy(), - element->attributeWithoutSynchronization(HTMLNames::crossoriginAttr), element->localName(), element->isInUserAgentShadowTree(), hasAsyncAttribute()); - - auto scriptURL = document->completeURL(sourceURL); - document->willLoadScriptElement(scriptURL); - - if (!document->checkedContentSecurityPolicy()->allowNonParserInsertedScripts(scriptURL, URL(), m_startLineNumber, element->nonce(), script->integrity(), String(), m_parserInserted)) - return false; - - frame.checkedScript()->setPendingImportMaps(); - if (script->load(document, scriptURL)) { - m_loadableScript = WTFMove(script); - m_isExternalScript = true; - } - } - - if (m_loadableScript) - return true; - - document->checkedEventLoop()->queueTask(TaskSource::DOMManipulation, [this, element] { - dispatchErrorEvent(); - }); - return false; -} - void ScriptElement::executeClassicScript(const ScriptSourceCode& sourceCode) { RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(ScriptDisallowedScope::InMainThread::isScriptAllowed()); @@ -609,10 +575,6 @@ void ScriptElement::executePendingScript(PendingScript& pendingScript) RefPtr document { &element().document() }; if (document->identifier() != m_preparationTimeDocumentIdentifier) { document->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Not executing script because it moved between documents during fetching"_s); - if (loadableScript) { - if (auto* loadableImportMap = dynamicDowncast(loadableScript)) - document = loadableImportMap->document(); - } } else { if (loadableScript) executeScriptAndDispatchEvent(*loadableScript); diff --git a/Source/WebCore/dom/ScriptElement.h b/Source/WebCore/dom/ScriptElement.h index 62c4afcbadae9..acdaa0464337a 100644 --- a/Source/WebCore/dom/ScriptElement.h +++ b/Source/WebCore/dom/ScriptElement.h @@ -123,7 +123,6 @@ class ScriptElement { bool requestClassicScript(const String& sourceURL); bool requestModuleScript(const TextPosition& scriptStartPosition); - bool requestImportMap(LocalFrame&, const String& sourceURL); void updateTaintedOriginFromSourceURL();