From 9df2a8435a3381fe0958116ca24fae9a43272e0e Mon Sep 17 00:00:00 2001 From: Jean-Paul Saman Date: Mon, 15 Mar 2010 13:26:25 +0100 Subject: [PATCH] activex: Fix heap corrumption on Async event delivery The heap corruption occured when events returned a value. Since the events cross COM boundaries, the values returned should be allocated in COM context too. Allocating the memory with CoMemTaskAlloc() should be used instead of new or malloc(). --- projects/activex/connectioncontainer.cpp | 6 +++ projects/activex/main.cpp | 1 + projects/activex/plugin.cpp | 62 +++++++++++++++--------- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/projects/activex/connectioncontainer.cpp b/projects/activex/connectioncontainer.cpp index b9f601a8b8..fbceb7e450 100644 --- a/projects/activex/connectioncontainer.cpp +++ b/projects/activex/connectioncontainer.cpp @@ -365,6 +365,7 @@ VLCConnectionPointContainer::~VLCConnectionPointContainer() { EnterCriticalSection(&csEvents); isRunning = FALSE; + freeze = TRUE; ConditionSignal(&sEvents); LeaveCriticalSection(&csEvents); @@ -376,6 +377,11 @@ VLCConnectionPointContainer::~VLCConnectionPointContainer() ConditionDestroy(&sEvents); DeleteCriticalSection(&csEvents); + _v_cps.clear(); + while(!_q_events.empty()) { + _q_events.pop(); + }; + delete _p_props; delete _p_events; }; diff --git a/projects/activex/main.cpp b/projects/activex/main.cpp index 5b68ad7d62..8db6bdffe6 100644 --- a/projects/activex/main.cpp +++ b/projects/activex/main.cpp @@ -297,6 +297,7 @@ STDAPI DllRegisterServer(VOID) DWORD DllPathLen=GetModuleFileName(h_instance, DllPath, MAX_PATH) ; if( 0 == DllPathLen ) return E_UNEXPECTED; + DllPath[MAX_PATH-1] = '\0'; HKEY hBaseKey; diff --git a/projects/activex/plugin.cpp b/projects/activex/plugin.cpp index 0c2f8bde9b..1627e5e3d2 100644 --- a/projects/activex/plugin.cpp +++ b/projects/activex/plugin.cpp @@ -214,6 +214,11 @@ VLCPlugin::VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter) : _i_codepage(CP_ACP), _b_usermode(TRUE) { + /* + ** bump refcount to avoid recursive release from + ** following interfaces when releasing this interface + */ + AddRef(); p_class->AddRef(); vlcOleControl = new VLCOleControl(this); @@ -244,12 +249,6 @@ VLCPlugin::VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter) : VLCPlugin::~VLCPlugin() { - /* - ** bump refcount to avoid recursive release from - ** following interfaces when releasing this interface - */ - AddRef(); - delete vlcSupportErrorInfo; delete vlcOleObject; delete vlcDataObject; @@ -285,6 +284,7 @@ VLCPlugin::~VLCPlugin() if( _p_libvlc ) { libvlc_release(_p_libvlc); _p_libvlc=NULL; } _p_class->Release(); + Release(); }; STDMETHODIMP VLCPlugin::QueryInterface(REFIID riid, void **ppv) @@ -442,6 +442,7 @@ void VLCPlugin::initVLC() { TCHAR w_progpath[MAX_PATH]; DWORD len = GetModuleFileName(DllGetModule(), w_progpath, MAX_PATH); + w_progpath[MAX_PATH-1] = '\0'; if( len > 0 ) { len = WideCharToMultiByte(CP_UTF8, 0, w_progpath, len, p_progpath, @@ -466,6 +467,7 @@ void VLCPlugin::initVLC() if( RegQueryValueEx( h_key, TEXT("InstallDir"), 0, &i_type, (LPBYTE)w_pluginpath, &i_data ) == ERROR_SUCCESS ) { + w_pluginpath[MAX_PATH-1] = '\0'; if( i_type == REG_SZ ) { if( WideCharToMultiByte(CP_UTF8, 0, w_pluginpath, -1, p_pluginpath, @@ -1107,10 +1109,14 @@ static void handle_input_state_event(const libvlc_event_t* event, void *param) void VLCPlugin::fireOnMediaPlayerTimeChangedEvent(long time) { - VARIANT varPos; - DISPPARAMS params = { &varPos, NULL, 1, 0 }; - varPos.vt = VT_I4; - varPos.lVal = time; + DISPPARAMS params; + params.cArgs = 1; + params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ; + memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs); + params.rgvarg[0].vt = VT_I4; + params.rgvarg[0].lVal = time; + params.rgdispidNamedArgs = NULL; + params.cNamedArgs = 0; vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerTimeChangedEvent, ¶ms); }; @@ -1122,10 +1128,14 @@ static void handle_time_changed_event(const libvlc_event_t* event, void *param) void VLCPlugin::fireOnMediaPlayerPositionChangedEvent(long position) { - VARIANT varPos; - DISPPARAMS params = { &varPos, NULL, 1, 0 }; - varPos.vt = VT_I4; - varPos.lVal = position; + DISPPARAMS params; + params.cArgs = 1; + params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ; + memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs); + params.rgvarg[0].vt = VT_I4; + params.rgvarg[0].lVal = position; + params.rgdispidNamedArgs = NULL; + params.cNamedArgs = 0; vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPositionChangedEvent, ¶ms); }; @@ -1138,10 +1148,14 @@ static void handle_position_changed_event(const libvlc_event_t* event, void *par #define B(val) ((val) ? 0xFFFF : 0x0000) void VLCPlugin::fireOnMediaPlayerSeekableChangedEvent(VARIANT_BOOL seekable) { - VARIANT varSeek; - DISPPARAMS params = { &varSeek, NULL, 1, 0 }; - varSeek.vt = VT_BOOL; - varSeek.boolVal = seekable; + DISPPARAMS params; + params.cArgs = 1; + params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ; + memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs); + params.rgvarg[0].vt = VT_BOOL; + params.rgvarg[0].boolVal = seekable; + params.rgdispidNamedArgs = NULL; + params.cNamedArgs = 0; vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerSeekableChangedEvent, ¶ms); }; @@ -1153,10 +1167,14 @@ static void handle_seekable_changed_event(const libvlc_event_t* event, void *par void VLCPlugin::fireOnMediaPlayerPausableChangedEvent(VARIANT_BOOL pausable) { - VARIANT varPause; - DISPPARAMS params = { &varPause, NULL, 1, 0 }; - varPause.vt = VT_BOOL; - varPause.boolVal = pausable; + DISPPARAMS params; + params.cArgs = 1; + params.rgvarg = (VARIANTARG *) CoTaskMemAlloc(sizeof(VARIANTARG) * params.cArgs) ; + memset(params.rgvarg, 0, sizeof(VARIANTARG) * params.cArgs); + params.rgvarg[0].vt = VT_BOOL; + params.rgvarg[0].boolVal = pausable; + params.rgdispidNamedArgs = NULL; + params.cNamedArgs = 0; vlcConnectionPointContainer->fireEvent(DISPID_MediaPlayerPausableChangedEvent, ¶ms); }; -- 2.39.2