Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: avoid contextBridge crash when RenderFrame address is reused #21514

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 3 additions & 11 deletions shell/renderer/api/atom_api_context_bridge.cc
Expand Up @@ -34,20 +34,12 @@ content::RenderFrame* GetRenderFrame(const v8::Local<v8::Object>& value) {
return content::RenderFrame::FromWebFrame(frame);
}

std::map<content::RenderFrame*, context_bridge::RenderFramePersistenceStore*>&
GetStoreMap() {
static base::NoDestructor<std::map<
content::RenderFrame*, context_bridge::RenderFramePersistenceStore*>>
store_map;
return *store_map;
}

context_bridge::RenderFramePersistenceStore* GetOrCreateStore(
content::RenderFrame* render_frame) {
auto it = GetStoreMap().find(render_frame);
if (it == GetStoreMap().end()) {
auto it = context_bridge::GetStoreMap().find(render_frame->GetRoutingID());
if (it == context_bridge::GetStoreMap().end()) {
auto* store = new context_bridge::RenderFramePersistenceStore(render_frame);
GetStoreMap().emplace(render_frame, store);
context_bridge::GetStoreMap().emplace(render_frame->GetRoutingID(), store);
return store;
}
return it->second;
Expand Down
Expand Up @@ -66,6 +66,12 @@ class CachedProxyLifeMonitor final : public ObjectLifeMonitor {

} // namespace

std::map<int32_t, RenderFramePersistenceStore*>& GetStoreMap() {
static base::NoDestructor<std::map<int32_t, RenderFramePersistenceStore*>>
store_map;
return *store_map;
}

WeakGlobalPairNode::WeakGlobalPairNode(WeakGlobalPair pair) {
this->pair = std::move(pair);
}
Expand All @@ -78,11 +84,13 @@ WeakGlobalPairNode::~WeakGlobalPairNode() {

RenderFramePersistenceStore::RenderFramePersistenceStore(
content::RenderFrame* render_frame)
: content::RenderFrameObserver(render_frame) {}
: content::RenderFrameObserver(render_frame),
routing_id_(render_frame->GetRoutingID()) {}

RenderFramePersistenceStore::~RenderFramePersistenceStore() = default;

void RenderFramePersistenceStore::OnDestruct() {
GetStoreMap().erase(routing_id_);
delete this;
}

Expand Down
Expand Up @@ -58,11 +58,15 @@ class RenderFramePersistenceStore final : public content::RenderFrameObserver {
// proxy maps are weak globals, i.e. these are not retained beyond
// there normal JS lifetime. You must check IsEmpty()

const int32_t routing_id_;

// object_identity ==> [from_value, proxy_value]
std::map<int, WeakGlobalPairNode*> proxy_map_;
base::WeakPtrFactory<RenderFramePersistenceStore> weak_factory_{this};
};

std::map<int32_t, RenderFramePersistenceStore*>& GetStoreMap();

} // namespace context_bridge

} // namespace api
Expand Down