[iOS] Apple Pay should be available in documents with no user agent scripts
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Mar 2019 20:51:56 +0000 (20:51 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Mar 2019 20:51:56 +0000 (20:51 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196061
<rdar://problem/48649391>

Reviewed by Brady Eidson.

Source/WebCore:

On platforms that support APPLE_PAY_REMOTE_UI, we can enable Apple Pay JS and Payment Request
by default in all WebKit clients.

In order to protect the privacy of Apple Pay transactions, this patch implements the
following restrictions on API usage:

1. If user agent scripts have been evaluated in a document, Apple Pay APIs will no longer be
available for the duration of the document's lifetime.
2. If an Apple Pay transaction has started in a document, user agent scripts will no longer
be evaluated for the duration of the document's lifetime.

These restrictions are disabled for clients with the
com.apple.private.WebKit.UnrestrictedApplePay entitlement and platforms that do support
Apple Pay but don't support APPLE_PAY_REMOTE_UI.

Added new API tests.

* Modules/applepay/ApplePayRequestBase.cpp:
(WebCore::convertAndValidate):
* Modules/applepay/ApplePayRequestBase.h:
* Modules/applepay/ApplePaySession.cpp:
(WebCore::convertAndValidate):
(WebCore::ApplePaySession::create):
(WebCore::ApplePaySession::supportsVersion):
(WebCore::ApplePaySession::canMakePayments):
(WebCore::ApplePaySession::canMakePaymentsWithActiveCard):
(WebCore::ApplePaySession::openPaymentSetup):
(WebCore::ApplePaySession::begin):
* Modules/applepay/ApplePaySession.h:
* Modules/applepay/ApplePaySession.idl:
* Modules/applepay/PaymentCoordinator.cpp:
(WebCore::PaymentCoordinator::supportsVersion const):
(WebCore::PaymentCoordinator::canMakePayments):
(WebCore::PaymentCoordinator::canMakePaymentsWithActiveCard):
(WebCore::PaymentCoordinator::openPaymentSetup):
(WebCore::PaymentCoordinator::beginPaymentSession):
(WebCore::PaymentCoordinator::validatedPaymentNetwork const):
(WebCore::PaymentCoordinator::shouldAllowApplePay const):
(WebCore::PaymentCoordinator::shouldAllowUserAgentScripts const):
* Modules/applepay/PaymentCoordinator.h:
* Modules/applepay/PaymentCoordinatorClient.h:
(WebCore::PaymentCoordinatorClient::supportsUnrestrictedApplePay const):
* Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp:
(WebCore::ApplePayPaymentHandler::show):
(WebCore::ApplePayPaymentHandler::canMakePayment):
(WebCore::ApplePayPaymentHandler::version const):
* Modules/applepay/paymentrequest/ApplePayPaymentHandler.h:
* Modules/paymentrequest/PaymentHandler.h:
* Modules/paymentrequest/PaymentRequest.cpp:
(WebCore::PaymentRequest::show):
(WebCore::PaymentRequest::canMakePayment):

Plumbed a Document& through to the various places that call into PaymentCoordinator for use
by shouldAllowApplePay and shouldAllowUserAgentScripts.

* bindings/js/ScriptController.cpp:
(WebCore::ScriptController::executeUserAgentScriptInWorld):
(WebCore::ScriptController::shouldAllowUserAgentScripts const):
* bindings/js/ScriptController.h:

Added executeUserAgentScriptInWorld, which calls executeScriptInWorld if allowed.

* dom/Document.cpp:
(WebCore::Document::ensurePlugInsInjectedScript):

Changed to only evaluate the chrome client's plug-in extra script if allowed, and to mark
the document as having evaluated user agent scripts.

(WebCore::Document::hasEvaluatedUserAgentScripts const):
(WebCore::Document::isRunningUserScripts const):
(WebCore::Document::setAsRunningUserScripts):
(WebCore::Document::setHasEvaluatedUserAgentScripts):
(WebCore::Document::hasStartedApplePaySession const):
(WebCore::Document::setHasStartedApplePaySession):
* dom/Document.h:

Added helper functions to set state on the top document.

* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::DocumentThreadableLoader):

Removed call to topDocument() now that isRunningUserScripts() always checks the top document.

* page/Frame.cpp:
(WebCore::Frame::injectUserScriptImmediately):

Changed to only inject the user script if allowed.

* page/Settings.yaml:
* page/SettingsDefaultValues.h:

Enabled Apple Pay by default on platforms that enable APPLE_PAY_REMOTE_UI.

* testing/Internals.cpp:
(WebCore::Internals::setAsRunningUserScripts):
(WebCore::Internals::setHasStartedApplePaySession):
* testing/Internals.h:
* testing/Internals.idl:
* testing/MockPaymentCoordinator.h:
* testing/MockPaymentCoordinator.idl:

Added some internal interfaces for use by TestWebKitAPI.

Source/WebKit:

* Shared/AuxiliaryProcess.h:
* Shared/Cocoa/AuxiliaryProcessCocoa.mm:
(WebKit::AuxiliaryProcess::parentProcessHasEntitlement):

Added a convenience function for checking parent process entitlements.

* Shared/WebPreferences.yaml:
* Shared/WebPreferencesDefaultValues.h:
* UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
(-[WKWebViewConfiguration init]):

Enabled Apple Pay by default on platforms that enable APPLE_PAY_REMOTE_UI.

* WebProcess/ApplePay/WebPaymentCoordinator.cpp:
(WebKit::WebPaymentCoordinator::supportsUnrestrictedApplePay const):
* WebProcess/ApplePay/WebPaymentCoordinator.h:

Implemented supportsUnrestrictedApplePay by checking for the
com.apple.private.WebKit.UnrestrictedApplePay entitlement on platforms that enable
APPLE_PAY_REMOTE_UI.

* WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInLoadDelegate.h:
* WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm:
(didClearWindowObjectForFrame):
(setUpPageLoaderClient):

Added injected bundle SPI that TestWebKitAPI uses to inject the WebCore Internals interface.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::runJavaScript):

Changed to call ScriptController::executeUserAgentScriptInWorld.

Source/WebKitLegacy/mac:

* WebView/WebFrame.mm:
(-[WebFrame _stringByEvaluatingJavaScriptFromString:withGlobalObject:inScriptWorld:]):

Tools:

