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

Side by Side Diff: extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc

Issue 2695633008: Re-check existence of GuestViewContainer before requesting attach. (Closed)
Patch Set: Fix Windows compile. Created 3 years, 10 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/guest_view/renderer/guest_view_container.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "extensions/renderer/guest_view/guest_view_internal_custom_bindings.h" 5 #include "extensions/renderer/guest_view/guest_view_internal_custom_bindings.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "components/guest_view/common/guest_view_constants.h" 11 #include "components/guest_view/common/guest_view_constants.h"
12 #include "components/guest_view/common/guest_view_messages.h" 12 #include "components/guest_view/common/guest_view_messages.h"
13 #include "components/guest_view/renderer/guest_view_request.h" 13 #include "components/guest_view/renderer/guest_view_request.h"
14 #include "components/guest_view/renderer/iframe_guest_view_container.h" 14 #include "components/guest_view/renderer/iframe_guest_view_container.h"
15 #include "components/guest_view/renderer/iframe_guest_view_request.h" 15 #include "components/guest_view/renderer/iframe_guest_view_request.h"
16 #include "content/public/child/v8_value_converter.h" 16 #include "content/public/child/v8_value_converter.h"
17 #include "content/public/renderer/render_frame.h" 17 #include "content/public/renderer/render_frame.h"
18 #include "content/public/renderer/render_frame_observer.h"
18 #include "content/public/renderer/render_thread.h" 19 #include "content/public/renderer/render_thread.h"
19 #include "content/public/renderer/render_view.h" 20 #include "content/public/renderer/render_view.h"
20 #include "extensions/common/extension.h" 21 #include "extensions/common/extension.h"
21 #include "extensions/common/extension_messages.h" 22 #include "extensions/common/extension_messages.h"
22 #include "extensions/common/guest_view/extensions_guest_view_messages.h" 23 #include "extensions/common/guest_view/extensions_guest_view_messages.h"
23 #include "extensions/renderer/guest_view/extensions_guest_view_container.h" 24 #include "extensions/renderer/guest_view/extensions_guest_view_container.h"
24 #include "extensions/renderer/script_context.h" 25 #include "extensions/renderer/script_context.h"
25 #include "third_party/WebKit/public/web/WebFrame.h" 26 #include "third_party/WebKit/public/web/WebFrame.h"
26 #include "third_party/WebKit/public/web/WebLocalFrame.h" 27 #include "third_party/WebKit/public/web/WebLocalFrame.h"
27 #include "third_party/WebKit/public/web/WebRemoteFrame.h" 28 #include "third_party/WebKit/public/web/WebRemoteFrame.h"
(...skipping 22 matching lines...) Expand all
50 v8::Local<v8::Context> context = 51 v8::Local<v8::Context> context =
51 v8::Local<v8::Object>::Cast(value)->CreationContext(); 52 v8::Local<v8::Object>::Cast(value)->CreationContext();
52 if (context.IsEmpty()) 53 if (context.IsEmpty())
53 return nullptr; 54 return nullptr;
54 blink::WebLocalFrame* frame = blink::WebLocalFrame::frameForContext(context); 55 blink::WebLocalFrame* frame = blink::WebLocalFrame::frameForContext(context);
55 if (!frame) 56 if (!frame)
56 return nullptr; 57 return nullptr;
57 return content::RenderFrame::FromWebFrame(frame); 58 return content::RenderFrame::FromWebFrame(frame);
58 } 59 }
59 60
61 class RenderFrameStatus : public content::RenderFrameObserver {
62 public:
63 explicit RenderFrameStatus(content::RenderFrame* render_frame)
64 : content::RenderFrameObserver(render_frame) {}
65 ~RenderFrameStatus() final {}
66
67 bool is_ok() { return render_frame() != nullptr; }
68
69 // RenderFrameObserver implementation.
70 void OnDestruct() final {}
71 };
72
60 } // namespace 73 } // namespace
61 74
62 GuestViewInternalCustomBindings::GuestViewInternalCustomBindings( 75 GuestViewInternalCustomBindings::GuestViewInternalCustomBindings(
63 ScriptContext* context) 76 ScriptContext* context)
64 : ObjectBackedNativeHandler(context) { 77 : ObjectBackedNativeHandler(context) {
65 RouteFunction("AttachGuest", 78 RouteFunction("AttachGuest",
66 base::Bind(&GuestViewInternalCustomBindings::AttachGuest, 79 base::Bind(&GuestViewInternalCustomBindings::AttachGuest,
67 base::Unretained(this))); 80 base::Unretained(this)));
68 RouteFunction("DetachGuest", 81 RouteFunction("DetachGuest",
69 base::Bind(&GuestViewInternalCustomBindings::DetachGuest, 82 base::Bind(&GuestViewInternalCustomBindings::DetachGuest,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 150
138 int element_instance_id = args[0]->Int32Value(); 151 int element_instance_id = args[0]->Int32Value();
139 // An element instance ID uniquely identifies a GuestViewContainer. 152 // An element instance ID uniquely identifies a GuestViewContainer.
140 auto* guest_view_container = 153 auto* guest_view_container =
141 guest_view::GuestViewContainer::FromID(element_instance_id); 154 guest_view::GuestViewContainer::FromID(element_instance_id);
142 155
143 // TODO(fsamuel): Should we be reporting an error if the element instance ID 156 // TODO(fsamuel): Should we be reporting an error if the element instance ID
144 // is invalid? 157 // is invalid?
145 if (!guest_view_container) 158 if (!guest_view_container)
146 return; 159 return;
160 // Retain a weak pointer so we can easily test if the container goes away.
161 auto weak_ptr = guest_view_container->GetWeakPtr();
147 162
148 int guest_instance_id = args[1]->Int32Value(); 163 int guest_instance_id = args[1]->Int32Value();
149 164
150 std::unique_ptr<base::DictionaryValue> params; 165 std::unique_ptr<base::DictionaryValue> params;
151 { 166 {
152 std::unique_ptr<V8ValueConverter> converter(V8ValueConverter::create()); 167 std::unique_ptr<V8ValueConverter> converter(V8ValueConverter::create());
153 std::unique_ptr<base::Value> params_as_value( 168 std::unique_ptr<base::Value> params_as_value(
154 converter->FromV8Value(args[2], context()->v8_context())); 169 converter->FromV8Value(args[2], context()->v8_context()));
155 params = base::DictionaryValue::From(std::move(params_as_value)); 170 params = base::DictionaryValue::From(std::move(params_as_value));
156 CHECK(params); 171 CHECK(params);
157 } 172 }
173 // We should be careful that some malicious JS in the GuestView's embedder
174 // hasn't destroyed |guest_view_container| during the enumeration of the
175 // properties of the guest's object during extraction of |params| above
176 // (see https://crbug.com/683523).
177 if (!weak_ptr)
178 return;
158 179
159 // Add flag to |params| to indicate that the element size is specified in 180 // Add flag to |params| to indicate that the element size is specified in
160 // logical units. 181 // logical units.
161 params->SetBoolean(guest_view::kElementSizeIsLogical, true); 182 params->SetBoolean(guest_view::kElementSizeIsLogical, true);
162 183
163 std::unique_ptr<guest_view::GuestViewRequest> request( 184 std::unique_ptr<guest_view::GuestViewRequest> request(
164 new guest_view::GuestViewAttachRequest( 185 new guest_view::GuestViewAttachRequest(
165 guest_view_container, guest_instance_id, std::move(params), 186 guest_view_container, guest_instance_id, std::move(params),
166 args.Length() == 4 ? args[3].As<v8::Function>() 187 args.Length() == 4 ? args[3].As<v8::Function>()
167 : v8::Local<v8::Function>(), 188 : v8::Local<v8::Function>(),
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 CHECK(args[2]->IsObject()); 235 CHECK(args[2]->IsObject());
215 // <iframe>.contentWindow. 236 // <iframe>.contentWindow.
216 CHECK(args[3]->IsObject()); 237 CHECK(args[3]->IsObject());
217 // Optional Callback Function. 238 // Optional Callback Function.
218 CHECK(args.Length() <= num_required_params || 239 CHECK(args.Length() <= num_required_params ||
219 args[num_required_params]->IsFunction()); 240 args[num_required_params]->IsFunction());
220 241
221 int element_instance_id = args[0]->Int32Value(); 242 int element_instance_id = args[0]->Int32Value();
222 int guest_instance_id = args[1]->Int32Value(); 243 int guest_instance_id = args[1]->Int32Value();
223 244
245 // Get the WebLocalFrame before (possibly) executing any user-space JS while
246 // getting the |params|. We track the status of the RenderFrame via an
247 // observer in case it is deleted during user code execution.
248 content::RenderFrame* render_frame = GetRenderFrame(args[3]);
249 RenderFrameStatus render_frame_status(render_frame);
250
224 std::unique_ptr<base::DictionaryValue> params; 251 std::unique_ptr<base::DictionaryValue> params;
225 { 252 {
226 std::unique_ptr<V8ValueConverter> converter(V8ValueConverter::create()); 253 std::unique_ptr<V8ValueConverter> converter(V8ValueConverter::create());
227 std::unique_ptr<base::Value> params_as_value( 254 std::unique_ptr<base::Value> params_as_value(
228 converter->FromV8Value(args[2], context()->v8_context())); 255 converter->FromV8Value(args[2], context()->v8_context()));
229 params = base::DictionaryValue::From(std::move(params_as_value)); 256 params = base::DictionaryValue::From(std::move(params_as_value));
230 CHECK(params); 257 CHECK(params);
231 } 258 }
259 if (!render_frame_status.is_ok())
260 return;
261
262 blink::WebLocalFrame* frame = render_frame->GetWebFrame();
263 // Parent must exist.
264 blink::WebFrame* parent_frame = frame->parent();
265 DCHECK(parent_frame);
266 DCHECK(parent_frame->isWebLocalFrame());
232 267
233 // Add flag to |params| to indicate that the element size is specified in 268 // Add flag to |params| to indicate that the element size is specified in
234 // logical units. 269 // logical units.
235 params->SetBoolean(guest_view::kElementSizeIsLogical, true); 270 params->SetBoolean(guest_view::kElementSizeIsLogical, true);
236 271
237 content::RenderFrame* render_frame = GetRenderFrame(args[3]);
238 blink::WebLocalFrame* frame = render_frame->GetWebFrame();
239
240 // Parent must exist.
241 blink::WebFrame* parent_frame = frame->parent();
242 DCHECK(parent_frame);
243 DCHECK(parent_frame->isWebLocalFrame());
244
245 content::RenderFrame* embedder_parent_frame = 272 content::RenderFrame* embedder_parent_frame =
246 content::RenderFrame::FromWebFrame(parent_frame); 273 content::RenderFrame::FromWebFrame(parent_frame);
247 274
275 // It's possible that code executed during the |params| enumeration above
276 // could delete the guest view's RenderFrame, so we shouldn't blindly assume
277 // it still exists.
278 if (!embedder_parent_frame)
lfg 2017/02/17 16:06:10 This shouldn't be needed anymore.
wjmaclean 2017/02/17 16:18:47 Removed.
279 return;
280
248 // Create a GuestViewContainer if it does not exist. 281 // Create a GuestViewContainer if it does not exist.
249 // An element instance ID uniquely identifies an IframeGuestViewContainer 282 // An element instance ID uniquely identifies an IframeGuestViewContainer
250 // within a RenderView. 283 // within a RenderView.
251 auto* guest_view_container = 284 auto* guest_view_container =
252 guest_view::GuestViewContainer::FromID(element_instance_id); 285 guest_view::GuestViewContainer::FromID(element_instance_id);
253 // This is the first time we hear about the |element_instance_id|. 286 // This is the first time we hear about the |element_instance_id|.
254 DCHECK(!guest_view_container); 287 DCHECK(!guest_view_container);
255 // The <webview> element's GC takes ownership of |guest_view_container|. 288 // The <webview> element's GC takes ownership of |guest_view_container|.
256 guest_view_container = 289 guest_view_container =
257 new guest_view::IframeGuestViewContainer(embedder_parent_frame); 290 new guest_view::IframeGuestViewContainer(embedder_parent_frame);
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 // EnterFullscreen() and do it directly rather than having a generic "run with 464 // EnterFullscreen() and do it directly rather than having a generic "run with
432 // user gesture" function. 465 // user gesture" function.
433 blink::WebScopedUserGesture user_gesture(context()->web_frame()); 466 blink::WebScopedUserGesture user_gesture(context()->web_frame());
434 CHECK_EQ(args.Length(), 1); 467 CHECK_EQ(args.Length(), 1);
435 CHECK(args[0]->IsFunction()); 468 CHECK(args[0]->IsFunction());
436 context()->SafeCallFunction( 469 context()->SafeCallFunction(
437 v8::Local<v8::Function>::Cast(args[0]), 0, nullptr); 470 v8::Local<v8::Function>::Cast(args[0]), 0, nullptr);
438 } 471 }
439 472
440 } // namespace extensions 473 } // namespace extensions
OLDNEW
« no previous file with comments | « components/guest_view/renderer/guest_view_container.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698