Skip to content

Commit

Permalink
cefclient: Fix invalid cast to ClientHandlerStd (see #3499)
Browse files Browse the repository at this point in the history
  • Loading branch information
magreenblatt committed Aug 5, 2024
1 parent 0d1d087 commit 49b6073
Show file tree
Hide file tree
Showing 13 changed files with 95 additions and 7 deletions.
1 change: 1 addition & 0 deletions cef_paths2.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@
'tests/cefclient/browser/client_prefs.cc',
'tests/cefclient/browser/client_prefs.h',
'tests/cefclient/browser/client_types.h',
'tests/cefclient/browser/default_client_handler.cc',
'tests/cefclient/browser/default_client_handler.h',
'tests/cefclient/browser/dialog_test.cc',
'tests/cefclient/browser/dialog_test.h',
Expand Down
8 changes: 7 additions & 1 deletion tests/cefclient/browser/base_client_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ BaseClientHandler::BaseClientHandler() {
// static
CefRefPtr<BaseClientHandler> BaseClientHandler::GetForBrowser(
CefRefPtr<CefBrowser> browser) {
return static_cast<BaseClientHandler*>(browser->GetHost()->GetClient().get());
return GetForClient(browser->GetHost()->GetClient());
}

// static
CefRefPtr<BaseClientHandler> BaseClientHandler::GetForClient(
CefRefPtr<CefClient> client) {
return static_cast<BaseClientHandler*>(client.get());
}

bool BaseClientHandler::OnProcessMessageReceived(
Expand Down
6 changes: 6 additions & 0 deletions tests/cefclient/browser/base_client_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class BaseClientHandler : public CefClient,
static CefRefPtr<BaseClientHandler> GetForBrowser(
CefRefPtr<CefBrowser> browser);

// Returns the BaseClientHandler for |client|.
static CefRefPtr<BaseClientHandler> GetForClient(CefRefPtr<CefClient> client);

// CefClient methods
CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override { return this; }
CefRefPtr<CefRequestHandler> GetRequestHandler() override { return this; }
Expand Down Expand Up @@ -92,6 +95,9 @@ class BaseClientHandler : public CefClient,
void SetHangAction(HangAction action);
HangAction GetHangAction() const;

// Used to determine the object type for each concrete implementation.
virtual const void* GetTypeKey() const = 0;

protected:
CefRefPtr<CefResourceManager> GetResourceManager() const {
return resource_manager_;
Expand Down
4 changes: 3 additions & 1 deletion tests/cefclient/browser/browser_window_osr_gtk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1124,7 +1124,9 @@ void BrowserWindowOsrGtk::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();

// Detach |this| from the ClientHandlerOsr.
static_cast<ClientHandlerOsr*>(client_handler_.get())->DetachOsrDelegate();
auto handler = ClientHandlerOsr::GetForClient(client_handler_);
CHECK(handler);
handler->DetachOsrDelegate();

ScopedGdkThreadsEnter scoped_gdk_threads;

Expand Down
6 changes: 4 additions & 2 deletions tests/cefclient/browser/browser_window_osr_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1581,8 +1581,10 @@ void OnImeCompositionRangeChanged(
REQUIRE_MAIN_THREAD();

// Detach |this| from the ClientHandlerOsr.
static_cast<ClientHandlerOsr*>(browser_window_.client_handler_.get())
->DetachOsrDelegate();
auto handler =
ClientHandlerOsr::GetForClient(browser_window_.client_handler_);
CHECK(handler);
handler->DetachOsrDelegate();
}

bool BrowserWindowOsrMacImpl::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
Expand Down
10 changes: 10 additions & 0 deletions tests/cefclient/browser/client_handler_osr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ ClientHandlerOsr::ClientHandlerOsr(Delegate* delegate,
DCHECK(osr_delegate_);
}

// static
CefRefPtr<ClientHandlerOsr> ClientHandlerOsr::GetForClient(
CefRefPtr<CefClient> client) {
auto base = BaseClientHandler::GetForClient(client);
if (base && base->GetTypeKey() == &kTypeKey) {
return static_cast<ClientHandlerOsr*>(base.get());
}
return nullptr;
}

void ClientHandlerOsr::DetachOsrDelegate() {
if (!CefCurrentlyOn(TID_UI)) {
// Execute this method on the UI thread.
Expand Down
8 changes: 8 additions & 0 deletions tests/cefclient/browser/client_handler_osr.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ class ClientHandlerOsr : public ClientHandler,
bool with_controls,
const std::string& startup_url);

// Returns the ClientHandlerOsr for |client|, or nullptr if |client| is not a
// ClientHandlerOsr.
static CefRefPtr<ClientHandlerOsr> GetForClient(CefRefPtr<CefClient> client);

// This object may outlive the OsrDelegate object so it's necessary for the
// OsrDelegate to detach itself before destruction.
void DetachOsrDelegate();
Expand Down Expand Up @@ -139,6 +143,10 @@ class ClientHandlerOsr : public ClientHandler,
void OnAccessibilityLocationChange(CefRefPtr<CefValue> value) override;

private:
// Used to determine the object type.
virtual const void* GetTypeKey() const override { return &kTypeKey; }
static const int kTypeKey = 0;

// Only accessed on the UI thread.
OsrDelegate* osr_delegate_;

Expand Down
10 changes: 10 additions & 0 deletions tests/cefclient/browser/client_handler_std.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,14 @@ ClientHandlerStd::ClientHandlerStd(Delegate* delegate,
const std::string& startup_url)
: ClientHandler(delegate, /*is_osr=*/false, with_controls, startup_url) {}

// static
CefRefPtr<ClientHandlerStd> ClientHandlerStd::GetForClient(
CefRefPtr<CefClient> client) {
auto base = BaseClientHandler::GetForClient(client);
if (base && base->GetTypeKey() == &kTypeKey) {
return static_cast<ClientHandlerStd*>(base.get());
}
return nullptr;
}

} // namespace client
8 changes: 8 additions & 0 deletions tests/cefclient/browser/client_handler_std.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@ class ClientHandlerStd : public ClientHandler {
bool with_controls,
const std::string& startup_url);

// Returns the ClientHandlerStd for |client|, or nullptr if |client| is not a
// ClientHandlerStd.
static CefRefPtr<ClientHandlerStd> GetForClient(CefRefPtr<CefClient> client);

private:
// Used to determine the object type.
virtual const void* GetTypeKey() const override { return &kTypeKey; }
static const int kTypeKey = 0;

// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(ClientHandlerStd);
DISALLOW_COPY_AND_ASSIGN(ClientHandlerStd);
Expand Down
19 changes: 19 additions & 0 deletions tests/cefclient/browser/default_client_handler.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include "tests/cefclient/browser/default_client_handler.h"

namespace client {

// static
CefRefPtr<DefaultClientHandler> DefaultClientHandler::GetForClient(
CefRefPtr<CefClient> client) {
auto base = BaseClientHandler::GetForClient(client);
if (base && base->GetTypeKey() == &kTypeKey) {
return static_cast<DefaultClientHandler*>(base.get());
}
return nullptr;
}

} // namespace client
9 changes: 9 additions & 0 deletions tests/cefclient/browser/default_client_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,16 @@ class DefaultClientHandler : public BaseClientHandler {
public:
DefaultClientHandler() = default;

// Returns the DefaultClientHandler for |client|, or nullptr if |client| is
// not a DefaultClientHandler.
static CefRefPtr<DefaultClientHandler> GetForClient(
CefRefPtr<CefClient> client);

private:
// Used to determine the object type.
virtual const void* GetTypeKey() const override { return &kTypeKey; }
static const int kTypeKey = 0;

IMPLEMENT_REFCOUNTING(DefaultClientHandler);
DISALLOW_COPY_AND_ASSIGN(DefaultClientHandler);
};
Expand Down
6 changes: 4 additions & 2 deletions tests/cefclient/browser/osr_window_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -947,8 +947,10 @@ void OsrWindowWin::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
void OsrWindowWin::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
// Detach |this| from the ClientHandlerOsr.
static_cast<ClientHandlerOsr*>(browser_->GetHost()->GetClient().get())
->DetachOsrDelegate();
auto handler =
ClientHandlerOsr::GetForClient(browser_->GetHost()->GetClient());
CHECK(handler);
handler->DetachOsrDelegate();
browser_ = nullptr;
render_handler_->SetBrowser(nullptr);
Destroy();
Expand Down
7 changes: 6 additions & 1 deletion tests/cefclient/browser/root_window_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,12 @@ ViewsWindow::Delegate* RootWindowViews::GetDelegateForPopup(
CefRefPtr<CefClient> client) {
CEF_REQUIRE_UI_THREAD();
// |handler| was created in RootWindowViews::InitAsPopup().
ClientHandlerStd* handler = static_cast<ClientHandlerStd*>(client.get());
// May return nullptr when running with `--use-default-popup`.
auto handler = ClientHandlerStd::GetForClient(client);
if (!handler) {
return nullptr;
}

RootWindowViews* root_window =
static_cast<RootWindowViews*>(handler->delegate());

Expand Down

0 comments on commit 49b6073

Please sign in to comment.