Diff
Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp (295678 => 295679)
--- trunk/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp 2022-06-21 00:29:18 UTC (rev 295678)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp 2022-06-21 03:54:18 UTC (rev 295679)
@@ -60,6 +60,7 @@
#include "WebsiteDataStore.h"
#include "WebsiteDataType.h"
#include <_javascript_Core/RemoteInspector.h>
+#include <WebCore/ContentSecurityPolicy.h>
#include <WebCore/ResourceLoaderIdentifier.h>
#include <glib/gi18n-lib.h>
#include <libintl.h>
@@ -1943,6 +1944,17 @@
pageConfiguration->setUserContentController(userContentManager ? webkitUserContentManagerGetUserContentControllerProxy(userContentManager) : nullptr);
pageConfiguration->setControlledByAutomation(webkit_web_view_is_controlled_by_automation(webView));
+ WebKitWebExtensionMode webExtensionMode = webkit_web_view_get_web_extension_mode(webView);
+ const char* defaultContentSecurityPolicy = webkit_web_view_get_default_content_security_policy(webView);
+
+ if (webExtensionMode == WEBKIT_WEB_EXTENSION_MODE_MANIFESTV3)
+ pageConfiguration->setContentSecurityPolicyModeForExtension(WebCore::ContentSecurityPolicyModeForExtension::ManifestV3);
+ else if (webExtensionMode == WEBKIT_WEB_EXTENSION_MODE_MANIFESTV2)
+ pageConfiguration->setContentSecurityPolicyModeForExtension(WebCore::ContentSecurityPolicyModeForExtension::ManifestV2);
+
+ if (defaultContentSecurityPolicy)
+ pageConfiguration->setOverrideContentSecurityPolicy(String::fromUTF8(defaultContentSecurityPolicy));
+
WebKitWebsiteDataManager* manager = webkitWebViewGetWebsiteDataManager(webView);
if (!manager)
manager = context->priv->websiteDataManager.get();
Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp (295678 => 295679)
--- trunk/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp 2022-06-21 00:29:18 UTC (rev 295678)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp 2022-06-21 03:54:18 UTC (rev 295679)
@@ -211,6 +211,9 @@
PROP_MICROPHONE_CAPTURE_STATE,
PROP_DISPLAY_CAPTURE_STATE,
+ PROP_WEB_EXTENSION_MODE,
+ PROP_DEFAULT_CONTENT_SECURITY_POLICY,
+
N_PROPERTIES,
};
@@ -317,6 +320,9 @@
GRefPtr<WebKitWebsiteDataManager> websiteDataManager;
GRefPtr<WebKitWebsitePolicies> websitePolicies;
+ CString defaultContentSecurityPolicy;
+ WebKitWebExtensionMode webExtensionMode;
+
double textScaleFactor;
bool isWebProcessResponsive;
@@ -901,6 +907,12 @@
case PROP_DISPLAY_CAPTURE_STATE:
webkit_web_view_set_display_capture_state(webView, static_cast<WebKitMediaCaptureState>(g_value_get_enum(value)));
break;
+ case PROP_WEB_EXTENSION_MODE:
+ webView->priv->webExtensionMode = static_cast<WebKitWebExtensionMode>(g_value_get_enum(value));
+ break;
+ case PROP_DEFAULT_CONTENT_SECURITY_POLICY:
+ webView->priv->defaultContentSecurityPolicy = CString(g_value_get_string(value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
}
@@ -981,6 +993,12 @@
case PROP_DISPLAY_CAPTURE_STATE:
g_value_set_enum(value, webkit_web_view_get_display_capture_state(webView));
break;
+ case PROP_WEB_EXTENSION_MODE:
+ g_value_set_enum(value, webkit_web_view_get_web_extension_mode(webView));
+ break;
+ case PROP_DEFAULT_CONTENT_SECURITY_POLICY:
+ g_value_set_string(value, webkit_web_view_get_default_content_security_policy(webView));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
}
@@ -1450,6 +1468,50 @@
WEBKIT_MEDIA_CAPTURE_STATE_NONE,
WEBKIT_PARAM_READWRITE);
+ /**
+ * WebKitWebView:web-extension-mode:
+ *
+ * This configures @web_view to treat the content as a WebExtension.
+ *
+ * Note that this refers to the web standard [WebExtensions](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions)
+ * and not WebKitWebExtensions.
+ *
+ * In practice this limits the Content-Security-Policies that are allowed to be set. Some details can be found in
+ * [Chrome's documentation](https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#content-security-policy).
+ *
+ * Since: 2.38
+ */
+ sObjProperties[PROP_WEB_EXTENSION_MODE] = g_param_spec_enum(
+ "web-extension-mode",
+ "WebExtension Mode",
+ _("Enables WebExtension mode"),
+ WEBKIT_TYPE_WEB_EXTENSION_MODE,
+ WEBKIT_WEB_EXTENSION_MODE_NONE,
+ static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * WebKitWebView:default-content-security-policy:
+ *
+ * The default Content-Security-Policy used by the webview as if it were set
+ * by an HTTP header.
+ *
+ * This applies to all content loaded including through navigation or via the various
+ * webkit_web_view_load_\* APIs. However do note that many WebKit APIs bypass
+ * Content-Security-Policy in general such as #WebKitUserContentManager and
+ * webkit_web_view_run_javascript().
+ *
+ * Policies are additive so if a website sets its own policy it still applies
+ * on top of the policy set here.
+ *
+ * Since: 2.38
+ */
+ sObjProperties[PROP_DEFAULT_CONTENT_SECURITY_POLICY] = g_param_spec_string(
+ "default-content-security-policy",
+ "Default Content-Security-Policy",
+ _("The default Content-Security-Policy"),
+ nullptr,
+ static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
g_object_class_install_properties(gObjectClass, N_PROPERTIES, sObjProperties);
/**
@@ -5178,3 +5240,41 @@
{
WebKit::WebsiteDataStore::setCachedProcessSuspensionDelayForTesting(Seconds(seconds));
}
+
+/**
+ * webkit_web_view_get_web_extension_mode:
+ * @web_view: a #WebKitWebView
+ *
+ * Get the view's #WebKitWebExtensionMode.
+ *
+ * Returns: the #WebKitWebExtensionMode
+ *
+ * Since: 2.38
+ */
+WebKitWebExtensionMode webkit_web_view_get_web_extension_mode(WebKitWebView* webView)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), WEBKIT_WEB_EXTENSION_MODE_NONE);
+
+ return webView->priv->webExtensionMode;
+}
+
+/**
+ * webkit_web_view_get_default_content_security_policy:
+ * @web_view: a #WebKitWebView
+ *
+ * Gets the configured default Content-Security-Policy.
+ *
+ * Returns: (nullable): The default policy or %NULL
+ *
+ * Since: 2.38
+ */
+const gchar*
+webkit_web_view_get_default_content_security_policy(WebKitWebView* webView)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
+
+ if (webView->priv->defaultContentSecurityPolicy.isNull())
+ return nullptr;
+
+ return webView->priv->defaultContentSecurityPolicy.data();
+}
Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebView.h (295678 => 295679)
--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebView.h 2022-06-21 00:29:18 UTC (rev 295678)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebView.h 2022-06-21 03:54:18 UTC (rev 295679)
@@ -221,6 +221,23 @@
WEBKIT_MEDIA_CAPTURE_STATE_MUTED,
} WebKitMediaCaptureState;
+/**
+ * WebKitWebExtensionMode:
+ * @WEBKIT_WEB_EXTENSION_MODE_NONE: Not for an extension.
+ * @WEBKIT_WEB_EXTENSION_MODE_MANIFESTV2: For a ManifestV2 extension.
+ * @WEBKIT_WEB_EXTENSION_MODE_MANIFESTV3: For a ManifestV3 extension.
+ *
+ * Enum values used for setting if a #WebKitWebView is intended for
+ * WebExtensions.
+ *
+ * Since: 2.38
+ */
+typedef enum {
+ WEBKIT_WEB_EXTENSION_MODE_NONE,
+ WEBKIT_WEB_EXTENSION_MODE_MANIFESTV2,
+ WEBKIT_WEB_EXTENSION_MODE_MANIFESTV3,
+} WebKitWebExtensionMode;
+
struct _WebKitWebView {
WebKitWebViewBase parent;
@@ -648,6 +665,12 @@
webkit_web_view_set_display_capture_state (WebKitWebView *web_view,
WebKitMediaCaptureState state);
+WEBKIT_API WebKitWebExtensionMode
+webkit_web_view_get_web_extension_mode (WebKitWebView *web_view);
+
+WEBKIT_API const gchar*
+webkit_web_view_get_default_content_security_policy (WebKitWebView *web_view);
+
G_END_DECLS
#endif
Modified: trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebView.h (295678 => 295679)
--- trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebView.h 2022-06-21 00:29:18 UTC (rev 295678)
+++ trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebView.h 2022-06-21 03:54:18 UTC (rev 295679)
@@ -202,6 +202,23 @@
WEBKIT_MEDIA_CAPTURE_STATE_MUTED,
} WebKitMediaCaptureState;
+/**
+ * WebKitWebExtensionMode:
+ * @WEBKIT_WEB_EXTENSION_MODE_NONE: Not for an extension.
+ * @WEBKIT_WEB_EXTENSION_MODE_MANIFESTV2: For a ManifestV2 extension.
+ * @WEBKIT_WEB_EXTENSION_MODE_MANIFESTV3: For a ManifestV3 extension.
+ *
+ * Enum values used for setting if a #WebKitWebView is intended for
+ * WebExtensions.
+ *
+ * Since: 2.38
+ */
+typedef enum {
+ WEBKIT_WEB_EXTENSION_MODE_NONE,
+ WEBKIT_WEB_EXTENSION_MODE_MANIFESTV2,
+ WEBKIT_WEB_EXTENSION_MODE_MANIFESTV3,
+} WebKitWebExtensionMode;
+
struct _WebKitWebView {
GObject parent;
@@ -625,6 +642,12 @@
webkit_web_view_set_display_capture_state (WebKitWebView *web_view,
WebKitMediaCaptureState state);
+WEBKIT_API WebKitWebExtensionMode
+webkit_web_view_get_web_extension_mode (WebKitWebView *web_view);
+
+WEBKIT_API const gchar*
+webkit_web_view_get_default_content_security_policy (WebKitWebView *web_view);
+
G_END_DECLS
#endif
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebView.cpp (295678 => 295679)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebView.cpp 2022-06-21 00:29:18 UTC (rev 295678)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebView.cpp 2022-06-21 03:54:18 UTC (rev 295679)
@@ -1857,6 +1857,71 @@
g_assert_cmpint(waitForFooChanged(), ==, 200);
}
+static void testWebViewDefaultContentSecurityPolicy(WebViewTest* test, gconstpointer)
+{
+ GUniqueOutPtr<GError> error;
+ WebKitJavascriptResult* _javascript_Result;
+
+ // Sanity check that eval works normally.
+ _javascript_Result = test->runJavaScriptAndWaitUntilFinished("eval('\"allowed\"')", &error.outPtr());
+ g_assert_nonnull(_javascript_Result);
+ g_assert_no_error(error.get());
+ GUniquePtr<char> evalValue(WebViewTest::_javascript_ResultToCString(_javascript_Result));
+ g_assert_cmpstr(evalValue.get(), ==, "allowed");
+ webkit_javascript_result_unref(_javascript_Result);
+
+ // Create a new web view with a policy that blocks eval().
+ auto webView = Test::adoptView(g_object_new(WEBKIT_TYPE_WEB_VIEW,
+ "default-content-security-policy", "script-src 'self'", nullptr));
+
+ // Ensure _javascript_ still functions.
+ _javascript_Result = test->runJavaScriptAndWaitUntilFinished("'allowed'", &error.outPtr(), webView.get());
+ g_assert_nonnull(_javascript_Result);
+ g_assert_no_error(error.get());
+ GUniquePtr<char> value(WebViewTest::_javascript_ResultToCString(_javascript_Result));
+ g_assert_cmpstr(value.get(), ==, "allowed");
+ webkit_javascript_result_unref(_javascript_Result);
+
+ // Then ensure eval is blocked.
+ _javascript_Result = test->runJavaScriptAndWaitUntilFinished("eval('\"allowed\"')", &error.outPtr(), webView.get());
+ g_assert_null(_javascript_Result);
+ g_assert_error(error.get(), WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED);
+}
+
+static void testWebViewWebExtensionMode(WebViewTest* test, gconstpointer)
+{
+ GUniqueOutPtr<GError> error;
+ WebKitJavascriptResult* _javascript_Result;
+ static const char* html =
+ "<html>"
+ " <head>"
+ " <title>unset</title>"
+ " <meta http-equiv=\"Content-Security-Policy\" content=\"script-src 'unsafe-inline';\">"
+ " <script>document.title = 'set';</script>"
+ " </head>"
+ "</html>";
+
+ // Sanity check that this HTML works as expected.
+ test->loadHtml(html, nullptr);
+ test->waitUntilLoadFinished();
+ _javascript_Result = test->runJavaScriptAndWaitUntilFinished("document.title == 'set';", &error.outPtr());
+ g_assert_nonnull(_javascript_Result);
+ g_assert_no_error(error.get());
+ g_assert_true(WebViewTest::_javascript_ResultToBoolean(_javascript_Result));
+ webkit_javascript_result_unref(_javascript_Result);
+
+ // Create a new web view with an extension mode that blocks the unsafe-inline keyword.
+ auto webView = Test::adoptView(g_object_new(WEBKIT_TYPE_WEB_VIEW,
+ "web-extension-mode", WEBKIT_WEB_EXTENSION_MODE_MANIFESTV3,
+ nullptr));
+ test->loadHtml(html, nullptr, webView.get());
+ test->waitUntilLoadFinished(webView.get());
+ _javascript_Result = test->runJavaScriptAndWaitUntilFinished("document.title == 'unset';", &error.outPtr(), webView.get());
+ g_assert_nonnull(_javascript_Result);
+ g_assert_no_error(error.get());
+ g_assert_true(WebViewTest::_javascript_ResultToBoolean(_javascript_Result));
+}
+
#if USE(SOUP2)
static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
#else
@@ -1930,6 +1995,8 @@
WebViewTerminateWebProcessTest::add("WebKitWebView", "terminate-web-process", testWebViewTerminateWebProcess);
WebViewTerminateWebProcessTest::add("WebKitWebView", "terminate-unresponsive-web-process", testWebViewTerminateUnresponsiveWebProcess);
WebViewTest::add("WebKitWebView", "cors-allowlist", testWebViewCORSAllowlist);
+ WebViewTest::add("WebKitWebView", "default-content-security-policy", testWebViewDefaultContentSecurityPolicy);
+ WebViewTest::add("WebKitWebView", "web-extension-mode", testWebViewWebExtensionMode);
}
void afterAll()
Modified: trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.cpp (295678 => 295679)
--- trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.cpp 2022-06-21 00:29:18 UTC (rev 295678)
+++ trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.cpp 2022-06-21 03:54:18 UTC (rev 295679)
@@ -85,15 +85,19 @@
g_assert_cmpstr(webkit_web_view_get_uri(m_webView), ==, m_activeURI.data());
}
-void WebViewTest::loadHtml(const char* html, const char* baseURI)
+void WebViewTest::loadHtml(const char* html, const char* baseURI, WebKitWebView* webView)
{
if (!baseURI)
m_activeURI = "about:blank";
else
m_activeURI = baseURI;
- webkit_web_view_load_html(m_webView, html, baseURI);
- g_assert_true(webkit_web_view_is_loading(m_webView));
- g_assert_cmpstr(webkit_web_view_get_uri(m_webView), ==, m_activeURI.data());
+
+ if (!webView)
+ webView = m_webView;
+
+ webkit_web_view_load_html(webView, html, baseURI);
+ g_assert_true(webkit_web_view_is_loading(webView));
+ g_assert_cmpstr(webkit_web_view_get_uri(webView), ==, m_activeURI.data());
}
void WebViewTest::loadPlainText(const char* plainText)
Modified: trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.h (295678 => 295679)
--- trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.h 2022-06-21 00:29:18 UTC (rev 295678)
+++ trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.h 2022-06-21 03:54:18 UTC (rev 295679)
@@ -37,7 +37,7 @@
void platformDestroy();
virtual void loadURI(const char* uri);
- virtual void loadHtml(const char* html, const char* baseURI);
+ virtual void loadHtml(const char* html, const char* baseURI, WebKitWebView* = nullptr);
virtual void loadPlainText(const char* plainText);
virtual void loadRequest(WebKitURIRequest*);
virtual void loadBytes(GBytes*, const char* mimeType, const char* encoding, const char* baseURI);