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

Unified Diff: chrome/browser/download/download_request_limiter.cc

Issue 10412061: Fix crashes in DownloadRequestLimiter when extension popups/bubbles initiate downloads automatically (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/download/download_request_limiter.cc
diff --git a/chrome/browser/download/download_request_limiter.cc b/chrome/browser/download/download_request_limiter.cc
index 91bb6cbc37578e3c8febf9371fe8b400e8b9988a..f1bbf55132ee3501058a2787936bfed03d24ea3f 100644
--- a/chrome/browser/download/download_request_limiter.cc
+++ b/chrome/browser/download/download_request_limiter.cc
@@ -84,9 +84,20 @@ void DownloadRequestLimiter::TabDownloadState::PromptUserForDownload(
if (DownloadRequestLimiter::delegate_) {
NotifyCallbacks(DownloadRequestLimiter::delegate_->ShouldAllowDownload());
} else {
- InfoBarTabHelper* infobar_helper =
- TabContentsWrapper::GetCurrentWrapperForContents(tab)->
- infobar_tab_helper();
+ TabContentsWrapper* tab_wrapper =
+ TabContentsWrapper::GetCurrentWrapperForContents(tab);
+ if (!tab_wrapper) {
Randy Smith (Not in Mondays) 2012/05/23 21:57:54 A sentence or two aside from the TODOs indicating
benjhayden 2012/05/24 20:43:39 Done.
+ // TODO(benjhayden): There's a bug in chromium where OnUserGesture() is
+ // not being called for successive clicks/downloads.
+ // TODO(benjhayden): If this is an automatic download from an extension,
+ // send a message to the extension's DevTools console (as we do for CSP)
+ // about how extensions should use chrome.downloads.download() to
+ // automatically download multiple files. This method requires the
+ // "downloads" permission.
+ Cancel();
+ return;
+ }
+ InfoBarTabHelper* infobar_helper = tab_wrapper->infobar_tab_helper();
infobar_ = new DownloadRequestInfoBarDelegate(infobar_helper, this);
infobar_helper->AddInfoBar(infobar_);
}
@@ -211,7 +222,8 @@ DownloadRequestLimiter::~DownloadRequestLimiter() {
DownloadRequestLimiter::DownloadStatus
DownloadRequestLimiter::GetDownloadStatus(WebContents* tab) {
- TabDownloadState* state = GetDownloadState(&tab->GetController(), NULL, false);
+ TabDownloadState* state =
+ GetDownloadState(&tab->GetController(), NULL, false);
return state ? state->download_status() : ALLOW_ONE_DOWNLOAD;
}
@@ -232,8 +244,8 @@ void DownloadRequestLimiter::CanDownloadOnIOThread(
}
void DownloadRequestLimiter::OnUserGesture(WebContents* tab) {
- TabDownloadState* state =
- GetDownloadState(&tab->GetController(), NULL, false);
+ TabDownloadState* state = GetDownloadState(
+ &tab->GetController(), NULL, false);
if (!state)
return;
@@ -245,10 +257,11 @@ void DownloadRequestLimiter::SetTestingDelegate(TestingDelegate* delegate) {
delegate_ = delegate;
}
-DownloadRequestLimiter::TabDownloadState* DownloadRequestLimiter::
- GetDownloadState(NavigationController* controller,
- NavigationController* originating_controller,
- bool create) {
+DownloadRequestLimiter::TabDownloadState*
+DownloadRequestLimiter::GetDownloadState(
+ NavigationController* controller,
+ NavigationController* originating_controller,
+ bool create) {
DCHECK(controller);
StateMap::iterator i = state_map_.find(controller);
if (i != state_map_.end())
@@ -270,49 +283,55 @@ void DownloadRequestLimiter::CanDownload(int render_process_host_id,
const Callback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- WebContents* originating_tab =
+ WebContents* originating_contents =
tab_util::GetWebContentsByID(render_process_host_id, render_view_id);
- if (!originating_tab) {
+ if (!originating_contents) {
// The tab was closed, don't allow the download.
ScheduleNotification(callback, false);
return;
}
CanDownloadImpl(
- TabContentsWrapper::GetCurrentWrapperForContents(originating_tab),
+ originating_contents,
request_id,
request_method,
callback);
}
-void DownloadRequestLimiter::CanDownloadImpl(
- TabContentsWrapper* originating_tab,
- int request_id,
- const std::string& request_method,
- const Callback& callback) {
- DCHECK(originating_tab);
+void DownloadRequestLimiter::CanDownloadImpl(WebContents* originating_contents,
+ int request_id,
+ const std::string& request_method,
+ const Callback& callback) {
+ DCHECK(originating_contents);
// FYI: Chrome Frame overrides CanDownload in ExternalTabContainer in order
// to cancel the download operation in chrome and let the host browser
// take care of it.
- WebContents* tab = originating_tab->web_contents();
- if (tab->GetDelegate() && !tab->GetDelegate()->CanDownload(
- tab->GetRenderViewHost(), request_id, request_method)) {
+ if (originating_contents->GetDelegate() &&
+ !originating_contents->GetDelegate()->CanDownload(
+ originating_contents->GetRenderViewHost(),
+ request_id,
+ request_method)) {
ScheduleNotification(callback, false);
return;
}
// If the tab requesting the download is a constrained popup that is not
// shown, treat the request as if it came from the parent.
- TabContentsWrapper* effective_wrapper = originating_tab;
- if (effective_wrapper->blocked_content_tab_helper()->delegate()) {
- effective_wrapper = effective_wrapper->blocked_content_tab_helper()->
- delegate()->GetConstrainingContentsWrapper(effective_wrapper);
+ WebContents* effective_contents = originating_contents;
+ TabContentsWrapper* originating_wrapper =
+ TabContentsWrapper::GetCurrentWrapperForContents(originating_contents);
+ if (originating_wrapper &&
+ originating_wrapper->blocked_content_tab_helper()->delegate()) {
+ effective_contents = originating_wrapper->blocked_content_tab_helper()->
+ delegate()->GetConstrainingContentsWrapper(originating_wrapper)->
+ web_contents();
}
TabDownloadState* state = GetDownloadState(
- &effective_wrapper->web_contents()->GetController(),
- &tab->GetController(), true);
+ &effective_contents->GetController(),
+ &originating_contents->GetController(),
+ true);
switch (state->download_status()) {
case ALLOW_ALL_DOWNLOADS:
if (state->download_count() && !(state->download_count() %
@@ -332,7 +351,7 @@ void DownloadRequestLimiter::CanDownloadImpl(
break;
case PROMPT_BEFORE_DOWNLOAD:
- state->PromptUserForDownload(effective_wrapper->web_contents(), callback);
+ state->PromptUserForDownload(effective_contents, callback);
state->increment_download_count();
break;

Powered by Google App Engine
This is Rietveld 408576698