Added API tests and related infrastructure.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/ApplePay.mm: Added.
(-[TestApplePayScriptMessageHandler initWithExpectation:]):
(-[TestApplePayScriptMessageHandler userContentController:didReceiveScriptMessage:]):
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebKitCocoa/apple-pay-active-session.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability-in-iframe.html: Added.
* TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability.html: Added.
* TestWebKitAPI/cocoa/TestProtocol.mm:
(-[TestProtocol startLoading]):
* TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.h: Added.
* TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.mm: Added.
(-[WebProcessPlugInWithInternals webProcessPlugIn:didCreateBrowserContextController:]):
(-[WebProcessPlugInWithInternals webProcessPlugInBrowserContextController:didClearWindowObjectForFrame:inScriptWorld:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243324 268f45cc-cd09-0410-ab3c-d52691b4dbfc

48 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/applepay/ApplePayRequestBase.cpp
Source/WebCore/Modules/applepay/ApplePayRequestBase.h
Source/WebCore/Modules/applepay/ApplePaySession.cpp
Source/WebCore/Modules/applepay/ApplePaySession.h
Source/WebCore/Modules/applepay/ApplePaySession.idl
Source/WebCore/Modules/applepay/PaymentCoordinator.cpp
Source/WebCore/Modules/applepay/PaymentCoordinator.h
Source/WebCore/Modules/applepay/PaymentCoordinatorClient.h
Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp
Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.h
Source/WebCore/Modules/paymentrequest/PaymentHandler.h
Source/WebCore/Modules/paymentrequest/PaymentRequest.cpp
Source/WebCore/bindings/js/ScriptController.cpp
Source/WebCore/bindings/js/ScriptController.h
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/loader/DocumentThreadableLoader.cpp
Source/WebCore/page/Frame.cpp
Source/WebCore/page/Settings.yaml
Source/WebCore/page/SettingsDefaultValues.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebCore/testing/MockPaymentCoordinator.h
Source/WebCore/testing/MockPaymentCoordinator.idl
Source/WebKit/ChangeLog
Source/WebKit/Shared/AuxiliaryProcess.h
Source/WebKit/Shared/Cocoa/AuxiliaryProcessCocoa.mm
Source/WebKit/Shared/WebPreferences.yaml
Source/WebKit/Shared/WebPreferencesDefaultValues.h
Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm
Source/WebKit/WebProcess/ApplePay/WebPaymentCoordinator.cpp
Source/WebKit/WebProcess/ApplePay/WebPaymentCoordinator.h
Source/WebKit/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInLoadDelegate.h
Source/WebKit/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebView/WebFrame.mm
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplePay.mm [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-pay-active-session.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability-in-iframe.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability.html [new file with mode: 0644]
Tools/TestWebKitAPI/cocoa/TestProtocol.mm
Tools/TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.h [new file with mode: 0644]
Tools/TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.mm [new file with mode: 0644]

index 11ea389..5b69ad4 100644 (file)
@@ -1,3 +1,114 @@
+2019-03-21  Andy Estes  <aestes@apple.com>
+
+        [iOS] Apple Pay should be available in documents with no user agent scripts
+        https://bugs.webkit.org/show_bug.cgi?id=196061
+        <rdar://problem/48649391>
+
+        Reviewed by Brady Eidson.
+
+        On platforms that support APPLE_PAY_REMOTE_UI, we can enable Apple Pay JS and Payment Request
+        by default in all WebKit clients.
+
+        In order to protect the privacy of Apple Pay transactions, this patch implements the
+        following restrictions on API usage:
+
+        1. If user agent scripts have been evaluated in a document, Apple Pay APIs will no longer be
+        available for the duration of the document's lifetime.
+        2. If an Apple Pay transaction has started in a document, user agent scripts will no longer
+        be evaluated for the duration of the document's lifetime.
+
+        These restrictions are disabled for clients with the
+        com.apple.private.WebKit.UnrestrictedApplePay entitlement and platforms that do support
+        Apple Pay but don't support APPLE_PAY_REMOTE_UI.
+
+        Added new API tests.
+
+        * Modules/applepay/ApplePayRequestBase.cpp:
+        (WebCore::convertAndValidate):
+        * Modules/applepay/ApplePayRequestBase.h:
+        * Modules/applepay/ApplePaySession.cpp:
+        (WebCore::convertAndValidate):
+        (WebCore::ApplePaySession::create):
+        (WebCore::ApplePaySession::supportsVersion):
+        (WebCore::ApplePaySession::canMakePayments):
+        (WebCore::ApplePaySession::canMakePaymentsWithActiveCard):
+        (WebCore::ApplePaySession::openPaymentSetup):
+        (WebCore::ApplePaySession::begin):
+        * Modules/applepay/ApplePaySession.h:
+        * Modules/applepay/ApplePaySession.idl:
+        * Modules/applepay/PaymentCoordinator.cpp:
+        (WebCore::PaymentCoordinator::supportsVersion const):
+        (WebCore::PaymentCoordinator::canMakePayments):
+        (WebCore::PaymentCoordinator::canMakePaymentsWithActiveCard):
+        (WebCore::PaymentCoordinator::openPaymentSetup):
+        (WebCore::PaymentCoordinator::beginPaymentSession):
+        (WebCore::PaymentCoordinator::validatedPaymentNetwork const):
+        (WebCore::PaymentCoordinator::shouldAllowApplePay const):
+        (WebCore::PaymentCoordinator::shouldAllowUserAgentScripts const):
+        * Modules/applepay/PaymentCoordinator.h:
+        * Modules/applepay/PaymentCoordinatorClient.h:
+        (WebCore::PaymentCoordinatorClient::supportsUnrestrictedApplePay const):
+        * Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp:
+        (WebCore::ApplePayPaymentHandler::show):
+        (WebCore::ApplePayPaymentHandler::canMakePayment):
+        (WebCore::ApplePayPaymentHandler::version const):
+        * Modules/applepay/paymentrequest/ApplePayPaymentHandler.h:
+        * Modules/paymentrequest/PaymentHandler.h:
+        * Modules/paymentrequest/PaymentRequest.cpp:
+        (WebCore::PaymentRequest::show):
+        (WebCore::PaymentRequest::canMakePayment):
+
+        Plumbed a Document& through to the various places that call into PaymentCoordinator for use
+        by shouldAllowApplePay and shouldAllowUserAgentScripts.
+
+        * bindings/js/ScriptController.cpp:
+        (WebCore::ScriptController::executeUserAgentScriptInWorld):
+        (WebCore::ScriptController::shouldAllowUserAgentScripts const):
+        * bindings/js/ScriptController.h:
+
+        Added executeUserAgentScriptInWorld, which calls executeScriptInWorld if allowed.
+
+        * dom/Document.cpp:
+        (WebCore::Document::ensurePlugInsInjectedScript):
+
+        Changed to only evaluate the chrome client's plug-in extra script if allowed, and to mark
+        the document as having evaluated user agent scripts.
+
+        (WebCore::Document::hasEvaluatedUserAgentScripts const):
+        (WebCore::Document::isRunningUserScripts const):
+        (WebCore::Document::setAsRunningUserScripts):
+        (WebCore::Document::setHasEvaluatedUserAgentScripts):
+        (WebCore::Document::hasStartedApplePaySession const):
+        (WebCore::Document::setHasStartedApplePaySession):
+        * dom/Document.h:
+
+        Added helper functions to set state on the top document.
+
+        * loader/DocumentThreadableLoader.cpp:
+        (WebCore::DocumentThreadableLoader::DocumentThreadableLoader):
+
+        Removed call to topDocument() now that isRunningUserScripts() always checks the top document.
+
+        * page/Frame.cpp:
+        (WebCore::Frame::injectUserScriptImmediately):
+
+        Changed to only inject the user script if allowed.
+
+        * page/Settings.yaml:
+        * page/SettingsDefaultValues.h:
+
+        Enabled Apple Pay by default on platforms that enable APPLE_PAY_REMOTE_UI.
+
+        * testing/Internals.cpp:
+        (WebCore::Internals::setAsRunningUserScripts):
+        (WebCore::Internals::setHasStartedApplePaySession):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+        * testing/MockPaymentCoordinator.h:
+        * testing/MockPaymentCoordinator.idl:
+
+        Added some internal interfaces for use by TestWebKitAPI.
+
 2019-03-21  Alex Christensen  <achristensen@webkit.org>
 
         Add SPI to inform applications of WKContentRuleList actions
index d626c04..0ce91f9 100644 (file)
@@ -33,7 +33,7 @@
 
 namespace WebCore {
 
-static ExceptionOr<Vector<String>> convertAndValidate(unsigned version, const Vector<String>& supportedNetworks, const PaymentCoordinator& paymentCoordinator)
+static ExceptionOr<Vector<String>> convertAndValidate(Document& document, unsigned version, const Vector<String>& supportedNetworks, const PaymentCoordinator& paymentCoordinator)
 {
     if (supportedNetworks.isEmpty())
         return Exception { TypeError, "At least one supported network must be provided." };
@@ -41,7 +41,7 @@ static ExceptionOr<Vector<String>> convertAndValidate(unsigned version, const Ve
     Vector<String> result;
     result.reserveInitialCapacity(supportedNetworks.size());
     for (auto& supportedNetwork : supportedNetworks) {
-        auto validatedNetwork = paymentCoordinator.validatedPaymentNetwork(version, supportedNetwork);
+        auto validatedNetwork = paymentCoordinator.validatedPaymentNetwork(document, version, supportedNetwork);
         if (!validatedNetwork)
             return Exception { TypeError, makeString("\"", supportedNetwork, "\" is not a valid payment network.") };
         result.uncheckedAppend(*validatedNetwork);
@@ -50,9 +50,9 @@ static ExceptionOr<Vector<String>> convertAndValidate(unsigned version, const Ve
     return WTFMove(result);
 }
 
-ExceptionOr<ApplePaySessionPaymentRequest> convertAndValidate(unsigned version, ApplePayRequestBase& request, const PaymentCoordinator& paymentCoordinator)
+ExceptionOr<ApplePaySessionPaymentRequest> convertAndValidate(Document& document, unsigned version, ApplePayRequestBase& request, const PaymentCoordinator& paymentCoordinator)
 {
-    if (!version || !paymentCoordinator.supportsVersion(version))
+    if (!version || !paymentCoordinator.supportsVersion(document, version))
         return Exception { InvalidAccessError, makeString('"', version, "\" is not a supported version.") };
 
     ApplePaySessionPaymentRequest result;
@@ -64,7 +64,7 @@ ExceptionOr<ApplePaySessionPaymentRequest> convertAndValidate(unsigned version,
         return merchantCapabilities.releaseException();
     result.setMerchantCapabilities(merchantCapabilities.releaseReturnValue());
 
-    auto supportedNetworks = convertAndValidate(version, request.supportedNetworks, paymentCoordinator);
+    auto supportedNetworks = convertAndValidate(document, version, request.supportedNetworks, paymentCoordinator);
     if (supportedNetworks.hasException())
         return supportedNetworks.releaseException();
     result.setSupportedNetworks(supportedNetworks.releaseReturnValue());
index 68c66b8..b80c937 100644 (file)
@@ -33,6 +33,7 @@
 
 namespace WebCore {
 
+class Document;
 class PaymentCoordinator;
 
 struct ApplePayRequestBase {
@@ -50,7 +51,7 @@ struct ApplePayRequestBase {
     Vector<String> supportedCountries;
 };
 
-ExceptionOr<ApplePaySessionPaymentRequest> convertAndValidate(unsigned version, ApplePayRequestBase&, const PaymentCoordinator&);
+ExceptionOr<ApplePaySessionPaymentRequest> convertAndValidate(Document&, unsigned version, ApplePayRequestBase&, const PaymentCoordinator&);
 
 } // namespace WebCore
 
index 308b99a..9d040a3 100644 (file)
@@ -207,9 +207,9 @@ static ExceptionOr<Vector<ApplePaySessionPaymentRequest::ShippingMethod>> conver
     return WTFMove(result);
 }
 
-static ExceptionOr<ApplePaySessionPaymentRequest> convertAndValidate(unsigned version, ApplePayPaymentRequest&& paymentRequest, const PaymentCoordinator& paymentCoordinator)
+static ExceptionOr<ApplePaySessionPaymentRequest> convertAndValidate(Document& document, unsigned version, ApplePayPaymentRequest&& paymentRequest, const PaymentCoordinator& paymentCoordinator)
 {
-    auto convertedRequest = convertAndValidate(version, paymentRequest, paymentCoordinator);
+    auto convertedRequest = convertAndValidate(document, version, paymentRequest, paymentCoordinator);
     if (convertedRequest.hasException())
         return convertedRequest.releaseException();
 
@@ -399,7 +399,7 @@ ExceptionOr<Ref<ApplePaySession>> ApplePaySession::create(Document& document, un
     if (!document.page())
         return Exception { InvalidAccessError, "Frame is detached" };
 
-    auto convertedPaymentRequest = convertAndValidate(version, WTFMove(paymentRequest), document.page()->paymentCoordinator());
+    auto convertedPaymentRequest = convertAndValidate(document, version, WTFMove(paymentRequest), document.page()->paymentCoordinator());
     if (convertedPaymentRequest.hasException())
         return convertedPaymentRequest.releaseException();
 
@@ -411,19 +411,17 @@ ApplePaySession::ApplePaySession(Document& document, unsigned version, ApplePayS
     , m_paymentRequest { WTFMove(paymentRequest) }
     , m_version { version }
 {
-    ASSERT(document.page()->paymentCoordinator().supportsVersion(version));
+    ASSERT(document.page()->paymentCoordinator().supportsVersion(document, version));
     suspendIfNeeded();
 }
 
 ApplePaySession::~ApplePaySession() = default;
 
-ExceptionOr<bool> ApplePaySession::supportsVersion(ScriptExecutionContext& scriptExecutionContext, unsigned version)
+ExceptionOr<bool> ApplePaySession::supportsVersion(Document& document, unsigned version)
 {
     if (!version)
         return Exception { InvalidAccessError };
 
-    auto& document = downcast<Document>(scriptExecutionContext);
-
     auto canCall = canCreateSession(document);
     if (canCall.hasException())
         return canCall.releaseException();
@@ -432,7 +430,7 @@ ExceptionOr<bool> ApplePaySession::supportsVersion(ScriptExecutionContext& scrip
     if (!page)
         return Exception { InvalidAccessError };
 
-    return page->paymentCoordinator().supportsVersion(version);
+    return page->paymentCoordinator().supportsVersion(document, version);
 }
 
 static bool shouldDiscloseApplePayCapability(Document& document)
@@ -444,10 +442,8 @@ static bool shouldDiscloseApplePayCapability(Document& document)
     return document.settings().applePayCapabilityDisclosureAllowed();
 }
 
-ExceptionOr<bool> ApplePaySession::canMakePayments(ScriptExecutionContext& scriptExecutionContext)
+ExceptionOr<bool> ApplePaySession::canMakePayments(Document& document)
 {
-    auto& document = downcast<Document>(scriptExecutionContext);
-
     auto canCall = canCreateSession(document);
     if (canCall.hasException())
         return canCall.releaseException();
@@ -456,13 +452,11 @@ ExceptionOr<bool> ApplePaySession::canMakePayments(ScriptExecutionContext& scrip
     if (!page)
         return Exception { InvalidAccessError };
 
-    return page->paymentCoordinator().canMakePayments();
+    return page->paymentCoordinator().canMakePayments(document);
 }
 
-ExceptionOr<void> ApplePaySession::canMakePaymentsWithActiveCard(ScriptExecutionContext& scriptExecutionContext, const String& merchantIdentifier, Ref<DeferredPromise>&& passedPromise)
+ExceptionOr<void> ApplePaySession::canMakePaymentsWithActiveCard(Document& document, const String& merchantIdentifier, Ref<DeferredPromise>&& passedPromise)
 {
-    auto& document = downcast<Document>(scriptExecutionContext);
-
     auto canCall = canCreateSession(document);
     if (canCall.hasException())
         return canCall.releaseException();
@@ -474,7 +468,7 @@ ExceptionOr<void> ApplePaySession::canMakePaymentsWithActiveCard(ScriptExecution
             return Exception { InvalidAccessError };
 
         auto& paymentCoordinator = page->paymentCoordinator();
-        bool canMakePayments = paymentCoordinator.canMakePayments();
+        bool canMakePayments = paymentCoordinator.canMakePayments(document);
 
         RunLoop::main().dispatch([promise, canMakePayments]() mutable {
             promise->resolve<IDLBoolean>(canMakePayments);
@@ -488,16 +482,14 @@ ExceptionOr<void> ApplePaySession::canMakePaymentsWithActiveCard(ScriptExecution
 
     auto& paymentCoordinator = page->paymentCoordinator();
 
-    paymentCoordinator.canMakePaymentsWithActiveCard(merchantIdentifier, document.domain(), [promise](bool canMakePayments) mutable {
+    paymentCoordinator.canMakePaymentsWithActiveCard(document, merchantIdentifier, [promise](bool canMakePayments) mutable {
         promise->resolve<IDLBoolean>(canMakePayments);
     });
     return { };
 }
 
-ExceptionOr<void> ApplePaySession::openPaymentSetup(ScriptExecutionContext& scriptExecutionContext, const String& merchantIdentifier, Ref<DeferredPromise>&& passedPromise)
+ExceptionOr<void> ApplePaySession::openPaymentSetup(Document& document, const String& merchantIdentifier, Ref<DeferredPromise>&& passedPromise)
 {
-    auto& document = downcast<Document>(scriptExecutionContext);
-
     auto canCall = canCreateSession(document);
     if (canCall.hasException())
         return canCall.releaseException();
@@ -512,14 +504,14 @@ ExceptionOr<void> ApplePaySession::openPaymentSetup(ScriptExecutionContext& scri
     auto& paymentCoordinator = page->paymentCoordinator();
 
     RefPtr<DeferredPromise> promise(WTFMove(passedPromise));
-    paymentCoordinator.openPaymentSetup(merchantIdentifier, document.domain(), [promise](bool result) mutable {
+    paymentCoordinator.openPaymentSetup(document, merchantIdentifier, [promise](bool result) mutable {
         promise->resolve<IDLBoolean>(result);
     });
 
     return { };
 }
 
-ExceptionOr<void> ApplePaySession::begin()
+ExceptionOr<void> ApplePaySession::begin(Document& document)
 {
     if (!canBegin())
         return Exception { InvalidAccessError, "Payment session is already active." };
@@ -527,13 +519,7 @@ ExceptionOr<void> ApplePaySession::begin()
     if (paymentCoordinator().hasActiveSession())
         return Exception { InvalidAccessError, "Page already has an active payment session." };
 
-    auto& document = *downcast<Document>(scriptExecutionContext());
-
-    Vector<URL> linkIconURLs;
-    for (auto& icon : LinkIconCollector { document }.iconsOfTypes({ LinkIconType::TouchIcon, LinkIconType::TouchPrecomposedIcon }))
-        linkIconURLs.append(icon.url);
-
-    if (!paymentCoordinator().beginPaymentSession(*this, document.url(), linkIconURLs, m_paymentRequest))
+    if (!paymentCoordinator().beginPaymentSession(document, *this, m_paymentRequest))
         return Exception { InvalidAccessError, "There is already has an active payment session." };
 
     m_state = State::Active;
index 7ec3982..88a63b8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-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
@@ -71,12 +71,12 @@ public:
     static const unsigned short STATUS_PIN_INCORRECT = 6;
     static const unsigned short STATUS_PIN_LOCKOUT = 7;
 
-    static ExceptionOr<bool> supportsVersion(ScriptExecutionContext&, unsigned version);
-    static ExceptionOr<bool> canMakePayments(ScriptExecutionContext&);
-    static ExceptionOr<void> canMakePaymentsWithActiveCard(ScriptExecutionContext&, const String& merchantIdentifier, Ref<DeferredPromise>&&);
-    static ExceptionOr<void> openPaymentSetup(ScriptExecutionContext&, const String& merchantIdentifier, Ref<DeferredPromise>&&);
+    static ExceptionOr<bool> supportsVersion(Document&, unsigned version);
+    static ExceptionOr<bool> canMakePayments(Document&);
+    static ExceptionOr<void> canMakePaymentsWithActiveCard(Document&, const String& merchantIdentifier, Ref<DeferredPromise>&&);
+    static ExceptionOr<void> openPaymentSetup(Document&, const String& merchantIdentifier, Ref<DeferredPromise>&&);
 
-    ExceptionOr<void> begin();
+    ExceptionOr<void> begin(Document&);
     ExceptionOr<void> abort();
     ExceptionOr<void> completeMerchantValidation(JSC::ExecState&, JSC::JSValue merchantSession);
     ExceptionOr<void> completeShippingMethodSelection(ApplePayShippingMethodUpdate&&);
index f68d919..66a89f8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-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
     const unsigned short STATUS_PIN_INCORRECT = 6;
     const unsigned short STATUS_PIN_LOCKOUT = 7;
 
-    [CallWith=ScriptExecutionContext, MayThrowException] static boolean supportsVersion(unsigned long version);
-    [CallWith=ScriptExecutionContext, MayThrowException] static boolean canMakePayments();
-    [CallWith=ScriptExecutionContext, MayThrowException] static Promise<boolean> canMakePaymentsWithActiveCard(DOMString merchantIdentifier);
-    [CallWith=ScriptExecutionContext, MayThrowException] static Promise<boolean> openPaymentSetup(DOMString merchantIdentifier);
+    [CallWith=Document, MayThrowException] static boolean supportsVersion(unsigned long version);
+    [CallWith=Document, MayThrowException] static boolean canMakePayments();
+    [CallWith=Document, MayThrowException] static Promise<boolean> canMakePaymentsWithActiveCard(DOMString merchantIdentifier);
+    [CallWith=Document, MayThrowException] static Promise<boolean> openPaymentSetup(DOMString merchantIdentifier);
 
-    [MayThrowException] void begin();
+    [CallWith=Document, MayThrowException] void begin();
     [MayThrowException] void abort();
     [MayThrowException, CallWith=ExecState] void completeMerchantValidation(any merchantSession);
     [MayThrowException, Conditional=APPLE_PAY_SESSION_V3] void completeShippingMethodSelection(ApplePayShippingMethodUpdate update);
index 659fe73..f877fde 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-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
@@ -28,6 +28,8 @@
 
 #if ENABLE(APPLE_PAY)
 
+#include "Document.h"
+#include "LinkIconCollector.h"
 #include "PaymentAuthorizationStatus.h"
 #include "PaymentCoordinatorClient.h"
 #include "PaymentSession.h"
@@ -46,34 +48,50 @@ PaymentCoordinator::~PaymentCoordinator()
     m_client.paymentCoordinatorDestroyed();
 }
 
-bool PaymentCoordinator::supportsVersion(unsigned version) const
+bool PaymentCoordinator::supportsVersion(Document& document, unsigned version) const
 {
+    if (!shouldAllowApplePay(document))
+        return false;
     return m_client.supportsVersion(version);
 }
 
-bool PaymentCoordinator::canMakePayments()
+bool PaymentCoordinator::canMakePayments(Document& document)
 {
+    if (!shouldAllowApplePay(document))
+        return false;
     return m_client.canMakePayments();
 }
 
-void PaymentCoordinator::canMakePaymentsWithActiveCard(const String& merchantIdentifier, const String& domainName, WTF::Function<void (bool)>&& completionHandler)
+void PaymentCoordinator::canMakePaymentsWithActiveCard(Document& document, const String& merchantIdentifier, WTF::Function<void(bool)>&& completionHandler)
 {
-    m_client.canMakePaymentsWithActiveCard(merchantIdentifier, domainName, WTFMove(completionHandler));
+    if (!shouldAllowApplePay(document))
+        return completionHandler(false);
+    m_client.canMakePaymentsWithActiveCard(merchantIdentifier, document.domain(), WTFMove(completionHandler));
 }
 
-void PaymentCoordinator::openPaymentSetup(const String& merchantIdentifier, const String& domainName, WTF::Function<void (bool)>&& completionHandler)
+void PaymentCoordinator::openPaymentSetup(Document& document, const String& merchantIdentifier, WTF::Function<void(bool)>&& completionHandler)
 {
-    m_client.openPaymentSetup(merchantIdentifier, domainName, WTFMove(completionHandler));
+    if (!shouldAllowApplePay(document))
+        return completionHandler(false);
+    m_client.openPaymentSetup(merchantIdentifier, document.domain(), WTFMove(completionHandler));
 }
 
-bool PaymentCoordinator::beginPaymentSession(PaymentSession& paymentSession, const URL& originatingURL, const Vector<URL>& linkIconURLs, const ApplePaySessionPaymentRequest& paymentRequest)
+bool PaymentCoordinator::beginPaymentSession(Document& document, PaymentSession& paymentSession, const ApplePaySessionPaymentRequest& paymentRequest)
 {
     ASSERT(!m_activeSession);
 
-    if (!m_client.showPaymentUI(originatingURL, linkIconURLs, paymentRequest))
+    if (!shouldAllowApplePay(document))
+        return false;
+
+    Vector<URL> linkIconURLs;
+    for (auto& icon : LinkIconCollector { document }.iconsOfTypes({ LinkIconType::TouchIcon, LinkIconType::TouchPrecomposedIcon }))
+        linkIconURLs.append(icon.url);
+
+    if (!m_client.showPaymentUI(document.url(), linkIconURLs, paymentRequest))
         return false;
 
     m_activeSession = &paymentSession;
+    document.setHasStartedApplePaySession();
     return true;
 }
 
@@ -195,8 +213,11 @@ void PaymentCoordinator::didCancelPaymentSession()
     m_activeSession = nullptr;
 }
 
-Optional<String> PaymentCoordinator::validatedPaymentNetwork(unsigned version, const String& paymentNetwork) const
+Optional<String> PaymentCoordinator::validatedPaymentNetwork(Document& document, unsigned version, const String& paymentNetwork) const
 {
+    if (!shouldAllowApplePay(document))
+        return WTF::nullopt;
+
     if (version < 2 && equalIgnoringASCIICase(paymentNetwork, "jcb"))
         return WTF::nullopt;
 
@@ -206,6 +227,32 @@ Optional<String> PaymentCoordinator::validatedPaymentNetwork(unsigned version, c
     return m_client.validatedPaymentNetwork(paymentNetwork);
 }
 
+bool PaymentCoordinator::shouldAllowApplePay(Document& document) const
+{
+    if (m_client.supportsUnrestrictedApplePay())
+        return true;
+
+    if (document.hasEvaluatedUserAgentScripts() || document.isRunningUserScripts()) {
+        ASSERT(shouldAllowUserAgentScripts(document));
+        return false;
+    }
+
+    return true;
+}
+
+bool PaymentCoordinator::shouldAllowUserAgentScripts(Document& document) const
+{
+    if (m_client.supportsUnrestrictedApplePay())
+        return true;
+
+    if (document.hasStartedApplePaySession()) {
+        ASSERT(shouldAllowApplePay(document));
+        return false;
+    }
+
+    return true;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(APPLE_PAY)
index 0142de5..3b321a2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-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
@@ -32,6 +32,7 @@
 
 namespace WebCore {
 
+class Document;
 class Payment;
 class PaymentCoordinatorClient;
 class PaymentContact;
@@ -52,14 +53,14 @@ public:
 
     PaymentCoordinatorClient& client() { return m_client; }
 
-    bool supportsVersion(unsigned version) const;
-    bool canMakePayments();
-    void canMakePaymentsWithActiveCard(const String& merchantIdentifier, const String& domainName, WTF::Function<void (bool)>&& completionHandler);
-    void openPaymentSetup(const String& merchantIdentifier, const String& domainName, WTF::Function<void (bool)>&& completionHandler);
+    bool supportsVersion(Document&, unsigned version) const;
+    bool canMakePayments(Document&);
+    void canMakePaymentsWithActiveCard(Document&, const String& merchantIdentifier, WTF::Function<void(bool)>&& completionHandler);
+    void openPaymentSetup(Document&, const String& merchantIdentifier, WTF::Function<void(bool)>&& completionHandler);
 
     bool hasActiveSession() const { return m_activeSession; }
 
-    bool beginPaymentSession(PaymentSession&, const URL& originatingURL, const Vector<URL>& linkIconURLs, const ApplePaySessionPaymentRequest&);
+    bool beginPaymentSession(Document&, PaymentSession&, const ApplePaySessionPaymentRequest&);
     void completeMerchantValidation(const PaymentMerchantSession&);
     void completeShippingMethodSelection(Optional<ShippingMethodUpdate>&&);
     void completeShippingContactSelection(Optional<ShippingContactUpdate>&&);
@@ -75,7 +76,10 @@ public:
     WEBCORE_EXPORT void didSelectShippingContact(const PaymentContact&);
     WEBCORE_EXPORT void didCancelPaymentSession();
 
-    Optional<String> validatedPaymentNetwork(unsigned version, const String&) const;
+    Optional<String> validatedPaymentNetwork(Document&, unsigned version, const String&) const;
+
+    WEBCORE_EXPORT bool shouldAllowApplePay(Document&) const;
+    WEBCORE_EXPORT bool shouldAllowUserAgentScripts(Document&) const;
 
 private:
     PaymentCoordinatorClient& m_client;
index 0dab573..e812ddb 100644 (file)
@@ -37,6 +37,7 @@
 
 namespace WebCore {
 
+class Document;
 class PaymentMerchantSession;
 struct PaymentAuthorizationResult;
 struct PaymentMethodUpdate;
@@ -65,6 +66,8 @@ public:
     virtual bool isMockPaymentCoordinator() const { return false; }
     virtual bool isWebPaymentCoordinator() const { return false; }
 
+    virtual bool supportsUnrestrictedApplePay() const { return true; }
+
 protected:
     virtual ~PaymentCoordinatorClient() = default;
 
index da71c2f..d97b5d8 100644 (file)
@@ -185,9 +185,9 @@ static void mergePaymentOptions(const PaymentOptions& options, ApplePaySessionPa
         request.setShippingType(convert(options.shippingType));
 }
 
-ExceptionOr<void> ApplePayPaymentHandler::show()
+ExceptionOr<void> ApplePayPaymentHandler::show(Document& document)
 {
-    auto validatedRequest = convertAndValidate(m_applePayRequest->version, *m_applePayRequest, paymentCoordinator());
+    auto validatedRequest = convertAndValidate(document, m_applePayRequest->version, *m_applePayRequest, paymentCoordinator());
     if (validatedRequest.hasException())
         return validatedRequest.releaseException();
 
@@ -217,11 +217,9 @@ ExceptionOr<void> ApplePayPaymentHandler::show()
     if (exception.hasException())
         return exception.releaseException();
 
-    Vector<URL> linkIconURLs;
-    for (auto& icon : LinkIconCollector { document() }.iconsOfTypes({ LinkIconType::TouchIcon, LinkIconType::TouchPrecomposedIcon }))
-        linkIconURLs.append(icon.url);
+    if (!paymentCoordinator().beginPaymentSession(document, *this, request))
+        return Exception { AbortError };
 
-    paymentCoordinator().beginPaymentSession(*this, document().url(), linkIconURLs, request);
     return { };
 }
 
@@ -230,9 +228,9 @@ void ApplePayPaymentHandler::hide()
     paymentCoordinator().abortPaymentSession();
 }
 
-void ApplePayPaymentHandler::canMakePayment(Function<void(bool)>&& completionHandler)
+void ApplePayPaymentHandler::canMakePayment(Document& document, Function<void(bool)>&& completionHandler)
 {
-    completionHandler(paymentCoordinator().canMakePayments());
+    completionHandler(paymentCoordinator().canMakePayments(document));
 }
 
 ExceptionOr<Vector<ApplePaySessionPaymentRequest::ShippingMethod>> ApplePayPaymentHandler::computeShippingMethods()
@@ -532,12 +530,7 @@ ExceptionOr<void> ApplePayPaymentHandler::retry(PaymentValidationErrors&& valida
 
 unsigned ApplePayPaymentHandler::version() const
 {
-    if (!m_applePayRequest)
-        return 0;
-    
-    auto version = m_applePayRequest->version;
-    ASSERT(paymentCoordinator().supportsVersion(version));
-    return version;
+    return m_applePayRequest ? m_applePayRequest->version : 0;
 }
 
 void ApplePayPaymentHandler::validateMerchant(URL&& validationURL)
index 8bbc7aa..803b54f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -65,9 +65,9 @@ private:
 
     // PaymentHandler
     ExceptionOr<void> convertData(JSC::JSValue&&) final;
-    ExceptionOr<void> show() final;
+    ExceptionOr<void> show(Document&) final;
     void hide() final;
-    void canMakePayment(WTF::Function<void(bool)>&& completionHandler) final;
+    void canMakePayment(Document&, WTF::Function<void(bool)>&& completionHandler) final;
     ExceptionOr<void> detailsUpdated(PaymentRequest::UpdateReason, String&& error, AddressErrors&&, PayerErrorFields&&, JSC::JSObject* paymentMethodErrors) final;
     ExceptionOr<void> merchantValidationCompleted(JSC::JSValue&&) final;
     void complete(Optional<PaymentComplete>&&) final;
index 91ea35e..0b4df03 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -49,9 +49,9 @@ public:
     static bool hasActiveSession(Document&);
 
     virtual ExceptionOr<void> convertData(JSC::JSValue&&) = 0;
-    virtual ExceptionOr<void> show() = 0;
+    virtual ExceptionOr<void> show(Document&) = 0;
     virtual void hide() = 0;
-    virtual void canMakePayment(WTF::Function<void(bool)>&& completionHandler) = 0;
+    virtual void canMakePayment(Document&, WTF::Function<void(bool)>&& completionHandler) = 0;
     virtual ExceptionOr<void> detailsUpdated(PaymentRequest::UpdateReason, String&& error, AddressErrors&&, PayerErrorFields&&, JSC::JSObject* paymentMethodErrors) = 0;
     virtual ExceptionOr<void> merchantValidationCompleted(JSC::JSValue&&) = 0;
     virtual void complete(Optional<PaymentComplete>&&) = 0;
index a47a95a..05017e4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -428,7 +428,7 @@ void PaymentRequest::show(Document& document, RefPtr<DOMPromise>&& detailsPromis
         return;
     }
 
-    auto exception = selectedPaymentHandler->show();
+    auto exception = selectedPaymentHandler->show(document);
     if (exception.hasException()) {
         settleShowPromise(exception.releaseException());
         return;
@@ -506,7 +506,7 @@ void PaymentRequest::canMakePayment(Document& document, CanMakePaymentPromise&&
         if (!handler)
             continue;
 
-        handler->canMakePayment([promise = WTFMove(promise)](bool canMakePayment) mutable {
+        handler->canMakePayment(document, [promise = WTFMove(promise)](bool canMakePayment) mutable {
             promise.resolve(canMakePayment);
         });
         return;
index 9d8b575..09aa824 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2006-2017 Apple Inc. All rights reserved.
+ *  Copyright (C) 2006-2019 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -44,6 +44,7 @@
 #include "Page.h"
 #include "PageConsoleClient.h"
 #include "PageGroup.h"
+#include "PaymentCoordinator.h"
 #include "PluginViewBase.h"
 #include "RuntimeApplicationChecks.h"
 #include "ScriptDisallowedScope.h"
@@ -554,6 +555,25 @@ JSValue ScriptController::executeScriptInWorld(DOMWrapperWorld& world, const Str
     return evaluateInWorld(sourceCode, world, exceptionDetails);
 }
 
+JSValue ScriptController::executeUserAgentScriptInWorld(DOMWrapperWorld& world, const String& script, bool forceUserGesture, ExceptionDetails* exceptionDetails)
+{
+    auto& document = *m_frame.document();
+    if (!shouldAllowUserAgentScripts(document))
+        return { };
+
+    document.setHasEvaluatedUserAgentScripts();
+    return executeScriptInWorld(world, script, forceUserGesture, exceptionDetails);
+}
+
+bool ScriptController::shouldAllowUserAgentScripts(Document& document) const
+{
+#if ENABLE(APPLE_PAY)
+    if (auto page = m_frame.page())
+        return page->paymentCoordinator().shouldAllowUserAgentScripts(document);
+#endif
+    return true;
+}
+
 bool ScriptController::canExecuteScripts(ReasonForCallingCanExecuteScripts reason)
 {
     if (reason == AboutToExecuteScript)
index f7bee05..81eb381 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ *  Copyright (C) 2008-2019 Apple Inc. All rights reserved.
  *  Copyright (C) 2008 Eric Seidel <eric@webkit.org>
  *
  *  This library is free software; you can redistribute it and/or
@@ -90,7 +90,10 @@ public:
 
     JSC::JSValue executeScript(const ScriptSourceCode&, ExceptionDetails* = nullptr);
     WEBCORE_EXPORT JSC::JSValue executeScript(const String& script, bool forceUserGesture = false, ExceptionDetails* = nullptr);
-    WEBCORE_EXPORT JSC::JSValue executeScriptInWorld(DOMWrapperWorld&, const String& script, bool forceUserGesture = false, ExceptionDetails* = nullptr);
+    JSC::JSValue executeScriptInWorld(DOMWrapperWorld&, const String& script, bool forceUserGesture = false, ExceptionDetails* = nullptr);
+    WEBCORE_EXPORT JSC::JSValue executeUserAgentScriptInWorld(DOMWrapperWorld&, const String& script, bool forceUserGesture, ExceptionDetails* = nullptr);
+
+    bool shouldAllowUserAgentScripts(Document&) const;
 
     // Returns true if argument is a JavaScript URL.
     bool executeIfJavaScriptURL(const URL&, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL = ReplaceDocumentIfJavaScriptURL);
index 1835524..a7bd98d 100644 (file)
@@ -7549,12 +7549,15 @@ void Document::ensurePlugInsInjectedScript(DOMWrapperWorld& world)
     if (m_hasInjectedPlugInsScript)
         return;
 
+    auto& scriptController = frame()->script();
+
     // Use the JS file provided by the Chrome client, or fallback to the default one.
     String jsString = page()->chrome().client().plugInExtraScript();
-    if (!jsString)
+    if (!jsString || !scriptController.shouldAllowUserAgentScripts(*this))
         jsString = String(plugInsJavaScript, sizeof(plugInsJavaScript));
 
-    frame()->script().evaluateInWorld(ScriptSourceCode(jsString), world);
+    setHasEvaluatedUserAgentScripts();
+    scriptController.evaluateInWorld(ScriptSourceCode(jsString), world);
 
     m_hasInjectedPlugInsScript = true;
 }
@@ -8726,4 +8729,53 @@ ContentChangeObserver& Document::contentChangeObserver()
 }
 #endif
 
+bool Document::hasEvaluatedUserAgentScripts() const
+{
+    auto& top = topDocument();
+    return this == &top ? m_hasEvaluatedUserAgentScripts : top.hasEvaluatedUserAgentScripts();
+}
+
+bool Document::isRunningUserScripts() const
+{
+    auto& top = topDocument();
+    return this == &top ? m_isRunningUserScripts : top.isRunningUserScripts();
+}
+
+void Document::setAsRunningUserScripts()
+{
+    auto& top = topDocument();
+    if (this == &top)
+        m_isRunningUserScripts = true;
+    else
+        top.setAsRunningUserScripts();
+}
+
+void Document::setHasEvaluatedUserAgentScripts()
+{
+    auto& top = topDocument();
+    if (this == &top)
+        m_hasEvaluatedUserAgentScripts = true;
+    else
+        top.setHasEvaluatedUserAgentScripts();
+}
+
+#if ENABLE(APPLE_PAY)
+
+bool Document::hasStartedApplePaySession() const
+{
+    auto& top = topDocument();
+    return this == &top ? m_hasStartedApplePaySession : top.hasStartedApplePaySession();
+}
+
+void Document::setHasStartedApplePaySession()
+{
+    auto& top = topDocument();
+    if (this == &top)
+        m_hasStartedApplePaySession = true;
+    else
+        top.setHasStartedApplePaySession();
+}
+
+#endif
+
 } // namespace WebCore
index c32f786..57714d7 100644 (file)
@@ -3,7 +3,7 @@
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
  *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2004-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2019 Apple Inc. All rights reserved.
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
  * Copyright (C) 2011 Google Inc. All rights reserved.
@@ -1537,8 +1537,14 @@ public:
     void setPaintWorkletGlobalScopeForName(const String& name, Ref<PaintWorkletGlobalScope>&&);
 #endif
 
-    void setAsRunningUserScripts() { m_isRunningUserScripts = true; }
-    bool isRunningUserScripts() const { return m_isRunningUserScripts; }
+    WEBCORE_EXPORT bool hasEvaluatedUserAgentScripts() const;
+    WEBCORE_EXPORT bool isRunningUserScripts() const;
+    WEBCORE_EXPORT void setAsRunningUserScripts();
+    void setHasEvaluatedUserAgentScripts();
+#if ENABLE(APPLE_PAY)
+    WEBCORE_EXPORT bool hasStartedApplePaySession() const;
+    WEBCORE_EXPORT void setHasStartedApplePaySession();
+#endif
 
     void frameWasDisconnectedFromOwner();
 
@@ -2095,7 +2101,11 @@ private:
     HashMap<String, Ref<PaintWorkletGlobalScope>> m_paintWorkletGlobalScopes;
 #endif
 
+    bool m_hasEvaluatedUserAgentScripts { false };
     bool m_isRunningUserScripts { false };
+#if ENABLE(APPLE_PAY)
+    bool m_hasStartedApplePaySession { false };
+#endif
 
     Ref<UndoManager> m_undoManager;
 #if PLATFORM(IOS_FAMILY)
index 614b4e4..5e79916 100644 (file)
@@ -147,7 +147,7 @@ DocumentThreadableLoader::DocumentThreadableLoader(Document& document, Threadabl
     if (shouldSetHTTPHeadersToKeep())
         m_options.httpHeadersToKeep = httpHeadersToKeepFromCleaning(request.httpHeaderFields());
 
-    if (document.topDocument().isRunningUserScripts() && SchemeRegistry::isUserExtensionScheme(request.url().protocol().toStringWithoutCopying())) {
+    if (document.isRunningUserScripts() && SchemeRegistry::isUserExtensionScheme(request.url().protocol().toStringWithoutCopying())) {
         m_options.mode = FetchOptions::Mode::NoCors;
         m_options.filteringPolicy = ResponseFilteringPolicy::Disable;
     }
index 7d60fdf..8a58aea 100644 (file)
@@ -5,7 +5,7 @@
  *                     2000 Simon Hausmann <hausmann@kde.org>
  *                     2000 Stefan Schimanski <1Stein@gmx.de>
  *                     2001 George Staikos <staikos@kde.org>
- * Copyright (C) 2004-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2019 Apple Inc. All rights reserved.
  * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
@@ -769,8 +769,10 @@ void Frame::injectUserScriptImmediately(DOMWrapperWorld& world, const UserScript
         return;
     if (!UserContentURLPattern::matchesPatterns(document->url(), script.whitelist(), script.blacklist()))
         return;
+    if (!m_script->shouldAllowUserAgentScripts(*document))
+        return;
 
-    document->topDocument().setAsRunningUserScripts();
+    document->setAsRunningUserScripts();
     loader().client().willInjectUserScript(world);
     m_script->evaluateInWorld(ScriptSourceCode(script.source(), URL(script.url())), world);
 }
index 4c77bc2..d7d5283 100644 (file)
@@ -662,7 +662,7 @@ applePayCapabilityDisclosureAllowed:
   initial: true
 applePayEnabled:
   conditional: APPLE_PAY
-  initial: false
+  initial: defaultApplePayEnabled
 applePayRemoteUIEnabled:
   conditional: APPLE_PAY_REMOTE_UI
   initial: true
index 7c9ddfc..7084a6a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -109,5 +109,11 @@ static const bool defaultConicGradient = true;
 #else
 static const bool defaultConicGradient = false;
 #endif
+    
+#if ENABLE(APPLE_PAY_REMOTE_UI)
+static const bool defaultApplePayEnabled = true;
+#else
+static const bool defaultApplePayEnabled = false;
+#endif
 
 }
index 07de946..b5a00c5 100644 (file)
@@ -4541,9 +4541,16 @@ void Internals::setQuickLookPassword(const String& password)
 
 void Internals::setAsRunningUserScripts(Document& document)
 {
-    document.topDocument().setAsRunningUserScripts();
+    document.setAsRunningUserScripts();
 }
 
+#if ENABLE(APPLE_PAY)
+void Internals::setHasStartedApplePaySession(Document& document)
+{
+    document.setHasStartedApplePaySession();
+}
+#endif
+
 #if ENABLE(WEBGL)
 void Internals::simulateWebGLContextChanged(WebGLRenderingContext& context)
 {
index 311db6a..5212839 100644 (file)
@@ -667,6 +667,9 @@ public:
     void setQuickLookPassword(const String&);
 
     void setAsRunningUserScripts(Document&);
+#if ENABLE(APPLE_PAY)
+    void setHasStartedApplePaySession(Document&);
+#endif
 
 #if ENABLE(WEBGL)
     void simulateWebGLContextChanged(WebGLRenderingContext&);
index 26025f7..a2f8c6a 100644 (file)
@@ -651,6 +651,7 @@ enum CompositingPolicy {
     void setQuickLookPassword(DOMString password);
 
     [CallWith=Document] void setAsRunningUserScripts();
+    [CallWith=Document, Conditional=APPLE_PAY] void setHasStartedApplePaySession();
 
     void disableTileSizeUpdateDelay();
     void setSpeculativeTilingDelayDisabledForTesting(boolean disabled);
index b07ea3e..14a0c97 100644 (file)
@@ -60,14 +60,17 @@ public:
     const MockPaymentContactFields& requiredBillingContactFields() const { return m_requiredBillingContactFields; }
     const MockPaymentContactFields& requiredShippingContactFields() const { return m_requiredShippingContactFields; }
 
+    bool supportsUnrestrictedApplePay() const final { return m_supportsUnrestrictedApplePay; }
+    void setSupportsUnrestrictedApplePay(bool supports) { m_supportsUnrestrictedApplePay = supports; }
+
     void ref() const { }
     void deref() const { }
 
 private:
     Optional<String> validatedPaymentNetwork(const String&) final;
     bool canMakePayments() final;
-    void canMakePaymentsWithActiveCard(const String&, const String&, CompletionHandler<void(bool)>&&);
-    void openPaymentSetup(const String&, const String&, CompletionHandler<void(bool)>&&);
+    void canMakePaymentsWithActiveCard(const String&, const String&, CompletionHandler<void(bool)>&&) final;
+    void openPaymentSetup(const String&, const String&, CompletionHandler<void(bool)>&&) final;
     bool showPaymentUI(const URL&, const Vector<URL>&, const ApplePaySessionPaymentRequest&) final;
     void completeMerchantValidation(const PaymentMerchantSession&) final;
     void completeShippingMethodSelection(Optional<ShippingMethodUpdate>&&) final;
@@ -93,6 +96,7 @@ private:
     HashSet<String, ASCIICaseInsensitiveHash> m_availablePaymentNetworks;
     MockPaymentContactFields m_requiredBillingContactFields;
     MockPaymentContactFields m_requiredShippingContactFields;
+    bool m_supportsUnrestrictedApplePay { true };
 };
 
 } // namespace WebCore
index 785546d..aa0f94b 100644 (file)
@@ -41,4 +41,6 @@
     readonly attribute sequence<ApplePayShippingMethod> shippingMethods;
     readonly attribute MockPaymentContactFields requiredBillingContactFields;
     readonly attribute MockPaymentContactFields requiredShippingContactFields;
+
+    attribute boolean supportsUnrestrictedApplePay;
 };
index d6dbc1d..252595f 100644 (file)
@@ -1,3 +1,44 @@
+2019-03-21  Andy Estes  <aestes@apple.com>
+
+        [iOS] Apple Pay should be available in documents with no user agent scripts
+        https://bugs.webkit.org/show_bug.cgi?id=196061
+        <rdar://problem/48649391>
+
+        Reviewed by Brady Eidson.
+
+        * Shared/AuxiliaryProcess.h:
+        * Shared/Cocoa/AuxiliaryProcessCocoa.mm:
+        (WebKit::AuxiliaryProcess::parentProcessHasEntitlement):
+
+        Added a convenience function for checking parent process entitlements.
+
+        * Shared/WebPreferences.yaml:
+        * Shared/WebPreferencesDefaultValues.h:
+        * UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
+        (-[WKWebViewConfiguration init]):
+
+        Enabled Apple Pay by default on platforms that enable APPLE_PAY_REMOTE_UI.
+
+        * WebProcess/ApplePay/WebPaymentCoordinator.cpp:
+        (WebKit::WebPaymentCoordinator::supportsUnrestrictedApplePay const):
+        * WebProcess/ApplePay/WebPaymentCoordinator.h:
+
+        Implemented supportsUnrestrictedApplePay by checking for the
+        com.apple.private.WebKit.UnrestrictedApplePay entitlement on platforms that enable
+        APPLE_PAY_REMOTE_UI.
+
+        * WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInLoadDelegate.h:
+        * WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm:
+        (didClearWindowObjectForFrame):
+        (setUpPageLoaderClient):
+
+        Added injected bundle SPI that TestWebKitAPI uses to inject the WebCore Internals interface.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::runJavaScript):
+
+        Changed to call ScriptController::executeUserAgentScriptInWorld.
+
 2019-03-21  Chris Dumez  <cdumez@apple.com>
 
         WebKit should throw when trying to create a WKWebView with a related view that is using a different data store
index 42f10c2..32b0a47 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-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
@@ -78,6 +78,10 @@ public:
 #if PLATFORM(MAC)
     static bool isSystemWebKit();
 #endif
+    
+#if PLATFORM(COCOA)
+    bool parentProcessHasEntitlement(const char* entitlement);
+#endif
 
 protected:
     explicit AuxiliaryProcess();
index b813f0c..e2d9eee 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -27,6 +27,7 @@
 #import "AuxiliaryProcess.h"
 
 #import "WKCrashReporter.h"
+#import <wtf/cocoa/Entitlements.h>
 
 namespace WebKit {
 
@@ -36,4 +37,9 @@ void AuxiliaryProcess::didReceiveInvalidMessage(IPC::Connection&, IPC::StringRef
     CRASH();
 }
 
+bool AuxiliaryProcess::parentProcessHasEntitlement(const char* entitlement)
+{
+    return WTF::hasEntitlement(m_connection->xpcConnection(), entitlement);
+}
+
 }
index 761411a..8be3081 100644 (file)
@@ -678,7 +678,7 @@ SelectionPaintingWithoutSelectionGapsEnabled:
 
 ApplePayEnabled:
   type: bool
-  defaultValue: false
+  defaultValue: DEFAULT_APPLE_PAY_ENABLED
   condition: ENABLE(APPLE_PAY)
 
 ApplePayCapabilityDisclosureAllowed:
index 0bdf87a..39ecc65 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-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
@@ -259,3 +259,9 @@ bool defaultCustomPasteboardDataEnabled();
 #define DEFAULT_FAST_CLICKS_EVERYWHERE true
 #endif
 #endif
+
+#if ENABLE(APPLE_PAY_REMOTE_UI)
+#define DEFAULT_APPLE_PAY_ENABLED true
+#else
+#define DEFAULT_APPLE_PAY_ENABLED false
+#endif
index 4d041f0..77b19dd 100644 (file)
@@ -249,6 +249,10 @@ static _WKDragLiftDelay toDragLiftDelay(NSUInteger value)
     _editableImagesEnabled = NO;
     _undoManagerAPIEnabled = NO;
 
+#if ENABLE(APPLE_PAY)
+    _applePayEnabled = DEFAULT_APPLE_PAY_ENABLED;
+#endif
+
     return self;
 }
 
index b4aece9..5112636 100644 (file)
@@ -157,6 +157,16 @@ void WebPaymentCoordinator::paymentCoordinatorDestroyed()
     delete this;
 }
 
+bool WebPaymentCoordinator::supportsUnrestrictedApplePay() const
+{
+#if ENABLE(APPLE_PAY_REMOTE_UI)
+    static bool hasEntitlement = WebProcess::singleton().parentProcessHasEntitlement("com.apple.private.WebKit.UnrestrictedApplePay");
+    return hasEntitlement;
+#else
+    return true;
+#endif
+}
+
 IPC::Connection* WebPaymentCoordinator::messageSenderConnection() const
 {
 #if ENABLE(APPLE_PAY_REMOTE_UI)
index 85b2b1a..d9277fe 100644 (file)
@@ -78,9 +78,11 @@ private:
 
     bool isWebPaymentCoordinator() const override { return true; }
 
+    bool supportsUnrestrictedApplePay() const override;
+
     // IPC::MessageReceiver.
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
-    
+
     // IPC::MessageSender.
     IPC::Connection* messageSenderConnection() const final;
     uint64_t messageSenderDestinationID() const final;
index 1f38d22..37428ea 100644 (file)
@@ -44,6 +44,7 @@
 - (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController*)controller didFailLoadWithErrorForFrame:(WKWebProcessPlugInFrame *)frame error:(NSError *)error;
 - (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController*)controller didFinishLoadForFrame:(WKWebProcessPlugInFrame *)frame;
 - (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController*)controller didSameDocumentNavigation:(_WKSameDocumentNavigationType)navigationType forFrame:(WKWebProcessPlugInFrame *)frame;
+- (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController *)controller didClearWindowObjectForFrame:(WKWebProcessPlugInFrame *)frame inScriptWorld:(WKWebProcessPlugInScriptWorld *)scriptWorld;
 - (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController*)controller globalObjectIsAvailableForFrame:(WKWebProcessPlugInFrame *)frame inScriptWorld:(WKWebProcessPlugInScriptWorld *)scriptWorld;
 - (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController *)controller didRemoveFrameFromHierarchy:(WKWebProcessPlugInFrame *)frame;
 - (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController *)controller didHandleOnloadEventsForFrame:(WKWebProcessPlugInFrame *)frame;
index 2adb315..5a99deb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-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
@@ -104,6 +104,15 @@ static void didFinishLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame,
         [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didFinishLoadForFrame:wrapper(*WebKit::toImpl(frame))];
 }
 
+static void didClearWindowObjectForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKBundleScriptWorldRef scriptWorld, const void* clientInfo)
+{
+    auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
+    auto loadDelegate = pluginContextController->_loadDelegate.get();
+    
+    if ([loadDelegate respondsToSelector:@selector(webProcessPlugInBrowserContextController:didClearWindowObjectForFrame:inScriptWorld:)])
+        [loadDelegate webProcessPlugInBrowserContextController:pluginContextController didClearWindowObjectForFrame:wrapper(*WebKit::toImpl(frame)) inScriptWorld:wrapper(*WebKit::toImpl(scriptWorld))];
+}
+
 static void globalObjectIsAvailableForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKBundleScriptWorldRef scriptWorld, const void* clientInfo)
 {
     auto pluginContextController = (__bridge WKWebProcessPlugInBrowserContextController *)clientInfo;
@@ -235,6 +244,7 @@ static void setUpPageLoaderClient(WKWebProcessPlugInBrowserContextController *co
     client.didFailLoadWithErrorForFrame = didFailLoadWithErrorForFrame;
     client.didSameDocumentNavigationForFrame = didSameDocumentNavigationForFrame;
     client.didFinishLoadForFrame = didFinishLoadForFrame;
+    client.didClearWindowObjectForFrame = didClearWindowObjectForFrame;
     client.globalObjectIsAvailableForFrame = globalObjectIsAvailableForFrame;
     client.didRemoveFrameFromHierarchy = didRemoveFrameFromHierarchy;
     client.didHandleOnloadEventsForFrame = didHandleOnloadEventsForFrame;
index 4a5ade5..2497ee7 100644 (file)
@@ -3289,7 +3289,7 @@ void WebPage::runJavaScript(const String& script, bool forceUserGesture, Optiona
     ExceptionDetails details;
     auto* world = worldName ? InjectedBundleScriptWorld::find(worldName.value()) : &InjectedBundleScriptWorld::normalWorld();
     if (world) {
-        if (JSValue resultValue = m_mainFrame->coreFrame()->script().executeScriptInWorld(world->coreWorld(), script, forceUserGesture, &details)) {
+        if (JSValue resultValue = m_mainFrame->coreFrame()->script().executeUserAgentScriptInWorld(world->coreWorld(), script, forceUserGesture, &details)) {
             hadException = false;
             serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContextForWorld(world),
                 toRef(m_mainFrame->coreFrame()->script().globalObject(world->coreWorld())->globalExec(), resultValue), nullptr);
index 20096a4..8de9efa 100644 (file)
@@ -1,3 +1,14 @@
+2019-03-21  Andy Estes  <aestes@apple.com>
+
+        [iOS] Apple Pay should be available in documents with no user agent scripts
+        https://bugs.webkit.org/show_bug.cgi?id=196061
+        <rdar://problem/48649391>
+
+        Reviewed by Brady Eidson.
+
+        * WebView/WebFrame.mm:
+        (-[WebFrame _stringByEvaluatingJavaScriptFromString:withGlobalObject:inScriptWorld:]):
+
 2019-03-20  Simon Fraser  <simon.fraser@apple.com>
 
         Rename ENABLE_ACCELERATED_OVERFLOW_SCROLLING macro to ENABLE_OVERFLOW_SCROLLING_TOUCH
index e0459f7..cb73d81 100644 (file)
@@ -2102,7 +2102,7 @@ static WebFrameLoadType toWebFrameLoadType(FrameLoadType frameLoadType)
     ASSERT(frame->document());
     RetainPtr<WebFrame> webFrame(kit(frame)); // Running arbitrary JavaScript can destroy the frame.
 
-    JSC::JSValue result = frame->script().executeScriptInWorld(*core(world), string, true);
+    JSC::JSValue result = frame->script().executeUserAgentScriptInWorld(*core(world), string, true);
 
     if (!webFrame->_private->coreFrame) // In case the script removed our frame from the page.
         return @"";
index ed96858..c7fd39b 100644 (file)
@@ -1,3 +1,28 @@
+2019-03-21  Andy Estes  <aestes@apple.com>
+
+        [iOS] Apple Pay should be available in documents with no user agent scripts
+        https://bugs.webkit.org/show_bug.cgi?id=196061
+        <rdar://problem/48649391>
+
+        Reviewed by Brady Eidson.
+
+        Added API tests and related infrastructure.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/ApplePay.mm: Added.
+        (-[TestApplePayScriptMessageHandler initWithExpectation:]):
+        (-[TestApplePayScriptMessageHandler userContentController:didReceiveScriptMessage:]):
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WebKitCocoa/apple-pay-active-session.html: Added.
+        * TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability-in-iframe.html: Added.
+        * TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability.html: Added.
+        * TestWebKitAPI/cocoa/TestProtocol.mm:
+        (-[TestProtocol startLoading]):
+        * TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.h: Added.
+        * TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.mm: Added.
+        (-[WebProcessPlugInWithInternals webProcessPlugIn:didCreateBrowserContextController:]):
+        (-[WebProcessPlugInWithInternals webProcessPlugInBrowserContextController:didClearWindowObjectForFrame:inScriptWorld:]):
+
 2019-03-21  Jonathan Bedard  <jbedard@apple.com>
 
         REGRESSSION (r243297): webkitpy tests broken
index fd20522..5bf4900 100644 (file)
                A155022A1E05020B00A24C57 /* DuplicateCompletionHandlerCalls.mm in Sources */ = {isa = PBXBuildFile; fileRef = A15502281E05020B00A24C57 /* DuplicateCompletionHandlerCalls.mm */; };
                A155022C1E050D0300A24C57 /* duplicate-completion-handler-calls.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A155022B1E050BC500A24C57 /* duplicate-completion-handler-calls.html */; };
                A16F66BA1C40EB4F00BD4D24 /* ContentFiltering.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A16F66B91C40EA2000BD4D24 /* ContentFiltering.html */; };
+               A1798B7F22431D2B000764BD /* libWebCoreTestSupport.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A1798B7E22431D2B000764BD /* libWebCoreTestSupport.dylib */; };
+               A1798B8222431D65000764BD /* ApplePay.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1798B8122431D65000764BD /* ApplePay.mm */; };
+               A1798B8522433647000764BD /* WebProcessPlugInWithInternals.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1798B8422433647000764BD /* WebProcessPlugInWithInternals.mm */; };
+               A1798B872243449B000764BD /* apple-pay-availability.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A1798B862243446B000764BD /* apple-pay-availability.html */; };
+               A1798B8922435E29000764BD /* apple-pay-availability-in-iframe.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A1798B8822435D2E000764BD /* apple-pay-availability-in-iframe.html */; };
+               A1798B8B224361A4000764BD /* apple-pay-active-session.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = A1798B8A2243611A000764BD /* apple-pay-active-session.html */; };
                A17991881E1C994E00A505ED /* SharedBuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = A17991861E1C994E00A505ED /* SharedBuffer.mm */; };
                A179918B1E1CA24100A505ED /* SharedBufferTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A17991891E1CA24100A505ED /* SharedBufferTest.cpp */; };
                A17EAC55208305A00084B41B /* find.pdf in Copy Resources */ = {isa = PBXBuildFile; fileRef = A17EAC542083056E0084B41B /* find.pdf */; };
                                1A63479F183D72A4005B1707 /* all-content-in-one-iframe.html in Copy Resources */,
                                C25CCA0D1E5141840026CB8A /* AllAhem.svg in Copy Resources */,
                                F4A9202F1FEE34E900F59590 /* apple-data-url.html in Copy Resources */,
+                               A1798B8B224361A4000764BD /* apple-pay-active-session.html in Copy Resources */,
+                               A1798B8922435E29000764BD /* apple-pay-availability-in-iframe.html in Copy Resources */,
+                               A1798B872243449B000764BD /* apple-pay-availability.html in Copy Resources */,
                                F46A095A1ED8A6E600D4AA55 /* apple.gif in Copy Resources */,
                                5C9E59411D3EB5AC00E3C62E /* ApplicationCache.db in Copy Resources */,
                                5C9E59421D3EB5AC00E3C62E /* ApplicationCache.db-shm in Copy Resources */,
                A15502281E05020B00A24C57 /* DuplicateCompletionHandlerCalls.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DuplicateCompletionHandlerCalls.mm; sourceTree = "<group>"; };
                A155022B1E050BC500A24C57 /* duplicate-completion-handler-calls.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "duplicate-completion-handler-calls.html"; sourceTree = "<group>"; };
                A16F66B91C40EA2000BD4D24 /* ContentFiltering.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ContentFiltering.html; sourceTree = "<group>"; };
+               A1798B7E22431D2B000764BD /* libWebCoreTestSupport.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; path = libWebCoreTestSupport.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+               A1798B8122431D65000764BD /* ApplePay.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ApplePay.mm; sourceTree = "<group>"; };
+               A1798B8322433647000764BD /* WebProcessPlugInWithInternals.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebProcessPlugInWithInternals.h; sourceTree = "<group>"; };
+               A1798B8422433647000764BD /* WebProcessPlugInWithInternals.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WebProcessPlugInWithInternals.mm; sourceTree = "<group>"; };
+               A1798B862243446B000764BD /* apple-pay-availability.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "apple-pay-availability.html"; sourceTree = "<group>"; };
+               A1798B8822435D2E000764BD /* apple-pay-availability-in-iframe.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "apple-pay-availability-in-iframe.html"; sourceTree = "<group>"; };
+               A1798B8A2243611A000764BD /* apple-pay-active-session.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "apple-pay-active-session.html"; sourceTree = "<group>"; };
                A17991861E1C994E00A505ED /* SharedBuffer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SharedBuffer.mm; sourceTree = "<group>"; };
                A17991891E1CA24100A505ED /* SharedBufferTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedBufferTest.cpp; sourceTree = "<group>"; };
                A179918A1E1CA24100A505ED /* SharedBufferTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedBufferTest.h; sourceTree = "<group>"; };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               A1798B7D22431D18000764BD /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               A1798B7F22431D2B000764BD /* libWebCoreTestSupport.dylib in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
                BC57597E126E74AF006F0F12 /* Frameworks */ = {
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                                55A817FB218100E00004A39A /* AdditionalSupportedImageTypes.mm */,
                                A1DF74301C41B65800A2F4D0 /* AlwaysRevalidatedURLSchemes.mm */,
                                2DE71AFD1D49C0BD00904094 /* AnimatedResize.mm */,
+                               A1798B8122431D65000764BD /* ApplePay.mm */,
                                63F668201F97C3AA0032EE51 /* ApplicationManifest.mm */,
                                834138C6203261B900F26960 /* AsyncPolicyForNavigationResponse.mm */,
                                3760C4F0211249AF00233ACC /* AttrStyle.mm */,
                                0F4FFAA01ED3D0DE00F7111F /* ImageIO.framework */,
                                CDA3159C1ED5643F009F60D3 /* IOKit.framework */,
                                7C83E0331D0A5F2700FEBCF3 /* libicucore.dylib */,
+                               A1798B7E22431D2B000764BD /* libWebCoreTestSupport.dylib */,
                                4135FB862011FABF00332139 /* libWebCoreTestSupport.dylib */,
                                7C83E0291D0A5CDF00FEBCF3 /* libWTF.a */,
                                578CBD66204FB2C70083B9F2 /* LocalAuthentication.framework */,
                        children = (
                                A13EBB541B8734E000097110 /* Info.plist */,
                                A13EBBA91B87428D00097110 /* WebProcessPlugIn.mm */,
+                               A1798B8322433647000764BD /* WebProcessPlugInWithInternals.h */,
+                               A1798B8422433647000764BD /* WebProcessPlugInWithInternals.mm */,
                        );
                        name = WebProcessPlugIn;
                        path = cocoa/WebProcessPlugIn;
                                55A817FD218101DF0004A39A /* 400x400-green.png */,
                                C25CCA0C1E5140E50026CB8A /* AllAhem.svg */,
                                F4A9202E1FEE34C800F59590 /* apple-data-url.html */,
+                               A1798B8A2243611A000764BD /* apple-pay-active-session.html */,
+                               A1798B8822435D2E000764BD /* apple-pay-availability-in-iframe.html */,
+                               A1798B862243446B000764BD /* apple-pay-availability.html */,
                                F47D30EB1ED28619000482E1 /* apple.gif */,
                                5C9E593E1D3EB1DE00E3C62E /* ApplicationCache.db */,
                                5C9E593F1D3EB1DE00E3C62E /* ApplicationCache.db-shm */,
                        buildConfigurationList = A13EBB4C1B87339E00097110 /* Build configuration list for PBXNativeTarget "WebProcessPlugIn" */;
                        buildPhases = (
                                A13EBB451B87339E00097110 /* Sources */,
+                               A1798B7D22431D18000764BD /* Frameworks */,
                        );
                        buildRules = (
                        );
                                A1DF74321C41B65800A2F4D0 /* AlwaysRevalidatedURLSchemes.mm in Sources */,
                                2DE71AFE1D49C0BD00904094 /* AnimatedResize.mm in Sources */,
                                57152B5E21CC2045000C37CA /* ApduTest.cpp in Sources */,
+                               A1798B8222431D65000764BD /* ApplePay.mm in Sources */,
                                63F668221F97F7F90032EE51 /* ApplicationManifest.mm in Sources */,
                                6354F4D11F7C3AB500D89DF3 /* ApplicationManifestParser.cpp in Sources */,
                                834138C7203261CA00F26960 /* AsyncPolicyForNavigationResponse.mm in Sources */,
                                7C882E091C80C630006BF731 /* UserContentWorldPlugIn.mm in Sources */,
                                7C83E03D1D0A60D600FEBCF3 /* UtilitiesCocoa.mm in Sources */,
                                A13EBBAA1B87428D00097110 /* WebProcessPlugIn.mm in Sources */,
+                               A1798B8522433647000764BD /* WebProcessPlugInWithInternals.mm in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplePay.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/ApplePay.mm
new file mode 100644 (file)
index 0000000..a2b5801
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * 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. 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"
+
+#if ENABLE(APPLE_PAY_REMOTE_UI)
+
+#import "PlatformUtilities.h"
+#import "Test.h"
+#import "TestNavigationDelegate.h"
+#import "TestProtocol.h"
+#import "TestWKWebView.h"
+#import "WKWebViewConfigurationExtras.h"
+#import <WebKit/WKUserContentControllerPrivate.h>
+#import <WebKit/WebKit.h>
+
+static bool isDone;
+
+@interface TestApplePayScriptMessageHandler : NSObject <WKScriptMessageHandler>
+
+- (instancetype)init NS_UNAVAILABLE;
+- (instancetype)initWithExpectation:(BOOL)expectation;
+
+@end
+
+@implementation TestApplePayScriptMessageHandler {
+    BOOL _expectation;
+}
+
+- (instancetype)initWithExpectation:(BOOL)expectation
+{
+    if (!(self = [super init]))
+        return nil;
+
+    _expectation = expectation;
+    return self;
+}
+
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+    EXPECT_EQ(_expectation, [[message.body objectForKey:@"supportsVersion"] boolValue]);
+    EXPECT_EQ(_expectation, [[message.body objectForKey:@"canMakePayments"] boolValue]);
+    EXPECT_EQ(_expectation, [[message.body objectForKey:@"canMakePaymentsWithActiveCard"] boolValue]);
+    EXPECT_EQ(_expectation, [[message.body objectForKey:@"canMakePayment"] boolValue]);
+    isDone = true;
+}
+
+@end
+
+namespace TestWebKitAPI {
+    
+TEST(ApplePay, ApplePayAvailableByDefault)
+{
+    [TestProtocol registerWithScheme:@"https"];
+
+    auto messageHandler = adoptNS([[TestApplePayScriptMessageHandler alloc] initWithExpectation:YES]);
+
+    WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals"];
+    [configuration.userContentController addScriptMessageHandler:messageHandler.get() name:@"testApplePay"];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://bundle-html-file/apple-pay-availability"]]];
+
+    Util::run(&isDone);
+
+    [TestProtocol unregister];
+}
+
+TEST(ApplePay, UserScriptDisablesApplePay)
+{
+    [TestProtocol registerWithScheme:@"https"];
+
+    auto messageHandler = adoptNS([[TestApplePayScriptMessageHandler alloc] initWithExpectation:NO]);
+    auto userScript = adoptNS([[WKUserScript alloc] initWithSource:@"window.wkUserScriptInjected = true" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]);
+
+    WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals"];
+    [configuration.userContentController addUserScript:userScript.get()];
+    [configuration.userContentController addScriptMessageHandler:messageHandler.get() name:@"testApplePay"];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://bundle-html-file/apple-pay-availability"]]];
+
+    Util::run(&isDone);
+
+    EXPECT_EQ(YES, [[webView objectByEvaluatingJavaScript:@"window.wkUserScriptInjected"] boolValue]);
+
+    [TestProtocol unregister];
+}
+
+TEST(ApplePay, UserAgentScriptEvaluationDisablesApplePay)
+{
+    [TestProtocol registerWithScheme:@"https"];
+
+    auto messageHandler = adoptNS([[TestApplePayScriptMessageHandler alloc] initWithExpectation:NO]);
+
+    WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals"];
+    [configuration.userContentController addScriptMessageHandler:messageHandler.get() name:@"testApplePay"];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://bundle-html-file/apple-pay-availability-in-iframe"]]];
+    [webView _test_waitForDidFinishNavigation];
+    [webView evaluateJavaScript:@"window.wkScriptEvaluated = true; loadApplePayFrame();" completionHandler:nil];
+
+    Util::run(&isDone);
+
+    EXPECT_EQ(YES, [[webView objectByEvaluatingJavaScript:@"window.wkScriptEvaluated"] boolValue]);
+
+    [TestProtocol unregister];
+}
+
+TEST(ApplePay, ActiveSessionBlocksUserAgentScripts)
+{
+    [TestProtocol registerWithScheme:@"https"];
+
+    auto userScript = adoptNS([[WKUserScript alloc] initWithSource:@"window.wkUserScriptInjected = true" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]);
+
+    WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals"];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration]);
+    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://bundle-html-file/apple-pay-active-session"]]];
+    [webView _test_waitForDidFinishNavigation];
+
+    [configuration.userContentController _addUserScriptImmediately:userScript.get()];
+    [webView evaluateJavaScript:@"window.wkUserScriptInjected" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
+        EXPECT_NULL(result);
+        EXPECT_NOT_NULL(error);
+        isDone = true;
+    }];
+    Util::run(&isDone);
+
+    [TestProtocol unregister];
+}
+
+} // namespace TestWebKitAPI
+
+#endif // ENABLE(APPLE_PAY_REMOTE_UI)
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-pay-active-session.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-pay-active-session.html
new file mode 100644 (file)
index 0000000..1bd9f6f
--- /dev/null
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<body>
+<script>
+    internals.mockPaymentCoordinator.supportsUnrestrictedApplePay = false;
+    internals.setHasStartedApplePaySession();
+</script>
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability-in-iframe.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability-in-iframe.html
new file mode 100644 (file)
index 0000000..a3fae1a
--- /dev/null
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<body>
+<script>
+    loadApplePayFrame = () => {
+        const iframe = document.createElement('iframe');
+        iframe.src = 'https://bundle-html-file/apple-pay-availability';
+        document.body.appendChild(iframe);
+    };
+</script>
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/apple-pay-availability.html
new file mode 100644 (file)
index 0000000..f302c6a
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<body>
+<script>
+    const applePayRequestBase = () => {
+        return {
+            merchantCapabilities: ['supports3DS'],
+            supportedNetworks: ['visa'],
+            countryCode: 'US',
+        };
+    };
+
+    const applePayPaymentRequest = () => {
+        const request = applePayRequestBase();
+        request.total = { label: 'total', amount: '0.00' };
+        request.currencyCode = 'USD';
+        return request;
+    };
+
+    const applePayMethod = () => {
+        const request = applePayRequestBase();
+        request.version = 1;
+        request.merchantIdentifier = '';
+        return {
+            supportedMethods: 'https://apple.com/apple-pay',
+            data: request,
+        };
+    };
+
+    window.addEventListener('load', async () => {
+        internals.mockPaymentCoordinator.supportsUnrestrictedApplePay = false;
+
+        const supportsVersion = ApplePaySession.supportsVersion(1);
+        const canMakePayments = ApplePaySession.canMakePayments();
+        const canMakePaymentsWithActiveCard = await ApplePaySession.canMakePaymentsWithActiveCard('');
+
+        const paymentRequest = new PaymentRequest([applePayMethod()], {
+            total: {
+                label: 'total',
+                amount: { currency: 'USD', value: '0.00' },
+            },
+        });
+
+        const canMakePayment = await paymentRequest.canMakePayment();
+
+        window.webkit.messageHandlers.testApplePay.postMessage({
+            supportsVersion,
+            canMakePayments,
+            canMakePaymentsWithActiveCard,
+            canMakePayment,
+        });
+    });
+</script>
index 1200ea2..d949c6f 100644 (file)
@@ -86,7 +86,12 @@ static NSURL *createRedirectURL(NSString *query)
         return;
     }
 
-    NSData *data = [@"PASS" dataUsingEncoding:NSASCIIStringEncoding];
+    NSData *data;
+    if ([requestURL.host isEqualToString:@"bundle-html-file"])
+        data = [NSData dataWithContentsOfURL:[NSBundle.mainBundle URLForResource:requestURL.lastPathComponent.stringByDeletingPathExtension withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+    else
+        data = [@"PASS" dataUsingEncoding:NSASCIIStringEncoding];
+
     RetainPtr<NSURLResponse> response = adoptNS([[NSURLResponse alloc] initWithURL:requestURL MIMEType:@"text/html" expectedContentLength:data.length textEncodingName:nil]);
 
     if ([requestURL.host isEqualToString:@"redirect"]) {
diff --git a/Tools/TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.h b/Tools/TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.h
new file mode 100644 (file)
index 0000000..b862ec2
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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. 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 <WebKit/WKWebProcessPlugIn.h>
+
+@interface WebProcessPlugInWithInternals : NSObject <WKWebProcessPlugIn>
+@end
diff --git a/Tools/TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.mm b/Tools/TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugInWithInternals.mm
new file mode 100644 (file)
index 0000000..2716be2
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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. 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 "WebProcessPlugInWithInternals.h"
+
+#import "WebCoreTestSupport.h"
+#import <WebKit/WKWebProcessPlugInBrowserContextController.h>
+#import <WebKit/WKWebProcessPlugInFrame.h>
+#import <WebKit/WKWebProcessPlugInLoadDelegate.h>
+
+@interface WebProcessPlugInWithInternals () <WKWebProcessPlugInLoadDelegate>
+
+@end
+
+@implementation WebProcessPlugInWithInternals
+
+- (void)webProcessPlugIn:(WKWebProcessPlugInController *)plugInController didCreateBrowserContextController:(WKWebProcessPlugInBrowserContextController *)browserContextController
+{
+    browserContextController.loadDelegate = self;
+}
+
+- (void)webProcessPlugInBrowserContextController:(WKWebProcessPlugInBrowserContextController *)controller didClearWindowObjectForFrame:(WKWebProcessPlugInFrame *)frame inScriptWorld:(WKWebProcessPlugInScriptWorld *)scriptWorld
+{
+    WebCoreTestSupport::injectInternalsObject([frame jsContextForWorld:scriptWorld].JSGlobalContextRef);
+}
+
+@end