diff options
author | brettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-07 16:13:31 +0000 |
---|---|---|
committer | brettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-07 16:13:31 +0000 |
commit | e79f10f3a37828e770dc3cfdbc0aa84eb0a07c9d (patch) | |
tree | db108c4df95c7c4f1f10d9b31d3a2b68462d8360 /chrome | |
parent | 65fabb5884a6087fb01030269ae8ee514191c1aa (diff) | |
download | chromium_src-e79f10f3a37828e770dc3cfdbc0aa84eb0a07c9d.zip chromium_src-e79f10f3a37828e770dc3cfdbc0aa84eb0a07c9d.tar.gz chromium_src-e79f10f3a37828e770dc3cfdbc0aa84eb0a07c9d.tar.bz2 |
Fix crash in the icon manager. The decoding could be NULL, which would then get
dereferenced in specific cases. We would have to create the failed icon twice,
so that it would think the icon was already in the cache, when in fact a NULL
value was being cached.
BUG=1259695
Review URL: http://codereview.chromium.org/9672
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4988 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/icon_manager.cc | 4 | ||||
-rw-r--r-- | chrome/browser/icon_manager.h | 2 | ||||
-rw-r--r-- | chrome/browser/views/download_item_view.cc | 8 |
3 files changed, 12 insertions, 2 deletions
diff --git a/chrome/browser/icon_manager.cc b/chrome/browser/icon_manager.cc index 8107877..59632e2 100644 --- a/chrome/browser/icon_manager.cc +++ b/chrome/browser/icon_manager.cc @@ -70,9 +70,11 @@ bool IconManager::OnSkBitmapLoaded(IconLoader* source, SkBitmap* result) { return false; // Return false to indicate result should be deleted. } + // Cache the bitmap. Watch out: |result| or the cached bitmap may be NULL to + // indicate a current or past failure. CacheKey key(client_request.file_name, client_request.size); IconMap::iterator it = icon_cache_.find(key); - if (it != icon_cache_.end()) { + if (it != icon_cache_.end() && result && it->second) { it->second->swap(*result); delete result; result = it->second; diff --git a/chrome/browser/icon_manager.h b/chrome/browser/icon_manager.h index ad6a4eb..6840ac1 100644 --- a/chrome/browser/icon_manager.h +++ b/chrome/browser/icon_manager.h @@ -70,6 +70,8 @@ public: // work is done on the file thread, with the callbacks running on the UI // thread. The return value is the 'request_id' that will be passed to the // client in the callback. + // + // WATCH OUT: The returned bitmap pointer may be NULL if decoding failed. typedef CancelableRequestProvider::Handle Handle; typedef Callback2<Handle, SkBitmap*>::Type IconRequestCallback; diff --git a/chrome/browser/views/download_item_view.cc b/chrome/browser/views/download_item_view.cc index 60a13f5..ab21fe2 100644 --- a/chrome/browser/views/download_item_view.cc +++ b/chrome/browser/views/download_item_view.cc @@ -489,6 +489,11 @@ void DownloadItemView::Paint(ChromeCanvas* canvas) { SkBitmap* icon = IsDangerousMode() ? warning_icon_ : im->LookupIcon(download_->full_path(), IconLoader::SMALL); + // We count on the fact that the icon manager will cache the icons and if one + // is available, it will be cached here. We *don't* want to request the icon + // to be loaded here, since this will also get called if the icon can't be + // loaded, in which case LookupIcon will always be NULL. The loading will be + // triggered only when we think the status might change. if (icon) { if (!IsDangerousMode()) { if (download_->state() == DownloadItem::IN_PROGRESS) { @@ -739,7 +744,8 @@ void DownloadItemView::OpenDownload() { void DownloadItemView::OnExtractIconComplete(IconManager::Handle handle, SkBitmap* icon_bitmap) { - GetParent()->SchedulePaint(); + if (icon_bitmap) + GetParent()->SchedulePaint(); } void DownloadItemView::LoadIcon() { |