Diff
Modified: trunk/LayoutTests/ChangeLog (245624 => 245625)
--- trunk/LayoutTests/ChangeLog 2019-05-22 17:31:06 UTC (rev 245624)
+++ trunk/LayoutTests/ChangeLog 2019-05-22 17:38:42 UTC (rev 245625)
@@ -1,3 +1,13 @@
+2019-05-22 Youenn Fablet <[email protected]>
+
+ Implement Feature policy self/none/* parsing
+ https://bugs.webkit.org/show_bug.cgi?id=198078
+
+ Reviewed by Eric Carlson.
+
+ * http/tests/media/media-stream/get-display-media-iframe-allow-attribute-expected.txt:
+ * http/tests/media/media-stream/get-display-media-iframe-allow-attribute.html:
+
2019-05-22 Alicia Boya GarcĂa <[email protected]>
[GTK] Unreviewed test gardening
Modified: trunk/LayoutTests/http/tests/media/media-stream/get-display-media-iframe-allow-attribute-expected.txt (245624 => 245625)
--- trunk/LayoutTests/http/tests/media/media-stream/get-display-media-iframe-allow-attribute-expected.txt 2019-05-22 17:31:06 UTC (rev 245624)
+++ trunk/LayoutTests/http/tests/media/media-stream/get-display-media-iframe-allow-attribute-expected.txt 2019-05-22 17:38:42 UTC (rev 245625)
@@ -5,5 +5,5 @@
PASS: <iframe allow=''> got "deny"
PASS: <iframe allow='camera'> got "deny"
-PASS: <iframe allow='display'> got "allow"
+PASS: <iframe allow='display-capture'> got "allow"
PASS: <iframe allow='microphone'> got "deny"
Modified: trunk/LayoutTests/http/tests/media/media-stream/get-display-media-iframe-allow-attribute.html (245624 => 245625)
--- trunk/LayoutTests/http/tests/media/media-stream/get-display-media-iframe-allow-attribute.html 2019-05-22 17:31:06 UTC (rev 245624)
+++ trunk/LayoutTests/http/tests/media/media-stream/get-display-media-iframe-allow-attribute.html 2019-05-22 17:38:42 UTC (rev 245625)
@@ -5,7 +5,7 @@
<iframe id="none" src=""
<iframe id="camera" allow="camera" src=""
<iframe id="microphone" allow="microphone" src=""
- <iframe id="display" allow="display" src=""
+ <iframe id="display" allow="display-capture" src=""
<script>
if (window.testRunner) {
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (245624 => 245625)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2019-05-22 17:31:06 UTC (rev 245624)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2019-05-22 17:38:42 UTC (rev 245625)
@@ -1,3 +1,13 @@
+2019-05-22 Youenn Fablet <[email protected]>
+
+ Implement Feature policy self/none/* parsing
+ https://bugs.webkit.org/show_bug.cgi?id=198078
+
+ Reviewed by Eric Carlson.
+
+ * web-platform-tests/mediacapture-streams/MediaStream-feature-policy-none.https-expected.txt: Added.
+ * web-platform-tests/mediacapture-streams/MediaStream-feature-policy-none.https.html: Added.
+
2019-05-21 Antoine Quint <[email protected]>
[macOS] Compatibility mouse events aren't prevented by calling preventDefault() on pointerdown
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-feature-policy-none.https-expected.txt (0 => 245625)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-feature-policy-none.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-feature-policy-none.https-expected.txt 2019-05-22 17:38:42 UTC (rev 245625)
@@ -0,0 +1,48 @@
+CONSOLE MESSAGE: line 43: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 49: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 37: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 43: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 49: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 37: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 49: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 37: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 43: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 49: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 37: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 49: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 37: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 49: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 43: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 49: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 37: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 49: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 43: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 49: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 43: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 49: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 43: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 49: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 37: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 49: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 43: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+CONSOLE MESSAGE: line 49: Trying to call getUserMedia from a frame without correct 'allow' attribute.
+
+PASS "camera 'none'" - same origin iframe
+PASS "camera 'none'" - cross origin iframe
+PASS "microphone 'none'" - same origin iframe
+PASS "microphone 'none';camera 'none'" - same origin iframe
+PASS "camera *;microphone 'none'" - same origin iframe
+PASS "camera *;microphone 'none'" - cross origin iframe
+PASS "camera 'none';microphone *" - same origin iframe
+PASS "microphone *; microphone 'none'" - same origin iframe
+PASS "microphone *; microphone ' none'" - same origin iframe
+PASS "microphone *; microphone none" - same origin iframe
+PASS "microphone *; camera 'self'" - same origin iframe
+PASS "microphone *; camera 'self'" - cross origin iframe
+PASS "microphone *; camera http:/example.org self" - same origin iframe
+PASS "microphone *; camera http:/example.org 'self'" - same origin iframe
+PASS "microphone *; camera http:/example.org 'self'" - cross origin iframe
+PASS "microphone https://127.0.0.1:9443" - same origin iframe
+PASS "microphone https://127.0.0.1:9443" - cross origin iframe
+PASS "microphone 'self' https://127.0.0.1:9443" - same origin iframe
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-feature-policy-none.https.html (0 => 245625)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-feature-policy-none.https.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-feature-policy-none.https.html 2019-05-22 17:38:42 UTC (rev 245625)
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<body>
+ <script src=""
+ <script src=""
+ <script src=""
+ <script>
+function withIFrame(url, allow) {
+ return new Promise(resolve => {
+ let frame = document.createElement('iframe');
+ frame.src = ""
+ frame.allow = allow;
+ frame._onload_ = () => { resolve(frame); };
+ document.body.appendChild(frame);
+ });
+}
+
+var crossDomain = get_host_info().HTTPS_REMOTE_ORIGIN;
+function runTestInIFrame(allow, crossOrigin)
+{
+ return new Promise(async resolve => {
+ window.addEventListener('message', function handler(event) {
+ resolve(event.data);
+ window.removeEventListener('message', handler);
+ iframe.remove();
+ });
+ let url = "" + "#test";
+ if (crossOrigin)
+ url = "" + url;
+ const iframe = await withIFrame(url, allow);
+ });
+}
+
+async function doTest()
+{
+ let results = { };
+ try {
+ await navigator.mediaDevices.getUserMedia({audio : true});
+ results.audio = true;
+ } catch (e) {
+ results.audio = false;
+ }
+ try {
+ await navigator.mediaDevices.getUserMedia({video : true});
+ results.video = true;
+ } catch (e) {
+ results.video = false;
+ }
+ try {
+ await navigator.mediaDevices.getUserMedia({audio : true, video : true});
+ results.audioVideo = true;
+ } catch (e) {
+ results.audioVideo = false;
+ }
+ return results;
+}
+
+if (location.hash == "#test") {
+ doTest().then(data ="" {
+ parent.postMessage(data, '*');
+ }, error => {
+ parent.postMessage('error', '*');
+ });
+} else {
+ var gum_tests = [
+ { allow: "camera 'none'", results: { audio: true, video: false, audioVideo: false } },
+ { allow: "camera 'none'", results: { audio: false, video: false, audioVideo: false }, crossOrigin: true },
+ { allow: "microphone 'none'", results: { audio: false, video: true, audioVideo: false } },
+ { allow: "microphone 'none';camera 'none'", results: { audio: false, video: false, audioVideo: false } },
+ { allow: "camera *;microphone 'none'", results: { audio: false, video: true, audioVideo: false } },
+ { allow: "camera *;microphone 'none'", results: { audio: false, video: true, audioVideo: false }, crossOrigin: true },
+ { allow: "camera 'none';microphone *", results: { audio: true, video: false, audioVideo: false } },
+ { allow: "microphone *; microphone 'none'", results: { audio: false, video: true, audioVideo: false } },
+ { allow: "microphone *; microphone ' none'", results: { audio: true, video: true, audioVideo: true } },
+ { allow: "microphone *; microphone none", results: { audio: true, video: true, audioVideo: true } },
+ { allow: "microphone *; camera 'self'", results: { audio: true, video: true, audioVideo: true } },
+ { allow: "microphone *; camera 'self'", results: { audio: true, video: false, audioVideo: false }, crossOrigin: true },
+ { allow: "microphone *; camera http:/example.org self", results: { audio: true, video: false, audioVideo: false } },
+ { allow: "microphone *; camera http:/example.org 'self'", results: { audio: true, video: true, audioVideo: true } },
+ { allow: "microphone *; camera http:/example.org 'self'", results: { audio: true, video: false, audioVideo: false }, crossOrigin: true },
+ { allow: "microphone " + crossDomain, results: { audio: false, video: true, audioVideo: false } },
+ { allow: "microphone " + crossDomain, results: { audio: true, video: false, audioVideo: false }, crossOrigin: true },
+ { allow: "microphone 'self' " + crossDomain, results: { audio: true, video: true, audioVideo: true } },
+ ];
+
+ for (let gum_test of gum_tests) {
+ promise_test(async (test) => {
+ const results = await runTestInIFrame(gum_test.allow, gum_test.crossOrigin);
+ assert_equals(results.audio, gum_test.results.audio, "audio");
+ assert_equals(results.video, gum_test.results.video, "video");
+ assert_equals(results.audioVideo, gum_test.results.audioVideo, "audioVideo");
+ }, "\"" + gum_test.allow + "\" - " + (gum_test.crossOrigin ? "cross origin iframe" : "same origin iframe"));
+ }
+}
+ </script>
+</body>
+
Modified: trunk/Source/WebCore/ChangeLog (245624 => 245625)
--- trunk/Source/WebCore/ChangeLog 2019-05-22 17:31:06 UTC (rev 245624)
+++ trunk/Source/WebCore/ChangeLog 2019-05-22 17:38:42 UTC (rev 245625)
@@ -1,3 +1,35 @@
+2019-05-22 Youenn Fablet <[email protected]>
+
+ Implement Feature policy self/none/* parsing
+ https://bugs.webkit.org/show_bug.cgi?id=198078
+
+ Reviewed by Eric Carlson.
+
+ Start to implement https://w3c.github.io/webappsec-feature-policy/#algo-parse-policy-directive
+ 'src' is not supported yet.
+ Apply the rules to getUserMedia.
+ Update getDisplayMedia keyword from 'display' to 'display-capture' as per spec.
+
+ Test: imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-feature-policy-none.https.html
+
+ * Headers.cmake:
+ * Modules/mediastream/UserMediaController.cpp:
+ (WebCore::isSecure):
+ (WebCore::isAllowedByFeaturePolicy):
+ (WebCore::isAllowedToUse):
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * html/FeaturePolicy.cpp: Added.
+ (WebCore::isAllowedByFeaturePolicy):
+ (WebCore::processOriginItem):
+ (WebCore::updateList):
+ (WebCore::FeaturePolicy::parse):
+ (WebCore::FeaturePolicy::allows const):
+ * html/FeaturePolicy.h: Added.
+ * html/HTMLIFrameElement.cpp:
+ (WebCore::HTMLIFrameElement::featurePolicy const):
+ * html/HTMLIFrameElement.h:
+
2019-05-21 Jer Noble <[email protected]>
Media controls don't show in WK2 video fullscreen sometimes
Modified: trunk/Source/WebCore/Headers.cmake (245624 => 245625)
--- trunk/Source/WebCore/Headers.cmake 2019-05-22 17:31:06 UTC (rev 245624)
+++ trunk/Source/WebCore/Headers.cmake 2019-05-22 17:38:42 UTC (rev 245625)
@@ -526,6 +526,7 @@
html/CollectionType.h
html/DOMTokenList.h
html/DataListSuggestionInformation.h
+ html/FeaturePolicy.h
html/FormAssociatedElement.h
html/FormNamedItem.h
html/HTMLAnchorElement.h
Modified: trunk/Source/WebCore/Modules/mediastream/UserMediaController.cpp (245624 => 245625)
--- trunk/Source/WebCore/Modules/mediastream/UserMediaController.cpp 2019-05-22 17:31:06 UTC (rev 245624)
+++ trunk/Source/WebCore/Modules/mediastream/UserMediaController.cpp 2019-05-22 17:38:42 UTC (rev 245625)
@@ -61,7 +61,7 @@
UserMediaController::provideTo(page, UserMediaController::supplementName(), std::make_unique<UserMediaController>(client));
}
-static bool isSecure(DocumentLoader& documentLoader)
+static inline bool isSecure(DocumentLoader& documentLoader)
{
auto& response = documentLoader.response();
if (SecurityOrigin::isLocalHostOrLoopbackIPAddress(documentLoader.response().url().host()))
@@ -71,6 +71,20 @@
&& !response.certificateInfo()->containsNonRootSHA1SignedCertificate();
}
+static inline bool isAllowedByFeaturePolicy(const FeaturePolicy& featurePolicy, const SecurityOriginData& origin, OptionSet<UserMediaController::CaptureType> types)
+{
+ if ((types & UserMediaController::CaptureType::Camera) && !featurePolicy.allows(FeaturePolicy::Type::Camera, origin))
+ return false;
+
+ if ((types & UserMediaController::CaptureType::Microphone) && !featurePolicy.allows(FeaturePolicy::Type::Microphone, origin))
+ return false;
+
+ if ((types & UserMediaController::CaptureType::Display) && !featurePolicy.allows(FeaturePolicy::Type::DisplayCapture, origin))
+ return false;
+
+ return true;
+}
+
static UserMediaController::GetUserMediaAccess isAllowedToUse(Document& document, Document& topDocument, OptionSet<UserMediaController::CaptureType> types)
{
if (&document == &topDocument)
@@ -80,31 +94,13 @@
if (!parentDocument)
return UserMediaController::GetUserMediaAccess::BlockedByParent;
- if (document.securityOrigin().isSameSchemeHostPort(parentDocument->securityOrigin()))
- return UserMediaController::GetUserMediaAccess::CanCall;
-
auto* element = document.ownerElement();
ASSERT(element);
- if (!element)
+ if (!element || !is<HTMLIFrameElement>(*element))
return UserMediaController::GetUserMediaAccess::BlockedByParent;
- if (!is<HTMLIFrameElement>(*element))
- return UserMediaController::GetUserMediaAccess::BlockedByParent;
- auto& allow = downcast<HTMLIFrameElement>(*element).allow();
-
- bool allowCameraAccess = false;
- bool allowMicrophoneAccess = false;
- bool allowDisplay = false;
- for (auto allowItem : StringView { allow }.split(';')) {
- auto item = allowItem.stripLeadingAndTrailingMatchedCharacters(isHTMLSpace<UChar>);
- if (!allowCameraAccess && item == "camera")
- allowCameraAccess = true;
- else if (!allowMicrophoneAccess && item == "microphone")
- allowMicrophoneAccess = true;
- else if (!allowDisplay && item == "display")
- allowDisplay = true;
- }
- if ((allowCameraAccess || !(types & UserMediaController::CaptureType::Camera)) && (allowMicrophoneAccess || !(types & UserMediaController::CaptureType::Microphone)) && (allowDisplay || !(types & UserMediaController::CaptureType::Display)))
+ auto& featurePolicy = downcast<HTMLIFrameElement>(*element).featurePolicy();
+ if (isAllowedByFeaturePolicy(featurePolicy, document.securityOrigin().data(), types))
return UserMediaController::GetUserMediaAccess::CanCall;
return UserMediaController::GetUserMediaAccess::BlockedByFeaturePolicy;
Modified: trunk/Source/WebCore/Sources.txt (245624 => 245625)
--- trunk/Source/WebCore/Sources.txt 2019-05-22 17:31:06 UTC (rev 245624)
+++ trunk/Source/WebCore/Sources.txt 2019-05-22 17:38:42 UTC (rev 245625)
@@ -1075,6 +1075,7 @@
html/EmailInputType.cpp
html/FTPDirectoryDocument.cpp
html/FileListCreator.cpp
+html/FeaturePolicy.cpp
html/FileInputType.cpp
html/FormAssociatedElement.cpp
html/FormController.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (245624 => 245625)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2019-05-22 17:31:06 UTC (rev 245624)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2019-05-22 17:38:42 UTC (rev 245625)
@@ -1104,6 +1104,7 @@
419ACF921F97E7DA009F1A83 /* ServiceWorkerFetch.h in Headers */ = {isa = PBXBuildFile; fileRef = 419ACF8E1F97E7D5009F1A83 /* ServiceWorkerFetch.h */; settings = {ATTRIBUTES = (Private, ); }; };
419BC2DF1685329900D64D6D /* VisitedLinkState.h in Headers */ = {isa = PBXBuildFile; fileRef = 419BC2DD1685329900D64D6D /* VisitedLinkState.h */; };
419BE7591BC7F42B00E1C85B /* WebCoreBuiltinNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 419BE7521BC7F3DB00E1C85B /* WebCoreBuiltinNames.h */; };
+ 41A0829C22935F3D008426E0 /* FeaturePolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 41A0829922932EF4008426E0 /* FeaturePolicy.h */; settings = {ATTRIBUTES = (Private, ); }; };
41A1B01C1E54239B007F3769 /* JSDOMGuardedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 41A1B01A1E542396007F3769 /* JSDOMGuardedObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
41A3D58F101C152D00316D07 /* DedicatedWorkerThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 41A3D58D101C152D00316D07 /* DedicatedWorkerThread.h */; };
41A7D3531F438D16008988DE /* WorkerCacheStorageConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 41A7D3501F438D10008988DE /* WorkerCacheStorageConnection.h */; };
@@ -7323,6 +7324,8 @@
419FAFAD1ABABCD5005B828B /* ReadableStreamDefaultReader.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadableStreamDefaultReader.idl; sourceTree = "<group>"; };
41A023ED1A39DB7900F722CF /* ReadableStream.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadableStream.idl; sourceTree = "<group>"; };
41A023ED1A39DB7900F722DF /* WritableStream.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WritableStream.idl; sourceTree = "<group>"; };
+ 41A0829922932EF4008426E0 /* FeaturePolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FeaturePolicy.h; sourceTree = "<group>"; };
+ 41A0829B22932EF4008426E0 /* FeaturePolicy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FeaturePolicy.cpp; sourceTree = "<group>"; };
41A1B00D1E52656E007F3769 /* LibWebRTCProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibWebRTCProvider.cpp; path = libwebrtc/LibWebRTCProvider.cpp; sourceTree = "<group>"; };
41A1B01A1E542396007F3769 /* JSDOMGuardedObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMGuardedObject.h; sourceTree = "<group>"; };
41A1B01B1E542396007F3769 /* JSDOMGuardedObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMGuardedObject.cpp; sourceTree = "<group>"; };
@@ -21209,6 +21212,8 @@
2E37DFD912DBAFB800A6B233 /* DOMURL.idl */,
F55B3D871251F12D003EF269 /* EmailInputType.cpp */,
F55B3D881251F12D003EF269 /* EmailInputType.h */,
+ 41A0829B22932EF4008426E0 /* FeaturePolicy.cpp */,
+ 41A0829922932EF4008426E0 /* FeaturePolicy.h */,
F55B3D891251F12D003EF269 /* FileInputType.cpp */,
F55B3D8A1251F12D003EF269 /* FileInputType.h */,
835D54C11F4DE53400E60671 /* FileListCreator.cpp */,
@@ -28958,6 +28963,7 @@
E47E276516036ED200EE2AFB /* ExtensionStyleSheets.h in Headers */,
5C4304B1191AC908000E2BC0 /* EXTShaderTextureLOD.h in Headers */,
7728694F14F8882500F484DC /* EXTTextureFilterAnisotropic.h in Headers */,
+ 41A0829C22935F3D008426E0 /* FeaturePolicy.h in Headers */,
A75E8B890E1DE2D6007F2481 /* FEBlend.h in Headers */,
A75E8B8B0E1DE2D6007F2481 /* FEColorMatrix.h in Headers */,
A75E8B8D0E1DE2D6007F2481 /* FEComponentTransfer.h in Headers */,
Added: trunk/Source/WebCore/html/FeaturePolicy.cpp (0 => 245625)
--- trunk/Source/WebCore/html/FeaturePolicy.cpp (rev 0)
+++ trunk/Source/WebCore/html/FeaturePolicy.cpp 2019-05-22 17:38:42 UTC (rev 245625)
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2019 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 "FeaturePolicy.h"
+
+#include "Document.h"
+#include "SecurityOrigin.h"
+
+namespace WebCore {
+
+static bool isAllowedByFeaturePolicy(const FeaturePolicy::AllowRule& rule, const SecurityOriginData& origin)
+{
+ switch (rule.type) {
+ case FeaturePolicy::AllowRule::Type::None:
+ return false;
+ case FeaturePolicy::AllowRule::Type::All:
+ return true;
+ case FeaturePolicy::AllowRule::Type::List:
+ return rule.allowedList.contains(origin);
+ }
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+static inline void processOriginItem(Document& document, FeaturePolicy::AllowRule& rule, StringView item)
+{
+ if (rule.type == FeaturePolicy::AllowRule::Type::None)
+ return;
+
+ item = item.stripLeadingAndTrailingMatchedCharacters(isHTMLSpace<UChar>);
+ // FIXME: Support 'src'.
+ if (item == "'src'")
+ return;
+
+ if (item == "*") {
+ rule.type = FeaturePolicy::AllowRule::Type::All;
+ return;
+ }
+
+ if (item == "'self'") {
+ rule.allowedList.add(document.securityOrigin().data());
+ return;
+ }
+ if (item == "'none'") {
+ rule.type = FeaturePolicy::AllowRule::Type::None;
+ return;
+ }
+ URL url { { }, item.toString() };
+ if (url.isValid())
+ rule.allowedList.add(SecurityOriginData::fromURL(url));
+}
+
+static inline void updateList(Document& document, FeaturePolicy::AllowRule& rule, StringView value)
+{
+ // We keep the empty string value equivalent to '*' for existing websites.
+ if (value.isEmpty()) {
+ rule.type = FeaturePolicy::AllowRule::Type::All;
+ return;
+ }
+
+ while (!value.isEmpty()) {
+ auto position = value.find(isHTMLSpace<UChar>);
+ if (position == notFound) {
+ processOriginItem(document, rule, value);
+ return;
+ }
+
+ processOriginItem(document, rule, value.substring(0, position));
+ value = value.substring(position + 1).stripLeadingAndTrailingMatchedCharacters(isHTMLSpace<UChar>);
+ }
+}
+
+FeaturePolicy FeaturePolicy::parse(Document& document, StringView allowAttributeValue)
+{
+ FeaturePolicy policy;
+ bool isCameraInitialized = false;
+ bool isMicrophoneInitialized = false;
+ bool isDisplayCaptureInitialized = false;
+ for (auto allowItem : allowAttributeValue.split(';')) {
+ auto item = allowItem.stripLeadingAndTrailingMatchedCharacters(isHTMLSpace<UChar>);
+ if (item.startsWith("camera")) {
+ isCameraInitialized = true;
+ updateList(document, policy.m_cameraRule, item.substring(7));
+ continue;
+ }
+ if (item.startsWith("microphone")) {
+ isMicrophoneInitialized = true;
+ updateList(document, policy.m_microphoneRule, item.substring(11));
+ continue;
+ }
+ if (item.startsWith("display-capture")) {
+ isDisplayCaptureInitialized = true;
+ updateList(document, policy.m_displayCaptureRule, item.substring(16));
+ continue;
+ }
+ }
+
+ // By default, camera, microphone and display-capture policy is 'self'
+ if (!isCameraInitialized)
+ policy.m_cameraRule.allowedList.add(document.securityOrigin().data());
+ if (!isMicrophoneInitialized)
+ policy.m_microphoneRule.allowedList.add(document.securityOrigin().data());
+ if (!isDisplayCaptureInitialized)
+ policy.m_displayCaptureRule.allowedList.add(document.securityOrigin().data());
+
+ return policy;
+}
+
+bool FeaturePolicy::allows(Type type, const SecurityOriginData& origin) const
+{
+ switch (type) {
+ case Type::Camera:
+ return isAllowedByFeaturePolicy(m_cameraRule, origin);
+ case Type::Microphone:
+ return isAllowedByFeaturePolicy(m_microphoneRule, origin);
+ case Type::DisplayCapture:
+ return isAllowedByFeaturePolicy(m_displayCaptureRule, origin);
+ }
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+}
Added: trunk/Source/WebCore/html/FeaturePolicy.h (0 => 245625)
--- trunk/Source/WebCore/html/FeaturePolicy.h (rev 0)
+++ trunk/Source/WebCore/html/FeaturePolicy.h 2019-05-22 17:38:42 UTC (rev 245625)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 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 "SecurityOriginData.h"
+#include <wtf/HashSet.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+class Document;
+
+class FeaturePolicy {
+public:
+ static FeaturePolicy parse(Document&, StringView);
+
+ enum class Type { Camera, Microphone, DisplayCapture };
+ bool allows(Type, const SecurityOriginData&) const;
+
+ struct AllowRule {
+ enum class Type { All, None, List };
+ Type type { Type::List };
+ HashSet<SecurityOriginData> allowedList;
+ };
+
+private:
+ AllowRule m_cameraRule;
+ AllowRule m_microphoneRule;
+ AllowRule m_displayCaptureRule;
+};
+
+} // namespace WebCore
Modified: trunk/Source/WebCore/html/HTMLIFrameElement.cpp (245624 => 245625)
--- trunk/Source/WebCore/html/HTMLIFrameElement.cpp 2019-05-22 17:31:06 UTC (rev 245624)
+++ trunk/Source/WebCore/html/HTMLIFrameElement.cpp 2019-05-22 17:38:42 UTC (rev 245625)
@@ -150,4 +150,11 @@
return ReferrerPolicy::EmptyString;
}
+const FeaturePolicy& HTMLIFrameElement::featurePolicy() const
+{
+ if (!m_featurePolicy)
+ m_featurePolicy = FeaturePolicy::parse(document(), m_allow);
+ return *m_featurePolicy;
}
+
+}
Modified: trunk/Source/WebCore/html/HTMLIFrameElement.h (245624 => 245625)
--- trunk/Source/WebCore/html/HTMLIFrameElement.h 2019-05-22 17:31:06 UTC (rev 245624)
+++ trunk/Source/WebCore/html/HTMLIFrameElement.h 2019-05-22 17:38:42 UTC (rev 245625)
@@ -23,6 +23,7 @@
#pragma once
+#include "FeaturePolicy.h"
#include "HTMLFrameElementBase.h"
namespace WebCore {
@@ -44,6 +45,8 @@
String referrerPolicyForBindings() const;
ReferrerPolicy referrerPolicy() const final;
+ const FeaturePolicy& featurePolicy() const;
+
private:
HTMLIFrameElement(const QualifiedName&, Document&);
@@ -60,6 +63,7 @@
std::unique_ptr<DOMTokenList> m_sandbox;
String m_allow;
+ mutable Optional<FeaturePolicy> m_featurePolicy;
};
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (245624 => 245625)
--- trunk/Source/WebKit/ChangeLog 2019-05-22 17:31:06 UTC (rev 245624)
+++ trunk/Source/WebKit/ChangeLog 2019-05-22 17:38:42 UTC (rev 245625)
@@ -1,3 +1,15 @@
+2019-05-22 Youenn Fablet <[email protected]>
+
+ Implement Feature policy self/none/* parsing
+ https://bugs.webkit.org/show_bug.cgi?id=198078
+
+ Reviewed by Eric Carlson.
+
+ Fix a case where completion handler might not always be called.
+
+ * WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp:
+ (WebKit::UserMediaPermissionRequestManager::userMediaAccessWasGranted):
+
2019-05-22 Ross Kirsling <[email protected]>
Unreviewed fix for non-unified build after r245320.
Modified: trunk/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp (245624 => 245625)
--- trunk/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp 2019-05-22 17:31:06 UTC (rev 245624)
+++ trunk/Source/WebKit/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp 2019-05-22 17:38:42 UTC (rev 245625)
@@ -140,8 +140,10 @@
void UserMediaPermissionRequestManager::userMediaAccessWasGranted(uint64_t requestID, CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, String&& deviceIdentifierHashSalt, CompletionHandler<void()>&& completionHandler)
{
auto request = m_idToUserMediaRequestMap.take(requestID);
- if (!request)
+ if (!request) {
+ completionHandler();
return;
+ }
removeMediaRequestFromMaps(*request);
request->allow(WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(deviceIdentifierHashSalt), WTFMove(completionHandler));