diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-02 17:10:57 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-02 17:10:57 +0000 |
commit | 5aef0faed81f398c426a245d5c9828e39679d3a7 (patch) | |
tree | 52e6f3df896eda04fcc120e30e1750a1e94c2dae /chrome_frame/protocol_sink_wrap.cc | |
parent | c32d6697f54f96a4483301232870b5ec15d14e7c (diff) | |
download | chromium_src-5aef0faed81f398c426a245d5c9828e39679d3a7.zip chromium_src-5aef0faed81f398c426a245d5c9828e39679d3a7.tar.gz chromium_src-5aef0faed81f398c426a245d5c9828e39679d3a7.tar.bz2 |
Fix a crash in ChromeFrame full tab mode while processing the attach external tab request, which comes in during window open.
We create a ProtData object instance which is mapped to the protocol with a NULL read function pointer which was used to indicate
if this is a dummy request. It appears that there are cases where we may receive a StartEx call with a reused protocol pointer.
which basically causes a crash in the context of IInternetProtocolSink::ReportData which internally calls IInternetProtocol::LockRequest,
which crashes as the transaction never started.
Fix is to invalidate the protdata mapping if the protdata has not been destroyed yet, but the underlying Transaction has been destroyed.
This can happen if the original bind context has not yet been destroyed
Fixes bug http://code.google.com/p/chromium/issues/detail?id=50814
Bug=50814,50956
Test=Subsequent CL.
Review URL: http://codereview.chromium.org/3078010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54553 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/protocol_sink_wrap.cc')
-rw-r--r-- | chrome_frame/protocol_sink_wrap.cc | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/chrome_frame/protocol_sink_wrap.cc b/chrome_frame/protocol_sink_wrap.cc index 330e300..0c9a4ea 100644 --- a/chrome_frame/protocol_sink_wrap.cc +++ b/chrome_frame/protocol_sink_wrap.cc @@ -224,6 +224,15 @@ bool IsCFRequest(IBindCtx* pbc) { return false; } +bool HasProtData(IBindCtx* pbc) { + ScopedComPtr<BindContextInfo> info; + BindContextInfo::FromBindContext(pbc, info.Receive()); + bool result = false; + if (info) + result = info->has_prot_data(); + return result; +} + void PutProtData(IBindCtx* pbc, ProtData* data) { // AddRef and Release to avoid a potential leak of a ProtData instance if // FromBindContext fails. @@ -317,11 +326,7 @@ ProtData::ProtData(IInternetProtocol* protocol, ProtData::~ProtData() { DLOG(INFO) << __FUNCTION__ << " " << this; - - // Remove from map. - AutoLock lock(datamap_lock_); - DCHECK(datamap_.end() != datamap_.find(protocol_)); - datamap_.erase(protocol_); + Invalidate(); } HRESULT ProtData::Read(void* buffer, ULONG size, ULONG* size_read) { @@ -541,6 +546,16 @@ scoped_refptr<ProtData> ProtData::DataFromProtocol( return instance; } +void ProtData::Invalidate() { + if (protocol_) { + // Remove from map. + AutoLock lock(datamap_lock_); + DCHECK(datamap_.end() != datamap_.find(protocol_)); + datamap_.erase(protocol_); + protocol_ = NULL; + } +} + // This function looks for the url pattern indicating that this request needs // to be forced into chrome frame. // This hack is required because window.open requests from Chrome don't have @@ -590,6 +605,12 @@ STDMETHODIMP Hook_Start(InternetProtocol_Start_Fn orig_start, return orig_start(protocol, url, prot_sink, bind_info, flags, reserved); } + scoped_refptr<ProtData> prot_data = ProtData::DataFromProtocol(protocol); + if (prot_data && !HasProtData(bind_ctx)) { + prot_data->Invalidate(); + prot_data = NULL; + } + if (HandleAttachToExistingExternalTab(url, protocol, prot_sink, bind_ctx)) { return S_OK; } @@ -598,7 +619,6 @@ STDMETHODIMP Hook_Start(InternetProtocol_Start_Fn orig_start, return orig_start(protocol, url, prot_sink, bind_info, flags, reserved); } - scoped_refptr<ProtData> prot_data = ProtData::DataFromProtocol(protocol); if (prot_data) { DLOG(INFO) << "Found existing ProtData!"; prot_data->UpdateUrl(url); @@ -641,6 +661,12 @@ STDMETHODIMP Hook_StartEx(InternetProtocol_StartEx_Fn orig_start_ex, return orig_start_ex(protocol, uri, prot_sink, bind_info, flags, reserved); } + scoped_refptr<ProtData> prot_data = ProtData::DataFromProtocol(protocol); + if (prot_data && !HasProtData(bind_ctx)) { + prot_data->Invalidate(); + prot_data = NULL; + } + if (HandleAttachToExistingExternalTab(url, protocol, prot_sink, bind_ctx)) { return S_OK; } @@ -649,7 +675,6 @@ STDMETHODIMP Hook_StartEx(InternetProtocol_StartEx_Fn orig_start_ex, return orig_start_ex(protocol, uri, prot_sink, bind_info, flags, reserved); } - scoped_refptr<ProtData> prot_data = ProtData::DataFromProtocol(protocol); if (prot_data) { DLOG(INFO) << "Found existing ProtData!"; prot_data->UpdateUrl(url); |