summaryrefslogtreecommitdiffstats
path: root/chrome_frame/vtable_patch_manager.cc
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-25 16:04:43 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-25 16:04:43 +0000
commitbc88e9d7be9dbc039071cef0c7f80b9b1017f804 (patch)
tree1f8982e99cc1258184dd79514e5355ca19745cfa /chrome_frame/vtable_patch_manager.cc
parent03aaa36e09ca9f235656fc78ff9b65b1116af71d (diff)
downloadchromium_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.cc11
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()));