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

Side by Side Diff: chrome_frame/chrome_active_document.cc

Issue 3051018: Ensure that window.open requests issued by ChromeFrame carry the correct cook... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « chrome_frame/chrome_active_document.h ('k') | chrome_frame/chrome_frame_activex_base.h » ('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 (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 // Implementation of ChromeActiveDocument 5 // Implementation of ChromeActiveDocument
6 #include "chrome_frame/chrome_active_document.h" 6 #include "chrome_frame/chrome_active_document.h"
7 7
8 #include <hlink.h> 8 #include <hlink.h>
9 #include <htiface.h> 9 #include <htiface.h>
10 #include <initguid.h> 10 #include <initguid.h>
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 #define DEFINE_ENCODING_ID_ARRAY(encoding_name, id, chrome_name) encoding_name, 58 #define DEFINE_ENCODING_ID_ARRAY(encoding_name, id, chrome_name) encoding_name,
59 INTERNAL_IE_ENCODINGMENU_IDS(DEFINE_ENCODING_ID_ARRAY) 59 INTERNAL_IE_ENCODINGMENU_IDS(DEFINE_ENCODING_ID_ARRAY)
60 #undef DEFINE_ENCODING_ID_ARRAY 60 #undef DEFINE_ENCODING_ID_ARRAY
61 0 // The Last data must be 0 to indicate the end of the encoding id array. 61 0 // The Last data must be 0 to indicate the end of the encoding id array.
62 }; 62 };
63 63
64 ChromeActiveDocument::ChromeActiveDocument() 64 ChromeActiveDocument::ChromeActiveDocument()
65 : first_navigation_(true), 65 : first_navigation_(true),
66 is_automation_client_reused_(false), 66 is_automation_client_reused_(false),
67 popup_allowed_(false), 67 popup_allowed_(false),
68 accelerator_table_(NULL), 68 accelerator_table_(NULL) {
69 is_new_navigation_(false) {
70 TRACE_EVENT_BEGIN("chromeframe.createactivedocument", this, ""); 69 TRACE_EVENT_BEGIN("chromeframe.createactivedocument", this, "");
71 70
72 url_fetcher_.set_frame_busting(false); 71 url_fetcher_.set_frame_busting(false);
73 memset(&navigation_info_, 0, sizeof(navigation_info_)); 72 memset(&navigation_info_, 0, sizeof(navigation_info_));
74 } 73 }
75 74
76 HRESULT ChromeActiveDocument::FinalConstruct() { 75 HRESULT ChromeActiveDocument::FinalConstruct() {
77 // If we have a cached ChromeActiveDocument instance in TLS, then grab 76 // If we have a cached ChromeActiveDocument instance in TLS, then grab
78 // ownership of the cached document's automation client. This is an 77 // ownership of the cached document's automation client. This is an
79 // optimization to get Chrome active documents to load faster. 78 // optimization to get Chrome active documents to load faster.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 mshtml_group_commands_map_[IDM_BASELINEFONT2] = flags; 117 mshtml_group_commands_map_[IDM_BASELINEFONT2] = flags;
119 mshtml_group_commands_map_[IDM_BASELINEFONT3] = flags; 118 mshtml_group_commands_map_[IDM_BASELINEFONT3] = flags;
120 mshtml_group_commands_map_[IDM_BASELINEFONT4] = flags; 119 mshtml_group_commands_map_[IDM_BASELINEFONT4] = flags;
121 mshtml_group_commands_map_[IDM_BASELINEFONT5] = flags; 120 mshtml_group_commands_map_[IDM_BASELINEFONT5] = flags;
122 121
123 HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase); 122 HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase);
124 accelerator_table_ = 123 accelerator_table_ =
125 LoadAccelerators(this_module, 124 LoadAccelerators(this_module,
126 MAKEINTRESOURCE(IDR_CHROME_FRAME_IE_FULL_TAB)); 125 MAKEINTRESOURCE(IDR_CHROME_FRAME_IE_FULL_TAB));
127 DCHECK(accelerator_table_ != NULL); 126 DCHECK(accelerator_table_ != NULL);
127
128 HRESULT hr = security_manager_.CreateInstance(CLSID_InternetSecurityManager);
129 if (FAILED(hr)) {
130 NOTREACHED() << __FUNCTION__
131 << " Failed to create InternetSecurityManager. Error: 0x%x"
132 << hr;
133 }
134
128 return S_OK; 135 return S_OK;
129 } 136 }
130 137
131 ChromeActiveDocument::~ChromeActiveDocument() { 138 ChromeActiveDocument::~ChromeActiveDocument() {
132 DLOG(INFO) << __FUNCTION__; 139 DLOG(INFO) << __FUNCTION__;
133 if (find_dialog_.IsWindow()) 140 if (find_dialog_.IsWindow())
134 find_dialog_.DestroyWindow(); 141 find_dialog_.DestroyWindow();
135 // ChromeFramePlugin 142 // ChromeFramePlugin
136 BaseActiveX::Uninitialize(); 143 BaseActiveX::Uninitialize();
137 144
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 if (info && !info->url().empty()) { 260 if (info && !info->url().empty()) {
254 url = info->url(); 261 url = info->url();
255 } else { 262 } else {
256 // If the original URL contains an anchor, then the URL queried 263 // If the original URL contains an anchor, then the URL queried
257 // from the moniker does not contain the anchor. To workaround 264 // from the moniker does not contain the anchor. To workaround
258 // this we retrieve the URL from our BHO. 265 // this we retrieve the URL from our BHO.
259 url = GetActualUrlFromMoniker(moniker_name, bind_context, 266 url = GetActualUrlFromMoniker(moniker_name, bind_context,
260 mgr ? mgr->url(): std::wstring()); 267 mgr ? mgr->url(): std::wstring());
261 } 268 }
262 269
263 // The is_new_navigation variable indicates if this a navigation initiated 270 ChromeFrameUrl cf_url;
264 // by typing in a URL for e.g. in the IE address bar, or from Chrome by 271 if (!cf_url.Parse(url)) {
265 // a window.open call from javascript, in which case the current IE tab 272 DLOG(WARNING) << __FUNCTION__ << " Failed to parse url:" << url;
266 // will attach to an existing ExternalTabContainer instance. 273 return E_INVALIDARG;
267 bool is_new_navigation = true; 274 }
268 bool is_chrome_protocol = false;
269 275
270 if (!ParseUrl(url, &is_new_navigation, &is_chrome_protocol, &url)) { 276 if (!CanNavigateInFullTabMode(cf_url, security_manager_)) {
271 DLOG(WARNING) << __FUNCTION__ << " Failed to parse url:" << url;
272 return E_INVALIDARG; 277 return E_INVALIDARG;
273 } 278 }
274 279
275 std::string referrer = mgr ? mgr->referrer() : EmptyString(); 280 std::string referrer = mgr ? mgr->referrer() : EmptyString();
276 // With CTransaction patch we have more robust way to grab the referrer for 281 // With CTransaction patch we have more robust way to grab the referrer for
277 // each top-level-switch-to-CF request by peeking at our sniffing data 282 // each top-level-switch-to-CF request by peeking at our sniffing data
278 // object that lives inside the bind context. 283 // object that lives inside the bind context.
279 if (g_patch_helper.state() == PatchHelper::PATCH_PROTOCOL && info) { 284 if (g_patch_helper.state() == PatchHelper::PATCH_PROTOCOL && info) {
280 scoped_refptr<ProtData> prot_data = info->get_prot_data(); 285 scoped_refptr<ProtData> prot_data = info->get_prot_data();
281 if (prot_data) 286 if (prot_data)
282 referrer = prot_data->referrer(); 287 referrer = prot_data->referrer();
283 } 288 }
284 289
285 if (!LaunchUrl(url, referrer, is_new_navigation)) { 290 if (!LaunchUrl(cf_url, referrer)) {
286 NOTREACHED() << __FUNCTION__ << " Failed to launch url:" << url; 291 NOTREACHED() << __FUNCTION__ << " Failed to launch url:" << url;
287 return E_INVALIDARG; 292 return E_INVALIDARG;
288 } 293 }
289 294
290 if (!is_chrome_protocol) 295 if (!cf_url.is_chrome_protocol() && !cf_url.attach_to_external_tab())
291 url_fetcher_.SetInfoForUrl(url, moniker_name, bind_context); 296 url_fetcher_.SetInfoForUrl(cf_url.url(), moniker_name, bind_context);
292 297
293 THREAD_SAFE_UMA_HISTOGRAM_CUSTOM_COUNTS("ChromeFrame.FullTabLaunchType", 298 THREAD_SAFE_UMA_HISTOGRAM_CUSTOM_COUNTS("ChromeFrame.FullTabLaunchType",
294 is_chrome_protocol, 0, 1, 2); 299 cf_url.is_chrome_protocol(),
300 0, 1, 2);
295 return S_OK; 301 return S_OK;
296 } 302 }
297 303
298 STDMETHODIMP ChromeActiveDocument::Save(IMoniker* moniker_name, 304 STDMETHODIMP ChromeActiveDocument::Save(IMoniker* moniker_name,
299 LPBC bind_context, 305 LPBC bind_context,
300 BOOL remember) { 306 BOOL remember) {
301 return E_NOTIMPL; 307 return E_NOTIMPL;
302 } 308 }
303 309
304 STDMETHODIMP ChromeActiveDocument::SaveCompleted(IMoniker* moniker_name, 310 STDMETHODIMP ChromeActiveDocument::SaveCompleted(IMoniker* moniker_name,
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 386
381 stream->Seek(offset, STREAM_SEEK_CUR, &cur_pos); 387 stream->Seek(offset, STREAM_SEEK_CUR, &cur_pos);
382 stream->Stat(&statstg, STATFLAG_NONAME); 388 stream->Stat(&statstg, STATFLAG_NONAME);
383 389
384 DWORD url_size = statstg.cbSize.LowPart - cur_pos.LowPart; 390 DWORD url_size = statstg.cbSize.LowPart - cur_pos.LowPart;
385 ScopedBstr url_bstr; 391 ScopedBstr url_bstr;
386 DWORD bytes_read = 0; 392 DWORD bytes_read = 0;
387 stream->Read(url_bstr.AllocateBytes(url_size), url_size, &bytes_read); 393 stream->Read(url_bstr.AllocateBytes(url_size), url_size, &bytes_read);
388 std::wstring url(url_bstr); 394 std::wstring url(url_bstr);
389 395
390 bool is_new_navigation = true; 396 ChromeFrameUrl cf_url;
391 bool is_chrome_protocol = false; 397 if (!cf_url.Parse(url)) {
392
393 if (!ParseUrl(url, &is_new_navigation, &is_chrome_protocol, &url)) {
394 DLOG(WARNING) << __FUNCTION__ << " Failed to parse url:" << url; 398 DLOG(WARNING) << __FUNCTION__ << " Failed to parse url:" << url;
395 return E_INVALIDARG; 399 return E_INVALIDARG;
396 } 400 }
397 401
402 if (!CanNavigateInFullTabMode(cf_url, security_manager_)) {
403 return E_INVALIDARG;
404 }
405
398 const std::string& referrer = EmptyString(); 406 const std::string& referrer = EmptyString();
399 if (!LaunchUrl(url, referrer, is_new_navigation)) { 407 if (!LaunchUrl(cf_url, referrer)) {
400 NOTREACHED() << __FUNCTION__ << " Failed to launch url:" << url; 408 NOTREACHED() << __FUNCTION__ << " Failed to launch url:" << url;
401 return E_INVALIDARG; 409 return E_INVALIDARG;
402 } 410 }
403 return S_OK; 411 return S_OK;
404 } 412 }
405 413
406 STDMETHODIMP ChromeActiveDocument::SaveHistory(IStream* stream) { 414 STDMETHODIMP ChromeActiveDocument::SaveHistory(IStream* stream) {
407 // TODO(sanjeevr): We need to fetch the entire list of navigation entries 415 // TODO(sanjeevr): We need to fetch the entire list of navigation entries
408 // from Chrome and persist it in the stream. And in LoadHistory we need to 416 // from Chrome and persist it in the stream. And in LoadHistory we need to
409 // pass this list back to Chrome which will recreate the list. This will allow 417 // pass this list back to Chrome which will recreate the list. This will allow
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 730
723 // Another case where we need to issue BeforeNavigate2 calls is as below:- 731 // Another case where we need to issue BeforeNavigate2 calls is as below:-
724 // We get notified after the fact, when navigations are initiated within 732 // We get notified after the fact, when navigations are initiated within
725 // Chrome via window.open calls. These navigations are handled by creating 733 // Chrome via window.open calls. These navigations are handled by creating
726 // an external tab container within chrome and then connecting to it from IE. 734 // an external tab container within chrome and then connecting to it from IE.
727 // We still want to update the address bar/history, etc, to ensure that 735 // We still want to update the address bar/history, etc, to ensure that
728 // the special URL used by Chrome to indicate this is updated correctly. 736 // the special URL used by Chrome to indicate this is updated correctly.
729 bool is_internal_navigation = ((new_navigation_info.navigation_index > 0) && 737 bool is_internal_navigation = ((new_navigation_info.navigation_index > 0) &&
730 (new_navigation_info.navigation_index != 738 (new_navigation_info.navigation_index !=
731 navigation_info_.navigation_index)) || 739 navigation_info_.navigation_index)) ||
732 StartsWith(static_cast<BSTR>(url_), kChromeAttachExternalTabPrefix, 740 MatchPatternWide(static_cast<BSTR>(url_), kChromeFrameAttachTabPattern);
733 false);
734 741
735 if (new_navigation_info.url.is_valid()) 742 if (new_navigation_info.url.is_valid())
736 url_.Allocate(UTF8ToWide(new_navigation_info.url.spec()).c_str()); 743 url_.Allocate(UTF8ToWide(new_navigation_info.url.spec()).c_str());
737 744
738 if (is_internal_navigation) { 745 if (is_internal_navigation) {
739 ScopedComPtr<IDocObjectService> doc_object_svc; 746 ScopedComPtr<IDocObjectService> doc_object_svc;
740 ScopedComPtr<IWebBrowserEventsService> web_browser_events_svc; 747 ScopedComPtr<IWebBrowserEventsService> web_browser_events_svc;
741 748
742 buggy_bho::BuggyBhoTls bad_bho_tls; 749 buggy_bho::BuggyBhoTls bad_bho_tls;
743 if (GetConfigBool(true, kEnableBuggyBhoIntercept)) { 750 if (GetConfigBool(true, kEnableBuggyBhoIntercept)) {
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 hr = frame_cmd_target.QueryFrom(in_place_site); 950 hr = frame_cmd_target.QueryFrom(in_place_site);
944 951
945 if (frame_cmd_target) { 952 if (frame_cmd_target) {
946 hr = frame_cmd_target->Exec(cmd_group_guid, command_id, cmd_exec_opt, 953 hr = frame_cmd_target->Exec(cmd_group_guid, command_id, cmd_exec_opt,
947 in_args, out_args); 954 in_args, out_args);
948 } 955 }
949 956
950 return hr; 957 return hr;
951 } 958 }
952 959
953 DWORD ChromeActiveDocument::MapUrlToZone(const wchar_t* url) { 960 bool ChromeActiveDocument::LaunchUrl(const ChromeFrameUrl& cf_url,
954 DWORD zone = URLZONE_INVALID; 961 const std::string& referrer) {
955 if (security_manager_.get() == NULL) { 962 DCHECK(automation_client_.get() != NULL);
956 HRESULT hr = CoCreateInstance( 963 DCHECK(!cf_url.url().empty());
957 CLSID_InternetSecurityManager,
958 NULL,
959 CLSCTX_ALL,
960 IID_IInternetSecurityManager,
961 reinterpret_cast<void**>(security_manager_.Receive()));
962 964
963 if (FAILED(hr)) { 965 url_.Allocate(cf_url.url().c_str());
964 NOTREACHED() << __FUNCTION__
965 << " Failed to create InternetSecurityManager. Error: 0x%x"
966 << hr;
967 return zone;
968 }
969 }
970 966
971 security_manager_->MapUrlToZone(url, &zone, 0); 967 std::string utf8_url;
972 return zone; 968 WideToUTF8(url_, url_.Length(), &utf8_url);
973 }
974 969
975 bool ChromeActiveDocument::ParseUrl(const std::wstring& url, 970 DLOG(INFO) << "Url is " << url_;
976 bool* is_new_navigation, 971
977 bool* is_chrome_protocol, 972 // Initiate navigation before launching chrome so that the url will be
978 std::wstring* parsed_url) { 973 // cached and sent with launch settings.
979 if (!is_new_navigation || !is_chrome_protocol|| !parsed_url) { 974 if (cf_url.attach_to_external_tab()) {
980 NOTREACHED() << __FUNCTION__ << " Invalid arguments"; 975 dimensions_ = cf_url.dimensions();
976 automation_client_->AttachExternalTab(cf_url.cookie());
977 } else if (!automation_client_->InitiateNavigation(utf8_url,
978 referrer,
979 is_privileged_)) {
980 DLOG(ERROR) << "Invalid URL: " << url_;
981 Error(L"Invalid URL");
982 url_.Reset();
981 return false; 983 return false;
982 } 984 }
983 985
984 std::wstring initial_url = url;
985
986 *is_chrome_protocol = StartsWith(initial_url, kChromeProtocolPrefix,
987 false);
988
989 *is_new_navigation = true;
990
991 if (*is_chrome_protocol) {
992 initial_url.erase(0, lstrlen(kChromeProtocolPrefix));
993 *is_new_navigation =
994 !StartsWith(initial_url, kChromeAttachExternalTabPrefix, false);
995 }
996
997 if (!IsValidUrlScheme(initial_url, is_privileged_)) {
998 DLOG(WARNING) << __FUNCTION__ << " Disallowing navigation to url: "
999 << url;
1000 return false;
1001 }
1002
1003 if (URLZONE_UNTRUSTED == MapUrlToZone(initial_url.c_str())) {
1004 DLOG(WARNING) << __FUNCTION__
1005 << " Disallowing navigation to restricted url: "
1006 << initial_url;
1007 return false;
1008 }
1009
1010 if (*is_chrome_protocol) {
1011 // Allow chrome protocol (gcf:) if -
1012 // - explicitly enabled using registry
1013 // - for gcf:attach_external_tab
1014 // - for gcf:about and gcf:view-source
1015 GURL crack_url(initial_url);
1016 bool allow_gcf_protocol = !*is_new_navigation ||
1017 GetConfigBool(false, kEnableGCFProtocol) ||
1018 crack_url.SchemeIs(chrome::kAboutScheme) ||
1019 crack_url.SchemeIs(chrome::kViewSourceScheme);
1020 if (!allow_gcf_protocol)
1021 return false;
1022 }
1023
1024 *parsed_url = initial_url;
1025 return true;
1026 }
1027
1028 bool ChromeActiveDocument::LaunchUrl(const std::wstring& url,
1029 const std::string& referrer,
1030 bool is_new_navigation) {
1031 DCHECK(automation_client_.get() != NULL);
1032
1033 url_.Allocate(url.c_str());
1034
1035 std::string utf8_url;
1036
1037 if (!is_new_navigation) {
1038 int disposition = 0;
1039 uint64 external_tab_cookie = 0;
1040
1041 if (!ParseAttachExternalTabUrl(url, &external_tab_cookie, &dimensions_,
1042 &disposition)) {
1043 NOTREACHED() << "Failed to parse attach tab url:" << url;
1044 return false;
1045 }
1046
1047 if (external_tab_cookie == 0) {
1048 NOTREACHED() << "invalid url for attach tab: " << url;
1049 return false;
1050 }
1051
1052 is_new_navigation_ = false;
1053 automation_client_->AttachExternalTab(external_tab_cookie);
1054 } else {
1055 is_new_navigation_ = true;
1056 // Initiate navigation before launching chrome so that the url will be
1057 // cached and sent with launch settings.
1058 if (url_.Length()) {
1059 WideToUTF8(url_, url_.Length(), &utf8_url);
1060 if (!automation_client_->InitiateNavigation(utf8_url,
1061 referrer,
1062 is_privileged_)) {
1063 DLOG(ERROR) << "Invalid URL: " << url;
1064 Error(L"Invalid URL");
1065 url_.Reset();
1066 return false;
1067 }
1068
1069 DLOG(INFO) << "Url is " << url_;
1070 }
1071 }
1072
1073 if (is_automation_client_reused_) 986 if (is_automation_client_reused_)
1074 return true; 987 return true;
1075 988
1076 automation_client_->SetUrlFetcher(&url_fetcher_); 989 automation_client_->SetUrlFetcher(&url_fetcher_);
1077 990
1078 return InitializeAutomation(GetHostProcessName(false), L"", IsIEInPrivate(), 991 return InitializeAutomation(GetHostProcessName(false), L"", IsIEInPrivate(),
1079 false, GURL(utf8_url), GURL(referrer)); 992 false, GURL(utf8_url), GURL(referrer));
1080 } 993 }
1081 994
1082 995
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 SetFocus(); 1206 SetFocus();
1294 return 0; 1207 return 0;
1295 } 1208 }
1296 1209
1297 LRESULT ChromeActiveDocument::OnSetFocus(UINT message, WPARAM wparam, 1210 LRESULT ChromeActiveDocument::OnSetFocus(UINT message, WPARAM wparam,
1298 LPARAM lparam, 1211 LPARAM lparam,
1299 BOOL& handled) { // NO_LINT 1212 BOOL& handled) { // NO_LINT
1300 GiveFocusToChrome(false); 1213 GiveFocusToChrome(false);
1301 return 0; 1214 return 0;
1302 } 1215 }
OLDNEW
« no previous file with comments | « chrome_frame/chrome_active_document.h ('k') | chrome_frame/chrome_frame_activex_base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698