对象标记上的IE attachEvent会导致内存损坏 [英] IE attachEvent on object tag causes memory corruption
问题描述
我在嵌入式IE7 / 8 HTML页面中有一个ActiveX控件(嵌入了< object />)。 < object />有以下dispinterface事件: [id(1)] HRESULT MessageReceived([in] BSTR id,[in] BSTR json);.
I've an ActiveX Control (embedded with <object/>) within an embedded IE7/8 HTML page. The <object/> has the following dispinterface event: [id(1)] HRESULT MessageReceived([in] BSTR id, [in] BSTR json);.
在Windows上,事件已向OCX.attachEvent("MessageReceived"," onMessageReceivedFunc)。
On Windows the event is registered with OCX.attachEvent("MessageReceived", onMessageReceivedFunc).
function onMessageReceivedFunc(id, json) {
alert("messageReceived id=" + id + ", json=" + json);
}
以下代码在HTML中触发事件页面。
Following code fires the event in the HTML page.
HRESULT Fire_MessageReceived(BSTR id, BSTR json)
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[2];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
pvars[1] = id;
pvars[0] = json;
DISPPARAMS disp = { pvars, NULL, 2, 0 };
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
delete[] pvars; // -> Memory Corruption here!
return varResult.scode;
}
使用应用程序验证程序启用gflags.exe后,会发生以下奇怪的行为:
在执行JavaScript回调的Invoke()之后,来自pvars [1]的BSTR由于某种未知原因被复制到pvars [0]! pvars的delete []会导致双重释放相同的字符串然后以堆损坏结束。
有没有人知道这里发生了什么?这是一个IE错误还是在我缺少的OCX实现中有一个技巧?
如果我使用<脚本/>标签如:
After I enabled gflags.exe with application verifier, the following strange behaviour occur:
After Invoke() that is executing the JavaScript callback, the BSTR from pvars[1] is copied to pvars[0] for some unknown reason!? The delete[] of pvars causes a double free of the same string then which ends in a heap corruption.
Does anybody has an idea whats going on here? Is this a IE bug or is there a trick within the OCX Implementation that I'm missing?
If I use the <script/> tag like:
<script for="OCX" event="MessageReceived(id, json)" language="JavaScript" type="text/javascript">
window.onMessageReceivedFunc(windowId, json);
</script>
...不会发生奇怪的复制操作。
以下代码似乎还可以,因为Fire_MessageReceived()的调用者负责释放BSTR。
... the strange copy operation does not occur.
The following code also seem to be ok due to the fact that the caller of Fire_MessageReceived() is responsible for freeing the BSTRs.
HRESULT Fire_MessageReceived(BSTR srcWindowId, BSTR json)
{
CComVariant varResult;
T* pT = static_cast<T*>(this);
int nConnectionIndex;
VARIANT pvars[2];
int nConnections = m_vec.GetSize();
for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if (pDispatch != NULL)
{
VariantClear(&varResult);
pvars[1].vt = VT_BSTR;
pvars[1].bstrVal = srcWindowId;
pvars[0].vt = VT_BSTR;
pvars[0].bstrVal = json;
DISPPARAMS disp = { pvars, NULL, 2, 0 };
pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
}
}
return varResult.scode;
}
谢谢!
Thanks!
推荐答案
pvars [1] = id;
pvars [0] = json;
pvars[1] = id;
pvars[0] = json;
我很惊讶上面没有给你编译错误。您正在为CComVariant分配BSTR。不好主意。
I'm surprised that the above isn't giving you compiler errors. You are assigning a BSTR to a CComVariant. Bad idea.
试试这个:
CComVariant(id).Detach(& pvars [1]);
CComVariant(json).Detach(& pvars [0]);
CComVariant (id).Detach (&pvars[1]);
CComVariant(json).Detach (&pvars[0]);
这篇关于对象标记上的IE attachEvent会导致内存损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!