mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Fix crash when creating JS popup with no URL (issue #2330)
This commit is contained in:
@@ -68,7 +68,6 @@
|
|||||||
#include "content/public/browser/render_view_host.h"
|
#include "content/public/browser/render_view_host.h"
|
||||||
#include "content/public/browser/render_widget_host.h"
|
#include "content/public/browser/render_widget_host.h"
|
||||||
#include "content/public/browser/resource_request_info.h"
|
#include "content/public/browser/resource_request_info.h"
|
||||||
#include "content/public/common/browser_side_navigation_policy.h"
|
|
||||||
#include "content/public/common/favicon_url.h"
|
#include "content/public/common/favicon_url.h"
|
||||||
#include "extensions/browser/process_manager.h"
|
#include "extensions/browser/process_manager.h"
|
||||||
#include "net/base/net_errors.h"
|
#include "net/base/net_errors.h"
|
||||||
@@ -2729,14 +2728,10 @@ void CefBrowserHostImpl::DidFinishNavigation(
|
|||||||
content::NavigationHandle* navigation_handle) {
|
content::NavigationHandle* navigation_handle) {
|
||||||
const net::Error error_code = navigation_handle->GetNetErrorCode();
|
const net::Error error_code = navigation_handle->GetNetErrorCode();
|
||||||
|
|
||||||
// With PlzNavigate the RenderFrameHost will only be nullptr if the
|
// Skip calls where the navigation has not yet committed and there is no
|
||||||
// provisional load fails, in which case |error_code| will be ERR_ABORTED.
|
// error code. For example, when creating a browser without loading a URL.
|
||||||
// Without PlzNavigate the RenderFrameHost may be nullptr and |error_code|
|
if (!navigation_handle->HasCommitted() && error_code == net::OK)
|
||||||
// may be OK when a pending navigation is canceled (e.g. by calling LoadURL
|
return;
|
||||||
// from OnCertificateError).
|
|
||||||
DCHECK(navigation_handle->GetRenderFrameHost() ||
|
|
||||||
error_code == net::ERR_ABORTED ||
|
|
||||||
!content::IsBrowserSideNavigationEnabled());
|
|
||||||
|
|
||||||
const int64 frame_id =
|
const int64 frame_id =
|
||||||
navigation_handle->GetRenderFrameHost()
|
navigation_handle->GetRenderFrameHost()
|
||||||
@@ -2752,7 +2747,9 @@ void CefBrowserHostImpl::DidFinishNavigation(
|
|||||||
base::string16(), url);
|
base::string16(), url);
|
||||||
|
|
||||||
if (error_code == net::OK) {
|
if (error_code == net::OK) {
|
||||||
// The navigation has been committed.
|
// The navigation has been committed and there is no error.
|
||||||
|
DCHECK(navigation_handle->HasCommitted());
|
||||||
|
|
||||||
// Don't call OnLoadStart for same page navigations (fragments,
|
// Don't call OnLoadStart for same page navigations (fragments,
|
||||||
// history state).
|
// history state).
|
||||||
if (!navigation_handle->IsSameDocument())
|
if (!navigation_handle->IsSameDocument())
|
||||||
@@ -2761,21 +2758,21 @@ void CefBrowserHostImpl::DidFinishNavigation(
|
|||||||
if (is_main_frame)
|
if (is_main_frame)
|
||||||
OnAddressChange(frame, url);
|
OnAddressChange(frame, url);
|
||||||
} else {
|
} else {
|
||||||
// The navigation failed before commit. Originates from
|
// The navigation failed with an error. This may happen before commit
|
||||||
|
// (e.g. network error) or after commit (e.g. response filter error).
|
||||||
|
// If the error happened before commit then this call will originate from
|
||||||
// RenderFrameHostImpl::OnDidFailProvisionalLoadWithError.
|
// RenderFrameHostImpl::OnDidFailProvisionalLoadWithError.
|
||||||
// OnLoadStart/OnLoadEnd will not be called.
|
// OnLoadStart/OnLoadEnd will not be called.
|
||||||
OnLoadError(frame, navigation_handle->GetURL(), error_code);
|
OnLoadError(frame, navigation_handle->GetURL(), error_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!web_contents())
|
if (web_contents()) {
|
||||||
return;
|
CefBrowserContext* context =
|
||||||
|
static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext());
|
||||||
CefBrowserContext* context =
|
if (context) {
|
||||||
static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext());
|
context->AddVisitedURLs(navigation_handle->GetRedirectChain());
|
||||||
if (!context)
|
}
|
||||||
return;
|
}
|
||||||
|
|
||||||
context->AddVisitedURLs(navigation_handle->GetRedirectChain());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserHostImpl::DocumentAvailableInMainFrame() {
|
void CefBrowserHostImpl::DocumentAvailableInMainFrame() {
|
||||||
|
@@ -2387,7 +2387,6 @@ const char kPopupJSOpenMainUrl[] = "http://www.tests-pjso.com/main.html";
|
|||||||
const char kPopupJSOpenPopupUrl[] = "http://www.tests-pjso.com/popup.html";
|
const char kPopupJSOpenPopupUrl[] = "http://www.tests-pjso.com/popup.html";
|
||||||
|
|
||||||
// Test a popup where the URL is a JavaScript URI that opens another popup.
|
// Test a popup where the URL is a JavaScript URI that opens another popup.
|
||||||
// See comments on CefBrowserInfoManager::FilterPendingPopupURL.
|
|
||||||
class PopupJSWindowOpenTestHandler : public TestHandler {
|
class PopupJSWindowOpenTestHandler : public TestHandler {
|
||||||
public:
|
public:
|
||||||
PopupJSWindowOpenTestHandler()
|
PopupJSWindowOpenTestHandler()
|
||||||
@@ -2533,6 +2532,109 @@ TEST(NavigationTest, PopupJSWindowOpen) {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
const char kPopupJSEmptyMainUrl[] = "http://www.tests-pjse.com/main.html";
|
||||||
|
|
||||||
|
// Test creation of a popup where the URL is empty.
|
||||||
|
class PopupJSWindowEmptyTestHandler : public TestHandler {
|
||||||
|
public:
|
||||||
|
PopupJSWindowEmptyTestHandler() {}
|
||||||
|
|
||||||
|
void RunTest() override {
|
||||||
|
AddResource(kPopupJSEmptyMainUrl, "<html>Main</html>", "text/html");
|
||||||
|
|
||||||
|
// Create the browser.
|
||||||
|
CreateBrowser(kPopupJSEmptyMainUrl);
|
||||||
|
|
||||||
|
// Time out the test after a reasonable period of time.
|
||||||
|
SetTestTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
const CefString& target_url,
|
||||||
|
const CefString& target_frame_name,
|
||||||
|
cef_window_open_disposition_t target_disposition,
|
||||||
|
bool user_gesture,
|
||||||
|
const CefPopupFeatures& popupFeatures,
|
||||||
|
CefWindowInfo& windowInfo,
|
||||||
|
CefRefPtr<CefClient>& client,
|
||||||
|
CefBrowserSettings& settings,
|
||||||
|
bool* no_javascript_access) override {
|
||||||
|
got_before_popup_.yes();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
|
||||||
|
TestHandler::OnAfterCreated(browser);
|
||||||
|
|
||||||
|
if (browser->IsPopup()) {
|
||||||
|
got_after_created_popup_.yes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
||||||
|
bool isLoading,
|
||||||
|
bool canGoBack,
|
||||||
|
bool canGoForward) override {
|
||||||
|
if (isLoading)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (browser->IsPopup()) {
|
||||||
|
got_load_end_popup_.yes();
|
||||||
|
CloseBrowser(browser, true);
|
||||||
|
} else {
|
||||||
|
browser->GetMainFrame()->LoadURL("javascript:window.open('')");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnLoadError(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
ErrorCode errorCode,
|
||||||
|
const CefString& errorText,
|
||||||
|
const CefString& failedUrl) override {
|
||||||
|
ADD_FAILURE() << "OnLoadError url: " << failedUrl.ToString()
|
||||||
|
<< " error: " << errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override {
|
||||||
|
TestHandler::OnBeforeClose(browser);
|
||||||
|
|
||||||
|
if (browser->IsPopup()) {
|
||||||
|
got_before_close_popup_.yes();
|
||||||
|
DestroyTest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DestroyTest() override {
|
||||||
|
EXPECT_TRUE(got_before_popup_);
|
||||||
|
EXPECT_TRUE(got_after_created_popup_);
|
||||||
|
EXPECT_TRUE(got_load_end_popup_);
|
||||||
|
EXPECT_TRUE(got_before_close_popup_);
|
||||||
|
|
||||||
|
TestHandler::DestroyTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackCallback got_before_popup_;
|
||||||
|
TrackCallback got_after_created_popup_;
|
||||||
|
TrackCallback got_load_end_popup_;
|
||||||
|
TrackCallback got_before_close_popup_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(PopupJSWindowEmptyTestHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Test creation of a popup where the URL is empty.
|
||||||
|
TEST(NavigationTest, PopupJSWindowEmpty) {
|
||||||
|
CefRefPtr<PopupJSWindowEmptyTestHandler> handler =
|
||||||
|
new PopupJSWindowEmptyTestHandler();
|
||||||
|
handler->ExecuteTest();
|
||||||
|
ReleaseAndWaitForDestructor(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
const char kBrowseNavPageUrl[] = "http://tests-browsenav/nav.html";
|
const char kBrowseNavPageUrl[] = "http://tests-browsenav/nav.html";
|
||||||
|
|
||||||
// Browser side.
|
// Browser side.
|
||||||
|
Reference in New Issue
Block a user