Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(617)

Side by Side Diff: components/web_view/frame.cc

Issue 1323233004: Adds better security checking to OnCreatedFrame() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/web_view/frame.h ('k') | components/web_view/frame_apptest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/web_view/frame.h" 5 #include "components/web_view/frame.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 11 matching lines...) Expand all
22 DECLARE_VIEW_PROPERTY_TYPE(web_view::Frame*); 22 DECLARE_VIEW_PROPERTY_TYPE(web_view::Frame*);
23 23
24 namespace web_view { 24 namespace web_view {
25 25
26 // Used to find the Frame associated with a View. 26 // Used to find the Frame associated with a View.
27 DEFINE_LOCAL_VIEW_PROPERTY_KEY(Frame*, kFrame, nullptr); 27 DEFINE_LOCAL_VIEW_PROPERTY_KEY(Frame*, kFrame, nullptr);
28 28
29 namespace { 29 namespace {
30 30
31 const uint32_t kNoParentId = 0u; 31 const uint32_t kNoParentId = 0u;
32 const mojo::ConnectionSpecificId kInvalidConnectionId = 0u;
32 33
33 FrameDataPtr FrameToFrameData(const Frame* frame) { 34 FrameDataPtr FrameToFrameData(const Frame* frame) {
34 FrameDataPtr frame_data(FrameData::New()); 35 FrameDataPtr frame_data(FrameData::New());
35 frame_data->frame_id = frame->id(); 36 frame_data->frame_id = frame->id();
36 frame_data->parent_id = frame->parent() ? frame->parent()->id() : kNoParentId; 37 frame_data->parent_id = frame->parent() ? frame->parent()->id() : kNoParentId;
37 frame_data->client_properties = 38 frame_data->client_properties =
38 mojo::Map<mojo::String, mojo::Array<uint8_t>>::From( 39 mojo::Map<mojo::String, mojo::Array<uint8_t>>::From(
39 frame->client_properties()); 40 frame->client_properties());
40 return frame_data.Pass(); 41 return frame_data.Pass();
41 } 42 }
42 43
43 } // namespace 44 } // namespace
44 45
45 struct Frame::FrameTreeServerBinding { 46 struct Frame::FrameTreeServerBinding {
46 scoped_ptr<FrameUserData> user_data; 47 scoped_ptr<FrameUserData> user_data;
47 scoped_ptr<mojo::Binding<FrameTreeServer>> frame_tree_server_binding; 48 scoped_ptr<mojo::Binding<FrameTreeServer>> frame_tree_server_binding;
48 }; 49 };
49 50
50 Frame::Frame(FrameTree* tree, 51 Frame::Frame(FrameTree* tree,
51 View* view, 52 View* view,
52 uint32_t frame_id, 53 uint32_t frame_id,
53 uint32_t app_id, 54 uint32_t app_id,
54 ViewOwnership view_ownership, 55 ViewOwnership view_ownership,
55 FrameTreeClient* frame_tree_client, 56 FrameTreeClient* frame_tree_client,
56 scoped_ptr<FrameUserData> user_data, 57 scoped_ptr<FrameUserData> user_data,
57 const ClientPropertyMap& client_properties) 58 const ClientPropertyMap& client_properties)
58 : tree_(tree), 59 : tree_(tree),
59 view_(nullptr), 60 view_(nullptr),
61 embedded_connection_id_(kInvalidConnectionId),
60 id_(frame_id), 62 id_(frame_id),
61 app_id_(app_id), 63 app_id_(app_id),
62 parent_(nullptr), 64 parent_(nullptr),
63 view_ownership_(view_ownership), 65 view_ownership_(view_ownership),
64 user_data_(user_data.Pass()), 66 user_data_(user_data.Pass()),
65 frame_tree_client_(frame_tree_client), 67 frame_tree_client_(frame_tree_client),
66 loading_(false), 68 loading_(false),
67 progress_(0.f), 69 progress_(0.f),
68 client_properties_(client_properties), 70 client_properties_(client_properties),
69 weak_factory_(this), 71 embed_weak_ptr_factory_(this),
70 navigate_weak_ptr_factory_(this) { 72 navigate_weak_ptr_factory_(this) {
71 if (view) 73 if (view)
72 SetView(view); 74 SetView(view);
73 } 75 }
74 76
75 Frame::~Frame() { 77 Frame::~Frame() {
76 if (view_) 78 if (view_)
77 view_->RemoveObserver(this); 79 view_->RemoveObserver(this);
78 while (!children_.empty()) 80 while (!children_.empty())
79 delete children_[0]; 81 delete children_[0];
80 if (parent_) 82 if (parent_)
81 parent_->Remove(this); 83 parent_->Remove(this);
82 if (view_) { 84 if (view_) {
83 view_->ClearLocalProperty(kFrame); 85 view_->ClearLocalProperty(kFrame);
84 if (view_ownership_ == ViewOwnership::OWNS_VIEW) 86 if (view_ownership_ == ViewOwnership::OWNS_VIEW)
85 view_->Destroy(); 87 view_->Destroy();
86 } 88 }
87 } 89 }
88 90
89 void Frame::Init(Frame* parent) { 91 void Frame::Init(Frame* parent, mojo::ViewTreeClientPtr view_tree_client) {
90 { 92 {
91 // Set the FrameTreeClient to null so that we don't notify the client of the 93 // Set the FrameTreeClient to null so that we don't notify the client of the
92 // add before OnConnect(). 94 // add before OnConnect().
93 base::AutoReset<FrameTreeClient*> frame_tree_client_resetter( 95 base::AutoReset<FrameTreeClient*> frame_tree_client_resetter(
94 &frame_tree_client_, nullptr); 96 &frame_tree_client_, nullptr);
95 if (parent) 97 if (parent)
96 parent->Add(this); 98 parent->Add(this);
97 } 99 }
98 100
99 InitClient(ClientType::NEW_APP, nullptr); 101 InitClient(ClientType::NEW_APP, nullptr, view_tree_client.Pass());
100 } 102 }
101 103
102 // static 104 // static
103 Frame* Frame::FindFirstFrameAncestor(View* view) { 105 Frame* Frame::FindFirstFrameAncestor(View* view) {
104 while (view && !view->GetLocalProperty(kFrame)) 106 while (view && !view->GetLocalProperty(kFrame))
105 view = view->parent(); 107 view = view->parent();
106 return view ? view->GetLocalProperty(kFrame) : nullptr; 108 return view ? view->GetLocalProperty(kFrame) : nullptr;
107 } 109 }
108 110
109 const Frame* Frame::FindFrame(uint32_t id) const { 111 const Frame* Frame::FindFrame(uint32_t id) const {
(...skipping 28 matching lines...) Expand all
138 double Frame::GatherProgress(int* frame_count) const { 140 double Frame::GatherProgress(int* frame_count) const {
139 ++(*frame_count); 141 ++(*frame_count);
140 double progress = progress_; 142 double progress = progress_;
141 for (const Frame* child : children_) 143 for (const Frame* child : children_)
142 progress += child->GatherProgress(frame_count); 144 progress += child->GatherProgress(frame_count);
143 return progress_; 145 return progress_;
144 } 146 }
145 147
146 void Frame::InitClient( 148 void Frame::InitClient(
147 ClientType client_type, 149 ClientType client_type,
148 scoped_ptr<FrameTreeServerBinding> frame_tree_server_binding) { 150 scoped_ptr<FrameTreeServerBinding> frame_tree_server_binding,
151 mojo::ViewTreeClientPtr view_tree_client) {
152 if (client_type == ClientType::NEW_APP && view_tree_client.get()) {
153 embedded_connection_id_ = kInvalidConnectionId;
154 embed_weak_ptr_factory_.InvalidateWeakPtrs();
155 view_->Embed(
156 view_tree_client.Pass(),
157 base::Bind(&Frame::OnEmbedAck, embed_weak_ptr_factory_.GetWeakPtr()));
158 }
159
149 std::vector<const Frame*> frames; 160 std::vector<const Frame*> frames;
150 tree_->root()->BuildFrameTree(&frames); 161 tree_->root()->BuildFrameTree(&frames);
151 162
152 mojo::Array<FrameDataPtr> array(frames.size()); 163 mojo::Array<FrameDataPtr> array(frames.size());
153 for (size_t i = 0; i < frames.size(); ++i) 164 for (size_t i = 0; i < frames.size(); ++i)
154 array[i] = FrameToFrameData(frames[i]).Pass(); 165 array[i] = FrameToFrameData(frames[i]).Pass();
155 166
156 // TODO(sky): error handling. 167 // TODO(sky): error handling.
157 FrameTreeServerPtr frame_tree_server_ptr; 168 FrameTreeServerPtr frame_tree_server_ptr;
158 frame_tree_server_binding_.reset(new mojo::Binding<FrameTreeServer>( 169 frame_tree_server_binding_.reset(new mojo::Binding<FrameTreeServer>(
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 frame_tree_server_binding_.Pass(); 203 frame_tree_server_binding_.Pass();
193 } 204 }
194 205
195 user_data_ = user_data.Pass(); 206 user_data_ = user_data.Pass();
196 frame_tree_client_ = frame_tree_client; 207 frame_tree_client_ = frame_tree_client;
197 frame_tree_server_binding_.reset(); 208 frame_tree_server_binding_.reset();
198 loading_ = false; 209 loading_ = false;
199 progress_ = 0.f; 210 progress_ = 0.f;
200 app_id_ = app_id; 211 app_id_ = app_id;
201 212
202 if (client_type == ClientType::NEW_APP) 213 InitClient(client_type, frame_tree_server_binding.Pass(),
203 view_->Embed(view_tree_client.Pass()); 214 view_tree_client.Pass());
215 }
204 216
205 InitClient(client_type, frame_tree_server_binding.Pass()); 217 void Frame::OnEmbedAck(bool success, mojo::ConnectionSpecificId connection_id) {
218 if (success)
219 embedded_connection_id_ = connection_id;
206 } 220 }
207 221
208 void Frame::SetView(mojo::View* view) { 222 void Frame::SetView(mojo::View* view) {
209 DCHECK(!view_); 223 DCHECK(!view_);
210 DCHECK_EQ(id_, view->id()); 224 DCHECK_EQ(id_, view->id());
211 view_ = view; 225 view_ = view;
212 view_->SetLocalProperty(kFrame, this); 226 view_->SetLocalProperty(kFrame, this);
213 view_->AddObserver(this); 227 view_->AddObserver(this);
214 if (pending_navigate_.get()) 228 if (pending_navigate_.get())
215 StartNavigate(pending_navigate_.Pass()); 229 StartNavigate(pending_navigate_.Pass());
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 } 407 }
394 408
395 void Frame::OnViewDestroying(mojo::View* view) { 409 void Frame::OnViewDestroying(mojo::View* view) {
396 if (parent_) 410 if (parent_)
397 parent_->Remove(this); 411 parent_->Remove(this);
398 412
399 // Reset |view_ownership_| so we don't attempt to delete |view_| in the 413 // Reset |view_ownership_| so we don't attempt to delete |view_| in the
400 // destructor. 414 // destructor.
401 view_ownership_ = ViewOwnership::DOESNT_OWN_VIEW; 415 view_ownership_ = ViewOwnership::DOESNT_OWN_VIEW;
402 416
403 // TODO(sky): Change browser to create a child for each FrameTree.
404 if (tree_->root() == this) { 417 if (tree_->root() == this) {
405 view_->RemoveObserver(this); 418 view_->RemoveObserver(this);
406 view_ = nullptr; 419 view_ = nullptr;
407 return; 420 return;
408 } 421 }
409 422
410 delete this; 423 delete this;
411 } 424 }
412 425
413 void Frame::PostMessageEventToFrame(uint32_t source_frame_id, 426 void Frame::PostMessageEventToFrame(uint32_t source_frame_id,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 mojo::Array<uint8_t> value) { 469 mojo::Array<uint8_t> value) {
457 Frame* target_frame = FindFrameWithIdFromSameApp(frame_id); 470 Frame* target_frame = FindFrameWithIdFromSameApp(frame_id);
458 if (target_frame) 471 if (target_frame)
459 target_frame->SetClientPropertyImpl(name, value.Pass()); 472 target_frame->SetClientPropertyImpl(name, value.Pass());
460 } 473 }
461 474
462 void Frame::OnCreatedFrame( 475 void Frame::OnCreatedFrame(
463 uint32_t parent_id, 476 uint32_t parent_id,
464 uint32_t frame_id, 477 uint32_t frame_id,
465 mojo::Map<mojo::String, mojo::Array<uint8_t>> client_properties) { 478 mojo::Map<mojo::String, mojo::Array<uint8_t>> client_properties) {
466 // TODO(sky): I need a way to verify the frame_id. Unfortunately the code here 479 if ((frame_id >> 16) != embedded_connection_id_) {
467 // doesn't know the connection id of the embedder, so it's not possible to 480 // TODO(sky): kill connection here?
468 // do it. 481 // TODO(sky): there is a race in that there is no guarantee we received the
482 // connection id before the frame tries to create a new frame. Ideally we
483 // could pause the frame until we get the connection id, but bindings don't
484 // offer such an API.
485 DVLOG(1) << "OnCreatedFrame supplied invalid frame id, expecting"
486 << embedded_connection_id_;
487 return;
488 }
469 489
470 if (FindFrame(frame_id)) { 490 if (FindFrame(frame_id)) {
471 // TODO(sky): kill connection here? 491 // TODO(sky): kill connection here?
472 DVLOG(1) << "OnCreatedLocalFrame supplied id of existing frame."; 492 DVLOG(1) << "OnCreatedFrame supplied id of existing frame.";
473 return; 493 return;
474 } 494 }
475 495
476 Frame* parent_frame = FindFrameWithIdFromSameApp(parent_id); 496 Frame* parent_frame = FindFrameWithIdFromSameApp(parent_id);
477 if (!parent_frame) { 497 if (!parent_frame) {
478 DVLOG(1) << "OnCreatedLocalFrame supplied invalid parent_id."; 498 DVLOG(1) << "OnCreatedFrame supplied invalid parent_id.";
479 return; 499 return;
480 } 500 }
481 501
482 if (parent_frame != this && parent_frame->frame_tree_client_) { 502 Frame* child_frame =
483 DVLOG(1) << "OnCreatedLocalFrame supplied parent from another connection."; 503 tree_->CreateSharedFrame(parent_frame, frame_id, app_id_,
484 return; 504 client_properties.To<ClientPropertyMap>());
485 } 505 child_frame->embedded_connection_id_ = embedded_connection_id_;
486
487 tree_->CreateSharedFrame(parent_frame, frame_id, app_id_,
488 client_properties.To<ClientPropertyMap>());
489 } 506 }
490 507
491 void Frame::RequestNavigate(NavigationTargetType target_type, 508 void Frame::RequestNavigate(NavigationTargetType target_type,
492 uint32_t target_frame_id, 509 uint32_t target_frame_id,
493 mojo::URLRequestPtr request) { 510 mojo::URLRequestPtr request) {
494 if (target_type == NAVIGATION_TARGET_TYPE_EXISTING_FRAME) { 511 if (target_type == NAVIGATION_TARGET_TYPE_EXISTING_FRAME) {
495 // |target_frame| is allowed to come from another connection. 512 // |target_frame| is allowed to come from another connection.
496 Frame* target_frame = tree_->root()->FindFrame(target_frame_id); 513 Frame* target_frame = tree_->root()->FindFrame(target_frame_id);
497 if (!target_frame) { 514 if (!target_frame) {
498 DVLOG(1) << "RequestNavigate EXIT_FRAME with no matching frame"; 515 DVLOG(1) << "RequestNavigate EXIT_FRAME with no matching frame";
499 return; 516 return;
500 } 517 }
501 if (target_frame != tree_->root()) { 518 if (target_frame != tree_->root()) {
502 target_frame->StartNavigate(request.Pass()); 519 target_frame->StartNavigate(request.Pass());
503 return; 520 return;
504 } 521 }
505 // Else case if |target_frame| == root. Treat at top level request. 522 // Else case if |target_frame| == root. Treat at top level request.
506 } 523 }
507 tree_->delegate_->NavigateTopLevel(this, request.Pass()); 524 tree_->delegate_->NavigateTopLevel(this, request.Pass());
508 } 525 }
509 526
510 void Frame::DidNavigateLocally(uint32_t frame_id, const mojo::String& url) { 527 void Frame::DidNavigateLocally(uint32_t frame_id, const mojo::String& url) {
511 NOTIMPLEMENTED(); 528 NOTIMPLEMENTED();
512 } 529 }
513 530
514 } // namespace web_view 531 } // namespace web_view
OLDNEW
« no previous file with comments | « components/web_view/frame.h ('k') | components/web_view/frame_apptest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698