diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-25 16:04:43 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-25 16:04:43 +0000 |
commit | bc88e9d7be9dbc039071cef0c7f80b9b1017f804 (patch) | |
tree | 1f8982e99cc1258184dd79514e5355ca19745cfa /chrome_frame/vtable_patch_manager.cc | |
parent | 03aaa36e09ca9f235656fc78ff9b65b1116af71d (diff) | |
download | chromium_src-bc88e9d7be9dbc039071cef0c7f80b9b1017f804.zip chromium_src-bc88e9d7be9dbc039071cef0c7f80b9b1017f804.tar.gz chromium_src-bc88e9d7be9dbc039071cef0c7f80b9b1017f804.tar.bz2 |
This fixes a crash in IE8 with ChromeFrame when a new tab was created.
ChromeFrame VTable patches the IInternetProtocol interface for the CLSID_HttpProtocol
and CLSID_HttpSProtocol handlers. However we were using the same VTable information to patch both
the handlers essentially overwriting the first one. While this all worked purely by chance, it
exposed a bug in IE8 where every new tab initially goes into a new process and if the chromeframe
is unloaded we would leave behind an IInternetProtocol interface in urlmon patched, which would
crash when dereferenced.
Added a check in the VTable patching code for this case.
This fixes bug http://code.google.com/p/chromium/issues/detail?id=22768
Bug=22768
Review URL: http://codereview.chromium.org/244002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27191 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/vtable_patch_manager.cc')
-rw-r--r-- | chrome_frame/vtable_patch_manager.cc | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/chrome_frame/vtable_patch_manager.cc b/chrome_frame/vtable_patch_manager.cc index 5f15158..0b9f79aa 100644 --- a/chrome_frame/vtable_patch_manager.cc +++ b/chrome_frame/vtable_patch_manager.cc @@ -30,6 +30,15 @@ HRESULT PatchInterfaceMethods(void* unknown, MethodPatchInfo* patches) { DCHECK(vtable); for (MethodPatchInfo* it = patches; it->index_ != -1; ++it) { + if (it->stub_ != NULL) { + // If this DCHECK fires it means that we are using the same VTable + // information to patch two different interfaces. + DCHECK(false); + DLOG(ERROR) << "Attempting to patch two different VTables with the " + << "same VTable information"; + continue; + } + PROC original_fn = vtable[it->index_]; FunctionStub* stub = FunctionStub::FromCode(original_fn); if (stub != NULL) { @@ -65,7 +74,7 @@ HRESULT PatchInterfaceMethods(void* unknown, MethodPatchInfo* patches) { HRESULT UnpatchInterfaceMethods(MethodPatchInfo* patches) { for (MethodPatchInfo* it = patches; it->index_ != -1; ++it) { if (it->stub_) { - DCHECK(it->stub_->absolute_target() == + DCHECK(it->stub_->absolute_target() == reinterpret_cast<uintptr_t>(it->method_)); // Modify the stub to just jump directly to the original function. it->stub_->BypassStub(reinterpret_cast<void*>(it->stub_->argument())); |