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/extension_process_bindings.h" | 5 #include "chrome/renderer/extensions/extension_process_bindings.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <set> | 8 #include <set> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 if (!ViewTypeMatches(render_view->view_type(), view_type_)) | 123 if (!ViewTypeMatches(render_view->view_type(), view_type_)) |
124 return true; | 124 return true; |
125 | 125 |
126 GURL url = render_view->webview()->mainFrame()->url(); | 126 GURL url = render_view->webview()->mainFrame()->url(); |
127 if (!url.SchemeIs(chrome::kExtensionScheme)) | 127 if (!url.SchemeIs(chrome::kExtensionScheme)) |
128 return true; | 128 return true; |
129 const std::string& extension_id = url.host(); | 129 const std::string& extension_id = url.host(); |
130 if (extension_id != extension_id_) | 130 if (extension_id != extension_id_) |
131 return true; | 131 return true; |
132 | 132 |
133 // If we are searching for a pop-up, it may be the case that the pop-up | 133 if (browser_window_id_ != extension_misc::kUnknownWindowId && |
134 // is not attached to a browser window instance. (It is hosted in a | 134 render_view->browser_window_id() != browser_window_id_) { |
135 // ExternalTabContainer.) If so, then bypass validation of | 135 return true; |
136 // same-browser-window origin. | |
137 // TODO(twiz): The browser window id of the views visited should always | |
138 // match that of the arguments to the accumulator. | |
139 // See bug: http://crbug.com/29646 | |
140 if (!(view_type_ == ViewType::EXTENSION_POPUP && | |
141 render_view->browser_window_id() == | |
142 extension_misc::kUnknownWindowId)) { | |
143 if (browser_window_id_ != extension_misc::kUnknownWindowId && | |
144 render_view->browser_window_id() != browser_window_id_) { | |
145 return true; | |
146 } | |
147 } | 136 } |
148 | 137 |
149 v8::Local<v8::Context> context = | 138 v8::Local<v8::Context> context = |
150 render_view->webview()->mainFrame()->mainWorldScriptContext(); | 139 render_view->webview()->mainFrame()->mainWorldScriptContext(); |
151 if (!context.IsEmpty()) { | 140 if (!context.IsEmpty()) { |
152 v8::Local<v8::Value> window = context->Global(); | 141 v8::Local<v8::Value> window = context->Global(); |
153 DCHECK(!window.IsEmpty()); | 142 DCHECK(!window.IsEmpty()); |
154 | 143 |
155 if (!OnMatchedView(window)) | 144 if (!OnMatchedView(window)) |
156 return false; | 145 return false; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 } else if (name->Equals(v8::String::New("GetNextRequestId"))) { | 218 } else if (name->Equals(v8::String::New("GetNextRequestId"))) { |
230 return v8::FunctionTemplate::New(GetNextRequestId); | 219 return v8::FunctionTemplate::New(GetNextRequestId); |
231 } else if (name->Equals(v8::String::New("OpenChannelToTab"))) { | 220 } else if (name->Equals(v8::String::New("OpenChannelToTab"))) { |
232 return v8::FunctionTemplate::New(OpenChannelToTab); | 221 return v8::FunctionTemplate::New(OpenChannelToTab); |
233 } else if (name->Equals(v8::String::New("GetCurrentPageActions"))) { | 222 } else if (name->Equals(v8::String::New("GetCurrentPageActions"))) { |
234 return v8::FunctionTemplate::New(GetCurrentPageActions); | 223 return v8::FunctionTemplate::New(GetCurrentPageActions); |
235 } else if (name->Equals(v8::String::New("StartRequest"))) { | 224 } else if (name->Equals(v8::String::New("StartRequest"))) { |
236 return v8::FunctionTemplate::New(StartRequest); | 225 return v8::FunctionTemplate::New(StartRequest); |
237 } else if (name->Equals(v8::String::New("GetRenderViewId"))) { | 226 } else if (name->Equals(v8::String::New("GetRenderViewId"))) { |
238 return v8::FunctionTemplate::New(GetRenderViewId); | 227 return v8::FunctionTemplate::New(GetRenderViewId); |
239 } else if (name->Equals(v8::String::New("GetPopupView"))) { | |
240 return v8::FunctionTemplate::New(GetPopupView); | |
241 } else if (name->Equals(v8::String::New("GetPopupParentWindow"))) { | |
242 return v8::FunctionTemplate::New(GetPopupParentWindow); | |
243 } else if (name->Equals(v8::String::New("SetIconCommon"))) { | 228 } else if (name->Equals(v8::String::New("SetIconCommon"))) { |
244 return v8::FunctionTemplate::New(SetIconCommon); | 229 return v8::FunctionTemplate::New(SetIconCommon); |
245 } else if (name->Equals(v8::String::New("IsExtensionProcess"))) { | 230 } else if (name->Equals(v8::String::New("IsExtensionProcess"))) { |
246 return v8::FunctionTemplate::New(IsExtensionProcess); | 231 return v8::FunctionTemplate::New(IsExtensionProcess); |
247 } else if (name->Equals(v8::String::New("IsIncognitoProcess"))) { | 232 } else if (name->Equals(v8::String::New("IsIncognitoProcess"))) { |
248 return v8::FunctionTemplate::New(IsIncognitoProcess); | 233 return v8::FunctionTemplate::New(IsIncognitoProcess); |
249 } | 234 } |
250 | 235 |
251 return ExtensionBase::GetNativeFunction(name); | 236 return ExtensionBase::GetNativeFunction(name); |
252 } | 237 } |
253 | 238 |
254 private: | 239 private: |
255 static v8::Handle<v8::Value> GetExtensionAPIDefinition( | 240 static v8::Handle<v8::Value> GetExtensionAPIDefinition( |
256 const v8::Arguments& args) { | 241 const v8::Arguments& args) { |
257 return v8::String::New(GetStringResource(IDR_EXTENSION_API_JSON)); | 242 return v8::String::New(GetStringResource(IDR_EXTENSION_API_JSON)); |
258 } | 243 } |
259 | 244 |
260 static v8::Handle<v8::Value> PopupViewFinder( | |
261 const v8::Arguments& args, | |
262 ViewType::Type viewtype_to_find) { | |
263 // TODO(twiz) Correct the logic that ties the ownership of the pop-up view | |
264 // to the hosting view. At the moment we assume that there may only be | |
265 // a single pop-up view for a given extension. By doing so, we can find | |
266 // the pop-up view by simply searching for the only pop-up view present. | |
267 // We also assume that if the current view is a pop-up, we can find the | |
268 // hosting view by searching for a tab contents view. | |
269 if (args.Length() != 0) | |
270 return v8::Undefined(); | |
271 | |
272 if (viewtype_to_find != ViewType::EXTENSION_POPUP && | |
273 viewtype_to_find != ViewType::EXTENSION_INFOBAR && | |
274 viewtype_to_find != ViewType::TAB_CONTENTS) { | |
275 NOTREACHED() << "Requesting invalid view type."; | |
276 } | |
277 | |
278 // Disallow searching for the same view type as the current view: | |
279 // Popups can only look for hosts, and hosts can only look for popups. | |
280 RenderView* render_view = bindings_utils::GetRenderViewForCurrentContext(); | |
281 if (!render_view || | |
282 render_view->view_type() == viewtype_to_find) { | |
283 return v8::Undefined(); | |
284 } | |
285 | |
286 int browser_window_id = render_view->browser_window_id(); | |
287 std::string extension_id = ExtensionIdForCurrentContext(); | |
288 if (extension_id.empty()) | |
289 return v8::Undefined(); | |
290 | |
291 ExtensionViewAccumulator popup_matcher(extension_id, | |
292 browser_window_id, | |
293 viewtype_to_find); | |
294 RenderView::ForEach(&popup_matcher); | |
295 | |
296 if (0 == popup_matcher.views()->Length()) | |
297 return v8::Undefined(); | |
298 DCHECK(1 == popup_matcher.views()->Length()); | |
299 | |
300 // Return the first view found. | |
301 return popup_matcher.views()->Get(v8::Integer::New(0)); | |
302 } | |
303 | |
304 static v8::Handle<v8::Value> GetPopupView(const v8::Arguments& args) { | |
305 return PopupViewFinder(args, ViewType::EXTENSION_POPUP); | |
306 } | |
307 | |
308 static v8::Handle<v8::Value> GetPopupParentWindow(const v8::Arguments& args) { | |
309 v8::Handle<v8::Value> view = PopupViewFinder(args, ViewType::TAB_CONTENTS); | |
310 if (view == v8::Undefined()) { | |
311 view = PopupViewFinder(args, ViewType::EXTENSION_INFOBAR); | |
312 } | |
313 return view; | |
314 } | |
315 | |
316 static v8::Handle<v8::Value> GetExtensionViews(const v8::Arguments& args) { | 245 static v8::Handle<v8::Value> GetExtensionViews(const v8::Arguments& args) { |
317 if (args.Length() != 2) | 246 if (args.Length() != 2) |
318 return v8::Undefined(); | 247 return v8::Undefined(); |
319 | 248 |
320 if (!args[0]->IsInt32() || !args[1]->IsString()) | 249 if (!args[0]->IsInt32() || !args[1]->IsString()) |
321 return v8::Undefined(); | 250 return v8::Undefined(); |
322 | 251 |
323 // |browser_window_id| == extension_misc::kUnknownWindowId means getting | 252 // |browser_window_id| == extension_misc::kUnknownWindowId means getting |
324 // views attached to any browser window. | 253 // views attached to any browser window. |
325 int browser_window_id = args[0]->Int32Value(); | 254 int browser_window_id = args[0]->Int32Value(); |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
671 ExtensionProcessBindings::ThrowPermissionDeniedException( | 600 ExtensionProcessBindings::ThrowPermissionDeniedException( |
672 const std::string& function_name) { | 601 const std::string& function_name) { |
673 static const char kMessage[] = | 602 static const char kMessage[] = |
674 "You do not have permission to use '%s'. Be sure to declare" | 603 "You do not have permission to use '%s'. Be sure to declare" |
675 " in your manifest what permissions you need."; | 604 " in your manifest what permissions you need."; |
676 std::string error_msg = StringPrintf(kMessage, function_name.c_str()); | 605 std::string error_msg = StringPrintf(kMessage, function_name.c_str()); |
677 | 606 |
678 return v8::ThrowException(v8::Exception::Error( | 607 return v8::ThrowException(v8::Exception::Error( |
679 v8::String::New(error_msg.c_str()))); | 608 v8::String::New(error_msg.c_str()))); |
680 } | 609 } |
OLD | NEW |