OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/renderer/extensions/event_bindings.h" | 5 #include "chrome/renderer/extensions/event_bindings.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 WebKit::WebString::fromUTF8(file_full_path.c_str()), | 182 WebKit::WebString::fromUTF8(file_full_path.c_str()), |
183 is_directory); | 183 is_directory); |
184 #else | 184 #else |
185 return v8::Undefined(); | 185 return v8::Undefined(); |
186 #endif | 186 #endif |
187 } | 187 } |
188 }; | 188 }; |
189 | 189 |
190 // Returns true if the extension running in the given |context| has sufficient | 190 // Returns true if the extension running in the given |context| has sufficient |
191 // permissions to access the data. | 191 // permissions to access the data. |
192 static bool HasSufficientPermissions(ContextInfo* context, | 192 static bool HasSufficientPermissions(RenderView* render_view, |
193 const GURL& event_url) { | 193 const GURL& event_url) { |
194 v8::Context::Scope context_scope(context->context); | |
195 | |
196 // During unit tests, we might be invoked without a v8 context. In these | 194 // During unit tests, we might be invoked without a v8 context. In these |
197 // cases, we only allow empty event_urls and short-circuit before retrieving | 195 // cases, we only allow empty event_urls and short-circuit before retrieving |
198 // the render view from the current context. | 196 // the render view from the current context. |
199 if (!event_url.is_valid()) | 197 if (!event_url.is_valid()) |
200 return true; | 198 return true; |
201 | 199 |
202 RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext(); | 200 WebDocument document = render_view->webview()->mainFrame()->document(); |
203 if (!renderview) | |
204 return false; | |
205 | |
206 WebDocument document = renderview->webview()->mainFrame()->document(); | |
207 return GURL(document.url()).SchemeIs(chrome::kExtensionScheme) && | 201 return GURL(document.url()).SchemeIs(chrome::kExtensionScheme) && |
208 document.securityOrigin().canRequest(event_url); | 202 document.securityOrigin().canRequest(event_url); |
209 } | 203 } |
210 | 204 |
211 } // namespace | 205 } // namespace |
212 | 206 |
213 const char* EventBindings::kName = "chrome/EventBindings"; | 207 const char* EventBindings::kName = "chrome/EventBindings"; |
214 const char* EventBindings::kTestingExtensionId = | 208 const char* EventBindings::kTestingExtensionId = |
215 "oooooooooooooooooooooooooooooooo"; | 209 "oooooooooooooooooooooooooooooooo"; |
216 | 210 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 if (!context.IsEmpty()) { | 351 if (!context.IsEmpty()) { |
358 ContextList::iterator context_iter = bindings_utils::FindContext(context); | 352 ContextList::iterator context_iter = bindings_utils::FindContext(context); |
359 if (context_iter != GetContexts().end()) | 353 if (context_iter != GetContexts().end()) |
360 UnregisterContext(context_iter, false); | 354 UnregisterContext(context_iter, false); |
361 } | 355 } |
362 | 356 |
363 // Unload any content script contexts for this frame. Note that the frame | 357 // Unload any content script contexts for this frame. Note that the frame |
364 // itself might not be registered, but can still be a parent frame. | 358 // itself might not be registered, but can still be a parent frame. |
365 for (ContextList::iterator it = GetContexts().begin(); | 359 for (ContextList::iterator it = GetContexts().begin(); |
366 it != GetContexts().end(); ) { | 360 it != GetContexts().end(); ) { |
367 if ((*it)->frame == frame) { | 361 if ((*it)->unsafe_frame == frame) { |
368 UnregisterContext(it, false); | 362 UnregisterContext(it, false); |
369 // UnregisterContext will remove |it| from the list, but may also | 363 // UnregisterContext will remove |it| from the list, but may also |
370 // modify the rest of the list as a result of calling into javascript. | 364 // modify the rest of the list as a result of calling into javascript. |
371 it = GetContexts().begin(); | 365 it = GetContexts().begin(); |
372 } else { | 366 } else { |
373 ++it; | 367 ++it; |
374 } | 368 } |
375 } | 369 } |
376 } | 370 } |
377 | 371 |
378 // static | 372 // static |
379 void EventBindings::CallFunction(const std::string& extension_id, | 373 void EventBindings::CallFunction(const std::string& extension_id, |
380 const std::string& function_name, | 374 const std::string& function_name, |
381 const ListValue& arguments, | 375 const ListValue& arguments, |
382 RenderView* render_view, | 376 RenderView* render_view, |
383 const GURL& event_url) { | 377 const GURL& event_url) { |
384 v8::HandleScope handle_scope; | 378 v8::HandleScope handle_scope; |
385 | 379 |
386 // We copy the context list, because calling into javascript may modify it | 380 // We copy the context list, because calling into javascript may modify it |
387 // out from under us. We also guard against deleted contexts by checking if | 381 // out from under us. We also guard against deleted contexts by checking if |
388 // they have been cleared first. | 382 // they have been cleared first. |
389 ContextList contexts = GetContexts(); | 383 ContextList contexts = GetContexts(); |
390 | 384 |
391 V8ValueConverter converter; | 385 V8ValueConverter converter; |
392 for (ContextList::iterator it = contexts.begin(); | 386 for (ContextList::iterator it = contexts.begin(); |
393 it != contexts.end(); ++it) { | 387 it != contexts.end(); ++it) { |
394 if (render_view) { | 388 if ((*it)->context.IsEmpty()) |
395 RenderView* context_render_view = | 389 continue; |
396 RenderView::FromWebView((*it)->frame->view()); | |
397 if (render_view != context_render_view) | |
398 continue; | |
399 } | |
400 | 390 |
401 if (!extension_id.empty() && extension_id != (*it)->extension_id) | 391 if (!extension_id.empty() && extension_id != (*it)->extension_id) |
402 continue; | 392 continue; |
403 | 393 |
404 if ((*it)->context.IsEmpty()) | 394 WebFrame* context_frame = WebFrame::frameForContext((*it)->context); |
| 395 if (!context_frame || !context_frame->view()) |
405 continue; | 396 continue; |
406 | 397 |
407 if (!HasSufficientPermissions(it->get(), event_url)) | 398 RenderView* context_render_view = |
| 399 RenderView::FromWebView(context_frame->view()); |
| 400 if (!context_render_view) |
| 401 continue; |
| 402 |
| 403 if (render_view && render_view != context_render_view) |
| 404 continue; |
| 405 |
| 406 if (!HasSufficientPermissions(context_render_view, event_url)) |
408 continue; | 407 continue; |
409 | 408 |
410 v8::Local<v8::Context> context(*((*it)->context)); | 409 v8::Local<v8::Context> context(*((*it)->context)); |
411 std::vector<v8::Handle<v8::Value> > v8_arguments; | 410 std::vector<v8::Handle<v8::Value> > v8_arguments; |
412 for (size_t i = 0; i < arguments.GetSize(); ++i) { | 411 for (size_t i = 0; i < arguments.GetSize(); ++i) { |
413 Value* item = NULL; | 412 Value* item = NULL; |
414 CHECK(arguments.Get(i, &item)); | 413 CHECK(arguments.Get(i, &item)); |
415 v8_arguments.push_back(converter.ToV8Value(item, context)); | 414 v8_arguments.push_back(converter.ToV8Value(item, context)); |
416 } | 415 } |
417 | 416 |
418 v8::Handle<v8::Value> retval = CallFunctionInContext( | 417 v8::Handle<v8::Value> retval = CallFunctionInContext( |
419 context, function_name, v8_arguments.size(), &v8_arguments[0]); | 418 context, function_name, v8_arguments.size(), &v8_arguments[0]); |
420 // In debug, the js will validate the event parameters and return a | 419 // In debug, the js will validate the event parameters and return a |
421 // string if a validation error has occured. | 420 // string if a validation error has occured. |
422 // TODO(rafaelw): Consider only doing this check if function_name == | 421 // TODO(rafaelw): Consider only doing this check if function_name == |
423 // "Event.dispatchJSON". | 422 // "Event.dispatchJSON". |
424 #ifndef NDEBUG | 423 #ifndef NDEBUG |
425 if (!retval.IsEmpty() && !retval->IsUndefined()) { | 424 if (!retval.IsEmpty() && !retval->IsUndefined()) { |
426 std::string error = *v8::String::AsciiValue(retval); | 425 std::string error = *v8::String::AsciiValue(retval); |
427 DCHECK(false) << error; | 426 DCHECK(false) << error; |
428 } | 427 } |
429 #endif | 428 #endif |
430 } | 429 } |
431 } | 430 } |
OLD | NEW |