summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoramit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-14 18:51:02 +0000
committeramit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-14 18:51:02 +0000
commitb758c0bb4d763195fb3046fc3ed7fd5cb9cd484f (patch)
tree6f852b220b4238fe2e2a6b2743594f9eacd283e6
parentf5e8263ebe4dfc62aa57833564fddf2a8eb04d73 (diff)
downloadchromium_src-b758c0bb4d763195fb3046fc3ed7fd5cb9cd484f.zip
chromium_src-b758c0bb4d763195fb3046fc3ed7fd5cb9cd484f.tar.gz
chromium_src-b758c0bb4d763195fb3046fc3ed7fd5cb9cd484f.tar.bz2
Merge 47184 - 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 TBR=amit@chromium.org Review URL: http://codereview.chromium.org/2091006 git-svn-id: svn://svn.chromium.org/chrome/branches/375/src@47288 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome_frame/urlmon_bind_status_callback.cc29
-rw-r--r--chrome_frame/urlmon_bind_status_callback.h4
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 0444c86..07baab5 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_;