diff options
author | amit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-13 20:21:08 +0000 |
---|---|---|
committer | amit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-13 20:21:08 +0000 |
commit | f1917ed6945d79a12fe45957c46584dfe8771dbb (patch) | |
tree | 9a28a5d9ac41ef81984b5b61a552157d9291f728 /chrome_frame | |
parent | 3368b54748ed06d61ddc35f0cce4190961ec950c (diff) | |
download | chromium_src-f1917ed6945d79a12fe45957c46584dfe8771dbb.zip chromium_src-f1917ed6945d79a12fe45957c46584dfe8771dbb.tar.gz chromium_src-f1917ed6945d79a12fe45957c46584dfe8771dbb.tar.bz2 |
Fix crash in CacheStream::Read
Fix incorrect assumption that the Read of CacheStream will happen
in the context of IBindStatusCallback::OnDataAvailable notification.
TEST=none
BUG=43949
Review URL: http://codereview.chromium.org/2007009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47184 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r-- | chrome_frame/urlmon_bind_status_callback.cc | 29 | ||||
-rw-r--r-- | chrome_frame/urlmon_bind_status_callback.h | 4 |
2 files changed, 23 insertions, 10 deletions
diff --git a/chrome_frame/urlmon_bind_status_callback.cc b/chrome_frame/urlmon_bind_status_callback.cc index b6d7c15..1f39a08 100644 --- a/chrome_frame/urlmon_bind_status_callback.cc +++ b/chrome_frame/urlmon_bind_status_callback.cc @@ -36,8 +36,10 @@ HRESULT CacheStream::BSCBFeedData(IBindStatusCallback* bscb, const char* data, return hr; } - cache_stream->AddRef(); - cache_stream->Initialize(data, size, eof); + scoped_refptr<CacheStream> cache_ref = cache_stream; + hr = cache_stream->Initialize(data, size, eof); + if (FAILED(hr)) + return hr; FORMATETC format_etc = { clip_format, NULL, DVASPECT_CONTENT, -1, TYMED_ISTREAM }; @@ -46,16 +48,24 @@ HRESULT CacheStream::BSCBFeedData(IBindStatusCallback* bscb, const char* data, medium.pstm = cache_stream; hr = bscb->OnDataAvailable(flags, size, &format_etc, &medium); - - cache_stream->Release(); return hr; } -void CacheStream::Initialize(const char* cache, size_t size, bool eof) { - cache_ = cache; - size_ = size; +HRESULT CacheStream::Initialize(const char* cache, size_t size, bool eof) { position_ = 0; eof_ = eof; + + HRESULT hr = S_OK; + cache_.reset(new char[size]); + if (cache_.get()) { + memcpy(cache_.get(), cache, size); + size_ = size; + } else { + DLOG(ERROR) << "failed to allocate cache stream."; + hr = E_OUTOFMEMORY; + } + + return hr; } // Read is the only call that we expect. Return E_PENDING if there @@ -65,11 +75,14 @@ STDMETHODIMP CacheStream::Read(void* pv, ULONG cb, ULONG* read) { if (!pv || !read) return E_INVALIDARG; + if (!cache_.get()) + return E_FAIL; + // Default to E_PENDING to signal that this is a partial data. HRESULT hr = eof_ ? S_FALSE : E_PENDING; if (position_ < size_) { *read = std::min(size_ - position_, size_t(cb)); - memcpy(pv, cache_ + position_, *read); + memcpy(pv, cache_ .get() + position_, *read); position_ += *read; hr = S_OK; } diff --git a/chrome_frame/urlmon_bind_status_callback.h b/chrome_frame/urlmon_bind_status_callback.h index 33e5a51..484bef3 100644 --- a/chrome_frame/urlmon_bind_status_callback.h +++ b/chrome_frame/urlmon_bind_status_callback.h @@ -23,7 +23,7 @@ class CacheStream : public CComObjectRoot, public StreamImpl { CacheStream() : cache_(NULL), size_(0), position_(0), eof_(false) { } - void Initialize(const char* cache, size_t size, bool eof); + HRESULT Initialize(const char* cache, size_t size, bool eof); static HRESULT BSCBFeedData(IBindStatusCallback* bscb, const char* data, size_t size, CLIPFORMAT clip_format, size_t flags, bool eof); @@ -32,7 +32,7 @@ class CacheStream : public CComObjectRoot, public StreamImpl { STDMETHOD(Read)(void* pv, ULONG cb, ULONG* read); protected: - const char* cache_; + scoped_ptr<char> cache_; size_t size_; size_t position_; bool eof_; |