Index: chrome_frame/utils.cc |
=================================================================== |
--- chrome_frame/utils.cc (revision 53833) |
+++ chrome_frame/utils.cc (working copy) |
@@ -43,6 +43,7 @@ |
const wchar_t kChromeProtocolPrefix[] = L"gcf:"; |
const wchar_t kChromeMimeType[] = L"application/chromepage"; |
const wchar_t kPatchProtocols[] = L"PatchProtocols"; |
+const wchar_t kChromeFrameAttachTabPattern[] = L"*?attach_external_tab&*"; |
static const wchar_t kChromeFrameConfigKey[] = |
L"Software\\Google\\ChromeFrame"; |
@@ -58,7 +59,7 @@ |
const wchar_t kChromeFrameOmahaSuffix[] = L"-cf"; |
const wchar_t kDevChannelName[] = L"-dev"; |
-const wchar_t kChromeAttachExternalTabPrefix[] = L"attach_external_tab"; |
+const wchar_t kChromeAttachExternalTabPrefix[] = L"?attach_external_tab"; |
// Indicates that we are running in a test environment, where execptions, etc |
// are handled by the chrome test crash server. |
@@ -858,9 +859,6 @@ |
crack_url.SchemeIs(chrome::kExtensionScheme))) |
return true; |
- if (StartsWith(url, kChromeAttachExternalTabPrefix, false)) |
- return true; |
- |
return false; |
} |
@@ -1238,21 +1236,52 @@ |
return hr; |
} |
-bool ParseAttachExternalTabUrl(const std::wstring& url, uint64* cookie, |
- gfx::Rect* dimensions, int* disposition) { |
- if (!StartsWith(url, kChromeAttachExternalTabPrefix, true)) { |
- DLOG(WARNING) << "Invalid url passed in:" |
- << url.c_str(); |
- return false; |
+ChromeFrameUrl::ChromeFrameUrl() |
+ : is_chrome_protocol_(false), |
+ attach_to_external_tab_(false), |
+ cookie_(0), |
+ disposition_(0) { |
+} |
+ |
+bool ChromeFrameUrl::Parse(const std::wstring& url) { |
+ bool ret = false; |
+ if (url.empty()) |
+ return ret; |
+ |
+ url_ = url; |
+ |
+ attach_to_external_tab_ = MatchPatternWide(url.c_str(), |
+ kChromeFrameAttachTabPattern); |
+ is_chrome_protocol_ = StartsWith(url, kChromeProtocolPrefix, |
+ false); |
+ DCHECK(!(attach_to_external_tab_ && is_chrome_protocol_)); |
+ if (is_chrome_protocol_) { |
+ url_.erase(0, lstrlen(kChromeProtocolPrefix)); |
} |
- if (!cookie || !dimensions || !disposition) |
+ if (attach_to_external_tab_) { |
+ ret = ParseAttachExternalTabUrl(); |
+ } else { |
+ ret = true; |
+ } |
+ return ret; |
+} |
+ |
+bool ChromeFrameUrl::ParseAttachExternalTabUrl() { |
+ size_t attach_external_tab_start_pos = |
+ url_.find(kChromeAttachExternalTabPrefix); |
+ if (attach_external_tab_start_pos == std::wstring::npos) { |
+ NOTREACHED() << "Invalid url:" << url_; |
return false; |
+ } |
+ std::wstring url = |
+ url_.substr(attach_external_tab_start_pos, |
+ url_.length() - attach_external_tab_start_pos); |
+ |
WStringTokenizer tokenizer(url, L"&"); |
// Skip over kChromeAttachExternalTabPrefix |
tokenizer.GetNext(); |
- |
// Read the following items in order. |
// 1. cookie |
// 2. disposition |
@@ -1262,41 +1291,81 @@ |
// 6. dimension.height. |
if (tokenizer.GetNext()) { |
wchar_t* end_ptr = 0; |
- *cookie = _wcstoui64(tokenizer.token().c_str(), &end_ptr, 10); |
+ cookie_ = _wcstoui64(tokenizer.token().c_str(), &end_ptr, 10); |
} else { |
return false; |
} |
if (tokenizer.GetNext()) { |
- *disposition = _wtoi(tokenizer.token().c_str()); |
+ disposition_ = _wtoi(tokenizer.token().c_str()); |
} else { |
return false; |
} |
if (tokenizer.GetNext()) { |
- dimensions->set_x(_wtoi(tokenizer.token().c_str())); |
+ dimensions_.set_x(_wtoi(tokenizer.token().c_str())); |
} else { |
return false; |
} |
if (tokenizer.GetNext()) { |
- dimensions->set_y(_wtoi(tokenizer.token().c_str())); |
+ dimensions_.set_y(_wtoi(tokenizer.token().c_str())); |
} else { |
return false; |
} |
if (tokenizer.GetNext()) { |
- dimensions->set_width(_wtoi(tokenizer.token().c_str())); |
+ dimensions_.set_width(_wtoi(tokenizer.token().c_str())); |
} else { |
return false; |
} |
if (tokenizer.GetNext()) { |
- dimensions->set_height(_wtoi(tokenizer.token().c_str())); |
+ dimensions_.set_height(_wtoi(tokenizer.token().c_str())); |
} else { |
return false; |
} |
+ return true; |
+} |
+bool CanNavigateInFullTabMode(const ChromeFrameUrl& cf_url, |
+ IInternetSecurityManager* security_manager) { |
+ bool is_privileged = false; |
+ |
+ if (!IsValidUrlScheme(cf_url.url(), is_privileged)) { |
+ DLOG(WARNING) << __FUNCTION__ << " Disallowing navigation to url: " |
+ << cf_url.url(); |
+ return false; |
+ } |
+ |
+ if (security_manager) { |
+ DWORD zone = URLZONE_INVALID; |
+ security_manager->MapUrlToZone(cf_url.url().c_str(), &zone, 0); |
+ if (zone == URLZONE_UNTRUSTED) { |
+ DLOG(WARNING) << __FUNCTION__ |
+ << " Disallowing navigation to restricted url: " |
+ << cf_url.url(); |
+ return false; |
+ } |
+ } |
+ |
+ if (cf_url.is_chrome_protocol()) { |
+ // Allow chrome protocol (gcf:) if - |
+ // - explicitly enabled using registry |
+ // - for gcf:attach_external_tab |
+ // - for gcf:about and gcf:view-source |
+ GURL crack_url(cf_url.url()); |
+ bool allow_gcf_protocol = |
+ GetConfigBool(false, kEnableGCFProtocol) || |
+ crack_url.SchemeIs(chrome::kAboutScheme) || |
+ crack_url.SchemeIs(chrome::kViewSourceScheme); |
+ if (!allow_gcf_protocol) { |
+ DLOG(WARNING) << __FUNCTION__ |
+ << " Disallowing navigation to gcf url: " |
+ << cf_url.url(); |
+ return false; |
+ } |
+ } |
+ |
return true; |
} |
- |