WebKit Bugzilla
Attachment 340729 Details for
Bug 185779
: Handle failure to extend sandbox gracefully
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-185779-20180518122811.patch (text/plain), 26.53 KB, created by
Eric Carlson
on 2018-05-18 12:28:12 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Eric Carlson
Created:
2018-05-18 12:28:12 PDT
Size:
26.53 KB
patch
obsolete
>Subversion Revision: 231918 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 41d9b538d5c4e4984e42b62de76ff99ae8a6ee12..f144b43ce4d47d230f07e4c3766f395aac7476f6 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,17 @@ >+2018-05-18 Eric Carlson <eric.carlson@apple.com> >+ >+ Handle failure to extend sandbox gracefully >+ https://bugs.webkit.org/show_bug.cgi?id=185779 >+ <rdar://problem/40316349> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Test: TestWebKitAPI/Tests/WebKitCocoa/UserMediaSimulateFailedSandbox.mm >+ >+ * Modules/mediastream/UserMediaRequest.cpp: >+ (WebCore::UserMediaRequest::deny): Include the error string in the promise rejection. >+ * Modules/mediastream/UserMediaRequest.h: >+ > 2018-05-17 Wenson Hsieh <wenson_hsieh@apple.com> > > [Extra zoom mode] Disabled adaptations are not reset upon mainframe navigation >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index f996e971c73784d0c99f24262e4e83031a62e6de..34fb5561680e4dbcb0d957de0e0fe1b9515536c2 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,28 @@ >+2018-05-18 Eric Carlson <eric.carlson@apple.com> >+ >+ Handle failure to extend sandbox gracefully >+ https://bugs.webkit.org/show_bug.cgi?id=185779 >+ <rdar://problem/40316349> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * UIProcess/API/Cocoa/WKWebView.mm: >+ (-[WKWebView _denyNextUserMediaRequest]): >+ * UIProcess/API/Cocoa/WKWebViewPrivate.h: >+ >+ * UIProcess/UserMediaPermissionRequestManagerProxy.cpp: >+ (WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted): Don't append >+ the request to m_grantedRequests if it failed. >+ (WebKit::UserMediaPermissionRequestManagerProxy::grantAccess): Deny request if willCreateMediaStream >+ fails. >+ * UIProcess/UserMediaPermissionRequestManagerProxy.h: >+ >+ * UIProcess/UserMediaProcessManager.cpp: >+ (WebKit::UserMediaProcessManager::willCreateMediaStream): Don't try to extend sandbox if >+ we fail to allocate all necessary handles. >+ * UIProcess/UserMediaProcessManager.h: >+ (WebKit::UserMediaProcessManager::denyNextUserMediaRequest): New, for testing. >+ > 2018-05-17 Carlos Alberto Lopez Perez <clopez@igalia.com> > > [WPE] Implement and enable FULLSCREEN_API >diff --git a/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp b/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp >index 6c20be1fe2fa7100a6d8494a7fa5745f5146be7a..00ec3ed6497aede39c123d6e53b1b823f7863857 100644 >--- a/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp >+++ b/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp >@@ -257,45 +257,51 @@ void UserMediaRequest::allow(CaptureDevice&& audioDevice, CaptureDevice&& videoD > #endif > } > >-void UserMediaRequest::deny(MediaAccessDenialReason reason, const String& invalidConstraint) >+void UserMediaRequest::deny(MediaAccessDenialReason reason, const String& message) > { > if (!m_scriptExecutionContext) > return; > >+ ExceptionCode code; > switch (reason) { > case MediaAccessDenialReason::NoConstraints: > RELEASE_LOG(MediaStream, "UserMediaRequest::deny - no constraints"); >- m_promise.reject(TypeError); >+ code = TypeError; > break; > case MediaAccessDenialReason::UserMediaDisabled: > RELEASE_LOG(MediaStream, "UserMediaRequest::deny - user media disabled"); >- m_promise.reject(SecurityError); >+ code = SecurityError; > break; > case MediaAccessDenialReason::NoCaptureDevices: > RELEASE_LOG(MediaStream, "UserMediaRequest::deny - no capture devices"); >- m_promise.reject(NotFoundError); >+ code = NotFoundError; > break; > case MediaAccessDenialReason::InvalidConstraint: >- RELEASE_LOG(MediaStream, "UserMediaRequest::deny - invalid constraint - %s", invalidConstraint.utf8().data()); >- m_promise.rejectType<IDLInterface<OverconstrainedError>>(OverconstrainedError::create(invalidConstraint, ASCIILiteral("Invalid constraint")).get()); >- break; >+ RELEASE_LOG(MediaStream, "UserMediaRequest::deny - invalid constraint - %s", message.utf8().data()); >+ m_promise.rejectType<IDLInterface<OverconstrainedError>>(OverconstrainedError::create(message, ASCIILiteral("Invalid constraint")).get()); >+ return; > case MediaAccessDenialReason::HardwareError: > RELEASE_LOG(MediaStream, "UserMediaRequest::deny - hardware error"); >- m_promise.reject(NotReadableError); >+ code = NotReadableError; > break; > case MediaAccessDenialReason::OtherFailure: > RELEASE_LOG(MediaStream, "UserMediaRequest::deny - other failure"); >- m_promise.reject(AbortError); >+ code = AbortError; > break; > case MediaAccessDenialReason::PermissionDenied: > RELEASE_LOG(MediaStream, "UserMediaRequest::deny - permission denied"); >- m_promise.reject(NotAllowedError); >+ code = NotAllowedError; > break; > case MediaAccessDenialReason::InvalidAccess: > RELEASE_LOG(MediaStream, "UserMediaRequest::deny - invalid access"); >- m_promise.reject(InvalidAccessError); >+ code = InvalidAccessError; > break; > } >+ >+ if (!message.isEmpty()) >+ m_promise.reject(code, message); >+ else >+ m_promise.reject(code); > } > > void UserMediaRequest::stop() >diff --git a/Source/WebCore/Modules/mediastream/UserMediaRequest.h b/Source/WebCore/Modules/mediastream/UserMediaRequest.h >index 6804da28c4793e5da969caa81735f21b58c58b9f..2da682ff53f19ac78ead0006c1c55b0cdc96b4be 100644 >--- a/Source/WebCore/Modules/mediastream/UserMediaRequest.h >+++ b/Source/WebCore/Modules/mediastream/UserMediaRequest.h >@@ -57,7 +57,7 @@ public: > WEBCORE_EXPORT void allow(CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, String&& deviceIdentifierHashSalt); > > enum MediaAccessDenialReason { NoConstraints, UserMediaDisabled, NoCaptureDevices, InvalidConstraint, HardwareError, PermissionDenied, InvalidAccess, OtherFailure }; >- WEBCORE_EXPORT void deny(MediaAccessDenialReason, const String& invalidConstraint = emptyString()); >+ WEBCORE_EXPORT void deny(MediaAccessDenialReason, const String& errorMessage = emptyString()); > > const Vector<String>& audioDeviceUIDs() const { return m_audioDeviceUIDs; } > const Vector<String>& videoDeviceUIDs() const { return m_videoDeviceUIDs; } >diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm b/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm >index 23bcfd72c66d954f386ff8812704aa30002df574..3a4df7d1a45561d7f61a903a1f2383cd71fbec2a 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm >+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm >@@ -47,6 +47,7 @@ > #import "RemoteObjectRegistryMessages.h" > #import "SandboxUtilities.h" > #import "UIDelegate.h" >+#import "UserMediaProcessManager.h" > #import "VersionChecks.h" > #import "ViewGestureController.h" > #import "ViewSnapshotStore.h" >@@ -6385,6 +6386,10 @@ static WebCore::UserInterfaceLayoutDirection toUserInterfaceLayoutDirection(UISe > _page->setDefersLoadingForTesting(defersLoading); > } > >+- (void)_denyNextUserMediaRequest >+{ >+ WebKit::UserMediaProcessManager::singleton().denyNextUserMediaRequest(); >+} > @end > > >diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h b/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h >index 049d90ad874aa7941ac658e498cc1532a6c5f9aa..a5721dbd373b6861f954cb17c77efacfec887cc0 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h >+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h >@@ -459,6 +459,8 @@ typedef NS_OPTIONS(NSUInteger, _WKRectEdge) { > - (void)_disableBackForwardSnapshotVolatilityForTesting WK_API_AVAILABLE(macosx(10.12.3), ios(10.3)); > - (void)_executeEditCommand:(NSString *)command argument:(NSString *)argument completion:(void (^)(BOOL))completion WK_API_AVAILABLE(macosx(10.13.4), ios(11.3)); > >+- (void)_denyNextUserMediaRequest WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA)); >+ > - (BOOL)_beginBackSwipeForTesting; > - (BOOL)_completeBackSwipeForTesting; > - (void)_setDefersLoadingForTesting:(BOOL)defersLoading; >diff --git a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp >index 26b8661bd61fd3cb177d3134bcc19a5438642b7b..3c07295f1053fc15dcc88445632905b8c3fcb96b 100644 >--- a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp >+++ b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp >@@ -153,8 +153,9 @@ void UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted(uint64_t > if (!request) > return; > >- grantAccess(userMediaID, WTFMove(audioDevice), WTFMove(videoDevice), request->deviceIdentifierHashSalt()); >- m_grantedRequests.append(request.releaseNonNull()); >+ if (grantAccess(userMediaID, WTFMove(audioDevice), WTFMove(videoDevice), request->deviceIdentifierHashSalt())) >+ m_grantedRequests.append(request.releaseNonNull()); >+ > #else > UNUSED_PARAM(userMediaID); > UNUSED_PARAM(audioDevice); >@@ -220,10 +221,15 @@ bool UserMediaPermissionRequestManagerProxy::wasRequestDenied(uint64_t mainFrame > return false; > } > >-void UserMediaPermissionRequestManagerProxy::grantAccess(uint64_t userMediaID, const CaptureDevice audioDevice, const CaptureDevice videoDevice, const String& deviceIdentifierHashSalt) >+bool UserMediaPermissionRequestManagerProxy::grantAccess(uint64_t userMediaID, const CaptureDevice audioDevice, const CaptureDevice videoDevice, const String& deviceIdentifierHashSalt) > { >- UserMediaProcessManager::singleton().willCreateMediaStream(*this, !!audioDevice, !!videoDevice); >+ if (!UserMediaProcessManager::singleton().willCreateMediaStream(*this, !!audioDevice, !!videoDevice)) { >+ denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::OtherFailure, "Unable to extend sandbox."); >+ return false; >+ } >+ > m_page.process().send(Messages::WebPage::UserMediaAccessWasGranted(userMediaID, audioDevice, videoDevice, deviceIdentifierHashSalt), m_page.pageID()); >+ return true; > } > #endif > >diff --git a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h >index ab15b49c28a2491374210e30ab43e5e6787301b0..573af04d71b853957512499d92c430648bbd179f 100644 >--- a/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h >+++ b/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h >@@ -68,7 +68,7 @@ private: > Ref<UserMediaPermissionRequestProxy> createPermissionRequest(uint64_t userMediaID, uint64_t mainFrameID, uint64_t frameID, Ref<WebCore::SecurityOrigin>&& userMediaDocumentOrigin, Ref<WebCore::SecurityOrigin>&& topLevelDocumentOrigin, Vector<WebCore::CaptureDevice>&& audioDevices, Vector<WebCore::CaptureDevice>&& videoDevices, String&&, WebCore::MediaStreamRequest&&); > void denyRequest(uint64_t userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason, const String& invalidConstraint); > #if ENABLE(MEDIA_STREAM) >- void grantAccess(uint64_t userMediaID, const WebCore::CaptureDevice audioDevice, const WebCore::CaptureDevice videoDevice, const String& deviceIdentifierHashSalt); >+ bool grantAccess(uint64_t userMediaID, const WebCore::CaptureDevice audioDevice, const WebCore::CaptureDevice videoDevice, const String& deviceIdentifierHashSalt); > > const UserMediaPermissionRequestProxy* searchForGrantedRequest(uint64_t frameID, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin, bool needsAudio, bool needsVideo) const; > bool wasRequestDenied(uint64_t mainFrameID, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin, bool needsAudio, bool needsVideo); >diff --git a/Source/WebKit/UIProcess/UserMediaProcessManager.cpp b/Source/WebKit/UIProcess/UserMediaProcessManager.cpp >index 89224c42df0f0f0a453ed9ed106689cb61fce9de..94a0b4619fd503e83ad1519cec719c3d05499628 100644 >--- a/Source/WebKit/UIProcess/UserMediaProcessManager.cpp >+++ b/Source/WebKit/UIProcess/UserMediaProcessManager.cpp >@@ -126,14 +126,17 @@ void UserMediaProcessManager::muteCaptureMediaStreamsExceptIn(WebPageProxy& page > #endif > } > >-void UserMediaProcessManager::willCreateMediaStream(UserMediaPermissionRequestManagerProxy& proxy, bool withAudio, bool withVideo) >+bool UserMediaProcessManager::willCreateMediaStream(UserMediaPermissionRequestManagerProxy& proxy, bool withAudio, bool withVideo) > { > #if ENABLE(SANDBOX_EXTENSIONS) > auto& processStartingCapture = proxy.page().process(); > > ASSERT(stateMap().contains(&processStartingCapture)); > >- proxy.page().activateMediaStreamCaptureInPage(); >+ if (m_denyNextRequest) { >+ m_denyNextRequest = false; >+ return false; >+ } > > auto& state = processState(processStartingCapture); > size_t extensionCount = 0; >@@ -171,10 +174,23 @@ void UserMediaProcessManager::willCreateMediaStream(UserMediaPermissionRequestMa > } > } > >+ if (ids.size() != handles.size()) { >+ WTFLogAlways("Could not create a required sandbox extension, capture will fail!"); >+ return false; >+ } >+ > state.setSandboxExtensionsGranted(currentExtensions); > processStartingCapture.send(Messages::WebPage::GrantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions(ids, WTFMove(handles))), proxy.page().pageID()); > } >+#else >+ UNUSED_PARAM(proxy); >+ UNUSED_PARAM(withAudio); >+ UNUSED_PARAM(withVideo); > #endif >+ >+ proxy.page().activateMediaStreamCaptureInPage(); >+ >+ return true; > } > > void UserMediaProcessManager::startedCaptureSession(UserMediaPermissionRequestManagerProxy& proxy) >diff --git a/Source/WebKit/UIProcess/UserMediaProcessManager.h b/Source/WebKit/UIProcess/UserMediaProcessManager.h >index e14252fb17318f7b151a0db224607b6c54a32095..81998b4acb7ddf91d50a83c79d2e5cac3d187473 100644 >--- a/Source/WebKit/UIProcess/UserMediaProcessManager.h >+++ b/Source/WebKit/UIProcess/UserMediaProcessManager.h >@@ -34,7 +34,7 @@ public: > void addUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy&); > void removeUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy&); > >- void willCreateMediaStream(UserMediaPermissionRequestManagerProxy&, bool withAudio, bool withVideo); >+ bool willCreateMediaStream(UserMediaPermissionRequestManagerProxy&, bool withAudio, bool withVideo); > void muteCaptureMediaStreamsExceptIn(WebPageProxy&); > > void startedCaptureSession(UserMediaPermissionRequestManagerProxy&); >@@ -43,8 +43,11 @@ public: > void setCaptureEnabled(bool); > bool captureEnabled() const { return m_captureEnabled; } > >+ void denyNextUserMediaRequest() { m_denyNextRequest = true; } >+ > private: > bool m_captureEnabled { true }; >+ bool m_denyNextRequest { false }; > }; > > } // namespace WebKit >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 4b8b0fbcd1d480db92991ba32b6ad61515ab0120..190ea4f873745ae3839214060c8473c8418ac68c 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,21 @@ >+2018-05-18 Eric Carlson <eric.carlson@apple.com> >+ >+ Handle failure to extend sandbox gracefully >+ https://bugs.webkit.org/show_bug.cgi?id=185779 >+ <rdar://problem/40316349> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: >+ * TestWebKitAPI/Tests/WebKitCocoa/UserMediaSimulateFailedSandbox.mm: Added. >+ (-[SimulateFailedSandboxMessageHandler userContentController:didReceiveScriptMessage:]): >+ (-[SimulateFailedSandboxUIDelegate _webView:requestUserMediaAuthorizationForDevices:url:mainFrameURL:decisionHandler:]): >+ (-[SimulateFailedSandboxUIDelegate _webView:checkUserMediaPermissionForURL:mainFrameURL:frameIdentifier:decisionHandler:]): >+ (MediaCaptureSimulateFailedSandbox::SetUp): >+ (MediaCaptureSimulateFailedSandbox::loadTestAndWaitForMessage): >+ (TEST_F): >+ * TestWebKitAPI/Tests/WebKitCocoa/disableGetUserMedia.html: >+ > 2018-05-17 Carlos Alberto Lopez Perez <clopez@igalia.com> > > [WPE] Implement and enable FULLSCREEN_API >diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >index b20baacb181d0e71876c13e0e86d34cb76ed920b..0372673c68009200fbb179812d8dcc90a870df38 100644 >--- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >+++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >@@ -35,6 +35,7 @@ > 07E1F6A21FFC44FA0096C7EC /* getDisplayMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 07E1F6A11FFC44F90096C7EC /* getDisplayMedia.html */; }; > 07E1F6A31FFC4B760096C7EC /* GetDisplayMedia.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07E1F6A01FFC3A080096C7EC /* GetDisplayMedia.mm */; }; > 07E499911F9E56DF002F1EF3 /* GetUserMediaReprompt.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07E499901F9E56A1002F1EF3 /* GetUserMediaReprompt.mm */; }; >+ 07F4E92E20AF59E2002E3803 /* UserMediaSimulateFailedSandbox.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07F4E92D20AF58D3002E3803 /* UserMediaSimulateFailedSandbox.mm */; }; > 0EBBCC661FFF9E0C00FA42AB /* pop-up-check.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 0EBBCC651FFF9DCE00FA42AB /* pop-up-check.html */; }; > 0F139E771A423A5B00F590F5 /* WeakObjCPtr.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F139E751A423A5300F590F5 /* WeakObjCPtr.mm */; }; > 0F139E781A423A6B00F590F5 /* PlatformUtilitiesCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F139E721A423A2B00F590F5 /* PlatformUtilitiesCocoa.mm */; }; >@@ -1151,6 +1152,7 @@ > 07E1F6A11FFC44F90096C7EC /* getDisplayMedia.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = getDisplayMedia.html; path = ../WebKit/getDisplayMedia.html; sourceTree = "<group>"; }; > 07E499901F9E56A1002F1EF3 /* GetUserMediaReprompt.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GetUserMediaReprompt.mm; sourceTree = "<group>"; }; > 07EDEFAC1EB9400C00D43292 /* UserMediaDisabled.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UserMediaDisabled.mm; sourceTree = "<group>"; }; >+ 07F4E92D20AF58D3002E3803 /* UserMediaSimulateFailedSandbox.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UserMediaSimulateFailedSandbox.mm; sourceTree = "<group>"; }; > 0BCD833414857CE400EA2003 /* HashMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HashMap.cpp; sourceTree = "<group>"; }; > 0BCD85691485C98B00EA2003 /* SetForScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SetForScope.cpp; sourceTree = "<group>"; }; > 0EBBCC651FFF9DCE00FA42AB /* pop-up-check.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "pop-up-check.html"; sourceTree = "<group>"; }; >@@ -2258,6 +2260,7 @@ > 7C882E051C80C624006BF731 /* UserContentWorldProtocol.h */, > 7CCB99201D3B41F6003922F6 /* UserInitiatedActionInNavigationAction.mm */, > 07EDEFAC1EB9400C00D43292 /* UserMediaDisabled.mm */, >+ 07F4E92D20AF58D3002E3803 /* UserMediaSimulateFailedSandbox.mm */, > 93E943F11CD3E87E00AC08C2 /* VideoControlsManager.mm */, > 6356FB211EC4E0BA0044BF18 /* VisibleContentRect.mm */, > 83779C371F82FEB0007CDA8A /* VisitedLinkStore.mm */, >@@ -3782,6 +3785,7 @@ > 7CCB99211D3B41F6003922F6 /* UserInitiatedActionInNavigationAction.mm in Sources */, > 7CCE7F171A411AE600447C4C /* UserMedia.cpp in Sources */, > 0799C3491EBA2D7B003B7532 /* UserMediaDisabled.mm in Sources */, >+ 07F4E92E20AF59E2002E3803 /* UserMediaSimulateFailedSandbox.mm in Sources */, > 7CCE7F181A411AE600447C4C /* UserMessage.cpp in Sources */, > 7C83E03A1D0A602700FEBCF3 /* UtilitiesCocoa.mm in Sources */, > 7C83E0C61D0A654E00FEBCF3 /* VideoControlsManager.mm in Sources */, >diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/UserMediaSimulateFailedSandbox.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/UserMediaSimulateFailedSandbox.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..07d5779c7dcca29f5f5784a62da6d2a857d69e7b >--- /dev/null >+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/UserMediaSimulateFailedSandbox.mm >@@ -0,0 +1,144 @@ >+/* >+ * Copyright (C) 2018 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. AND ITS CONTRIBUTORS ``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 ITS 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. >+ */ >+ >+#import "config.h" >+ >+#import "PlatformUtilities.h" >+#import "Test.h" >+#import "TestWKWebView.h" >+ >+#import <WebKit/WKPreferencesPrivate.h> >+#import <WebKit/WKUserContentControllerPrivate.h> >+#import <WebKit/WKWebViewConfigurationPrivate.h> >+#import <WebKit/WKWebViewPrivate.h> >+#import <WebKit/WebKit.h> >+#import <WebKit/_WKProcessPoolConfiguration.h> >+#import <wtf/RetainPtr.h> >+ >+#if WK_API_ENABLED >+ >+static bool refuseRequest = false; >+static bool wasPrompted = false; >+ >+static bool receivedScriptMessage = false; >+static RetainPtr<WKScriptMessage> lastScriptMessage; >+ >+@interface SimulateFailedSandboxMessageHandler : NSObject <WKScriptMessageHandler> >+@end >+ >+@implementation SimulateFailedSandboxMessageHandler >+ >+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message >+{ >+ lastScriptMessage = message; >+ receivedScriptMessage = true; >+} >+@end >+ >+@interface SimulateFailedSandboxUIDelegate : NSObject <WKUIDelegate> >+@end >+ >+@implementation SimulateFailedSandboxUIDelegate >+ >+- (void)_webView:(WKWebView *)webView requestUserMediaAuthorizationForDevices:(NSUInteger)devices url:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL decisionHandler:(void (^)(BOOL))decisionHandler >+{ >+ wasPrompted = true; >+ >+ if (refuseRequest) { >+ decisionHandler(NO); >+ return; >+ } >+ >+ BOOL needsMicrophoneAuthorized = devices & _WKCaptureDeviceMicrophone; >+ BOOL needsCameraAuthorized = devices & _WKCaptureDeviceCamera; >+ if (!needsMicrophoneAuthorized && !needsCameraAuthorized) { >+ decisionHandler(NO); >+ return; >+ } >+ >+ decisionHandler(YES); >+} >+ >+- (void)_webView:(WKWebView *)webView checkUserMediaPermissionForURL:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL frameIdentifier:(NSUInteger)frameIdentifier decisionHandler:(void (^)(NSString *, BOOL))decisionHandler >+{ >+ if (refuseRequest) { >+ decisionHandler(nil, NO); >+ return; >+ } >+ >+ decisionHandler(@"0x987654321", NO); >+} >+@end >+ >+class MediaCaptureSimulateFailedSandbox : public testing::Test { >+public: >+ virtual void SetUp() >+ { >+ m_configuration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ >+ RetainPtr<SimulateFailedSandboxMessageHandler> handler = adoptNS([[SimulateFailedSandboxMessageHandler alloc] init]); >+ [[m_configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"]; >+ >+ m_webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:m_configuration.get()]); >+ >+ auto preferences = [m_webView configuration].preferences; >+ preferences._mediaDevicesEnabled = YES; >+ preferences._mockCaptureDevicesEnabled = YES; >+ preferences._mediaCaptureRequiresSecureConnection = NO; >+ >+ m_uiDelegate = adoptNS([[SimulateFailedSandboxUIDelegate alloc] init]); >+ [m_webView setUIDelegate:m_uiDelegate.get()]; >+ } >+ >+ void loadTestAndWaitForMessage(const char* message) >+ { >+ wasPrompted = false; >+ receivedScriptMessage = false; >+ [m_webView loadTestPageNamed:@"disableGetUserMedia"]; >+ TestWebKitAPI::Util::run(&receivedScriptMessage); >+ EXPECT_STREQ([(NSString *)[lastScriptMessage body] UTF8String], message); >+ } >+ >+ RetainPtr<WKWebViewConfiguration> m_configuration; >+ RetainPtr<SimulateFailedSandboxUIDelegate> m_uiDelegate; >+ RetainPtr<TestWKWebView> m_webView; >+}; >+ >+TEST_F(MediaCaptureSimulateFailedSandbox, Test) >+{ >+ EXPECT_TRUE(m_webView.get()._mediaCaptureEnabled); >+ loadTestAndWaitForMessage("allowed"); >+ EXPECT_TRUE(wasPrompted); >+ >+ [m_webView _denyNextUserMediaRequest]; >+ loadTestAndWaitForMessage("denied"); >+ EXPECT_TRUE(wasPrompted); >+ auto* error = [m_webView stringByEvaluatingJavaScript:@"lastError()"]; >+ EXPECT_STREQ([error UTF8String], "AbortError,Unable to extend sandbox"); >+ >+ loadTestAndWaitForMessage("allowed"); >+ EXPECT_TRUE(wasPrompted); >+} >+#endif >diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/disableGetUserMedia.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/disableGetUserMedia.html >index bb61d9b13ac49b27bf0b4eededefd8172d52bc04..3953cd12fce7f2ba6187635939eeed9bc9220ba1 100644 >--- a/Tools/TestWebKitAPI/Tests/WebKitCocoa/disableGetUserMedia.html >+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/disableGetUserMedia.html >@@ -1,4 +1,5 @@ > <script> >+ let err = ''; > function gotUserMedia(mediaStream) > { > window.webkit.messageHandlers.testHandler.postMessage('allowed'); >@@ -6,10 +7,16 @@ > > function userMediaError(error) > { >+ err = `${error.name},${error.message}`; > window.webkit.messageHandlers.testHandler.postMessage('denied'); > } > >- var constraints = { audio: false, video: true}; >+ function lastError() >+ { >+ return err; >+ } >+ >+ let constraints = { audio: false, video: true}; > navigator.mediaDevices.getUserMedia(constraints) > .then(gotUserMedia). > catch(userMediaError);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185779
: 340729 |
340743