Modified: releases/WebKitGTK/webkit-2.24/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp (243972 => 243973)
--- releases/WebKitGTK/webkit-2.24/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp 2019-04-08 10:13:59 UTC (rev 243972)
+++ releases/WebKitGTK/webkit-2.24/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp 2019-04-08 10:14:04 UTC (rev 243973)
@@ -246,6 +246,7 @@
CString title;
CString customTextEncoding;
CString activeURI;
+ bool isActiveURIChangeBlocked;
bool isLoading;
bool isEphemeral;
bool isControlledByAutomation;
@@ -355,10 +356,14 @@
void willChangeActiveURL() override
{
+ if (m_webView->priv->isActiveURIChangeBlocked)
+ return;
g_object_freeze_notify(G_OBJECT(m_webView));
}
void didChangeActiveURL() override
{
+ if (m_webView->priv->isActiveURIChangeBlocked)
+ return;
m_webView->priv->activeURI = getPage(m_webView).pageLoadState().activeURL().utf8();
g_object_notify(G_OBJECT(m_webView), "uri");
g_object_thaw_notify(G_OBJECT(m_webView));
@@ -2077,6 +2082,15 @@
void webkitWebViewWillStartLoad(WebKitWebView* webView)
{
+ // Ignore the active URI changes happening before WEBKIT_LOAD_STARTED. If they are not user-initiated,
+ // they could be a malicious attempt to trick users by loading an invalid URI on a trusted host, with the load
+ // intended to stall, or perhaps be repeated. If we trust the URI here and display it to the user, then the user's
+ // only indication that something is wrong would be a page loading indicator. If the load request is not
+ // user-initiated, we must not trust it until WEBKIT_LOAD_COMMITTED. If the load is triggered by API
+ // request, then the active URI is already the pending API request URL, so the blocking is harmless and the
+ // client application will still see the URI update immediately. Otherwise, the URI update will be delayed a bit.
+ webView->priv->isActiveURIChangeBlocked = true;
+
// This is called before NavigationClient::didStartProvisionalNavigation(), the page load state hasn't been committed yet.
auto& pageLoadState = getPage(webView).pageLoadState();
if (pageLoadState.isFinished())
@@ -2099,15 +2113,24 @@
webkitWebViewCancelAuthenticationRequest(webView);
priv->loadingResourcesMap.clear();
priv->mainResource = nullptr;
+ webView->priv->isActiveURIChangeBlocked = false;
break;
+ case WEBKIT_LOAD_COMMITTED: {
+ auto activeURL = getPage(webView).pageLoadState().activeURL().utf8();
+ // Active URL is trusted now. If it's different to our active URI, due to the
+ // update block before WEBKIT_LOAD_STARTED, we update it here to be in sync
+ // again with the page load state.
+ if (activeURL != priv->activeURI) {
+ priv->activeURI = activeURL;
+ g_object_notify(G_OBJECT(webView), "uri");
+ }
#if PLATFORM(GTK)
- case WEBKIT_LOAD_COMMITTED: {
WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get());
GUniquePtr<char> faviconURI(webkit_favicon_database_get_favicon_uri(database, priv->activeURI.data()));
webkitWebViewUpdateFaviconURI(webView, faviconURI.get());
+#endif
break;
}
-#endif
case WEBKIT_LOAD_FINISHED:
webkitWebViewCancelAuthenticationRequest(webView);
break;
Modified: releases/WebKitGTK/webkit-2.24/Tools/TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp (243972 => 243973)
--- releases/WebKitGTK/webkit-2.24/Tools/TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp 2019-04-08 10:13:59 UTC (rev 243972)
+++ releases/WebKitGTK/webkit-2.24/Tools/TestWebKitAPI/Tests/WebKitGLib/TestLoaderClient.cpp 2019-04-08 10:14:04 UTC (rev 243973)
@@ -368,6 +368,55 @@
test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, "/normal-change-request");
test->checkURIAtState(ViewURITrackingTest::State::Commited, "/request-changed-on-redirect");
test->checkURIAtState(ViewURITrackingTest::State::Finished, "/request-changed-on-redirect");
+
+ // Non-API request loads.
+ test->loadURI(kServer->getURIForPath("/redirect-js/normal").data());
+ test->waitUntilLoadFinished();
+ test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/normal");
+ test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, nullptr);
+ test->checkURIAtState(ViewURITrackingTest::State::Commited, "/redirect-js/normal");
+ test->checkURIAtState(ViewURITrackingTest::State::Finished, "/redirect-js/normal");
+ test->waitUntilLoadFinished();
+ test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/normal");
+ test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, nullptr);
+ test->checkURIAtState(ViewURITrackingTest::State::Commited, "/normal");
+ test->checkURIAtState(ViewURITrackingTest::State::Finished, "/normal");
+
+ test->loadURI(kServer->getURIForPath("/redirect-js/redirect").data());
+ test->waitUntilLoadFinished();
+ test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/redirect");
+ test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, nullptr);
+ test->checkURIAtState(ViewURITrackingTest::State::Commited, "/redirect-js/redirect");
+ test->checkURIAtState(ViewURITrackingTest::State::Finished, "/redirect-js/redirect");
+ test->waitUntilLoadFinished();
+ test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/redirect");
+ test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, "/normal");
+ test->checkURIAtState(ViewURITrackingTest::State::Commited, "/normal");
+ test->checkURIAtState(ViewURITrackingTest::State::Finished, "/normal");
+
+ test->loadURI(kServer->getURIForPath("/redirect-js/normal-change-request").data());
+ test->waitUntilLoadFinished();
+ test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/normal-change-request");
+ test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, nullptr);
+ test->checkURIAtState(ViewURITrackingTest::State::Commited, "/redirect-js/normal-change-request");
+ test->checkURIAtState(ViewURITrackingTest::State::Finished, "/redirect-js/normal-change-request");
+ test->waitUntilLoadFinished();
+ test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/normal-change-request");
+ test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, nullptr);
+ test->checkURIAtState(ViewURITrackingTest::State::Commited, "/request-changed");
+ test->checkURIAtState(ViewURITrackingTest::State::Finished, "/request-changed");
+
+ test->loadURI(kServer->getURIForPath("/redirect-js/redirect-to-change-request").data());
+ test->waitUntilLoadFinished();
+ test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/redirect-to-change-request");
+ test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, nullptr);
+ test->checkURIAtState(ViewURITrackingTest::State::Commited, "/redirect-js/redirect-to-change-request");
+ test->checkURIAtState(ViewURITrackingTest::State::Finished, "/redirect-js/redirect-to-change-request");
+ test->waitUntilLoadFinished();
+ test->checkURIAtState(ViewURITrackingTest::State::Provisional, "/redirect-js/redirect-to-change-request");
+ test->checkURIAtState(ViewURITrackingTest::State::ProvisionalAfterRedirect, "/normal-change-request");
+ test->checkURIAtState(ViewURITrackingTest::State::Commited, "/request-changed-on-redirect");
+ test->checkURIAtState(ViewURITrackingTest::State::Finished, "/request-changed-on-redirect");
}
class ViewIsLoadingTest: public LoadTrackingTest {
@@ -618,16 +667,6 @@
"Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!"
"Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!</body></html>";
- static const char* unfinishedSubresourceLoadResponseString = "<html><body>"
- "<img src=""
- "<script>"
- " function run() {"
- " location = '/normal';"
- " }"
- " setInterval(run(), 50);"
- "</script>"
- "</body></html>";
-
if (message->method != SOUP_METHOD_GET) {
soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
return;
@@ -645,6 +684,10 @@
} else if (g_str_equal(path, "/redirect-to-change-request")) {
soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY);
soup_message_headers_append(message->response_headers, "Location", "/normal-change-request");
+ } else if (g_str_has_prefix(path, "/redirect-js/")) {
+ static const char* redirectJSFormat = "<html><body><script>location = '%s';</script></body></html>";
+ char* redirectJS = g_strdup_printf(redirectJSFormat, g_strrstr(path, "/"));
+ soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, redirectJS, strlen(redirectJS));
} else if (g_str_equal(path, "/cancelled")) {
soup_message_headers_set_encoding(message->response_headers, SOUP_ENCODING_CHUNKED);
soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, responseString, strlen(responseString));
@@ -664,6 +707,15 @@
soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY);
soup_message_headers_append(message->response_headers, "Location", "data:text/plain;charset=utf-8,data-uri");
} else if (g_str_equal(path, "/unfinished-subresource-load")) {
+ static const char* unfinishedSubresourceLoadResponseString = "<html><body>"
+ "<img src=""
+ "<script>"
+ " function run() {"
+ " location = '/normal';"
+ " }"
+ " setInterval(run(), 50);"
+ "</script>"
+ "</body></html>";
soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, unfinishedSubresourceLoadResponseString, strlen(unfinishedSubresourceLoadResponseString));
} else if (g_str_equal(path, "/stall")) {
// This request is never unpaused and stalls forever.
Modified: releases/WebKitGTK/webkit-2.24/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp (243972 => 243973)
--- releases/WebKitGTK/webkit-2.24/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp 2019-04-08 10:13:59 UTC (rev 243972)
+++ releases/WebKitGTK/webkit-2.24/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp 2019-04-08 10:14:04 UTC (rev 243973)
@@ -205,7 +205,7 @@
SoupMessageHeaders* headers = webkit_uri_request_get_http_headers(request);
g_assert_nonnull(headers);
soup_message_headers_append(headers, "DNT", "1");
- } else if (g_str_has_suffix(requestURI, "/normal-change-request")) {
+ } else if (g_str_has_suffix(requestURI, "/normal-change-request") && !g_strrstr(requestURI, "/redirect-js/")) {
GUniquePtr<char> prefix(g_strndup(requestURI, strlen(requestURI) - strlen("/normal-change-request")));
GUniquePtr<char> newURI(g_strdup_printf("%s/request-changed%s", prefix.get(), redirectResponse ? "-on-redirect" : ""));
webkit_uri_request_set_uri(request, newURI.get());