>From 2c42bcbb967ede4a2e4b5d15b35d4c91a6ca694a Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Sun, 30 Oct 2011 01:27:50 +0400
Subject: [PATCH 2/3] Release IDispatchEx dynamic data properly

---
 dlls/msxml3/dispex.c        |   16 ++++++++++++++++
 dlls/msxml3/msxml_private.h |    1 +
 dlls/msxml3/node.c          |    6 ++----
 dlls/msxml3/selection.c     |    9 +++++----
 4 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/dlls/msxml3/dispex.c b/dlls/msxml3/dispex.c
index 67570c0..274f604 100644
--- a/dlls/msxml3/dispex.c
+++ b/dlls/msxml3/dispex.c
@@ -653,6 +653,22 @@ BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv)
     return TRUE;
 }
 
+void release_dispex(DispatchEx *This)
+{
+    dynamic_prop_t *prop;
+
+    if(!This->dynamic_data)
+        return;
+
+    for(prop = This->dynamic_data->props; prop < This->dynamic_data->props + This->dynamic_data->prop_cnt; prop++) {
+        VariantClear(&prop->var);
+        heap_free(prop->name);
+    }
+
+    heap_free(This->dynamic_data->props);
+    heap_free(This->dynamic_data);
+}
+
 void init_dispex(DispatchEx *dispex, IUnknown *outer, dispex_static_data_t *data)
 {
     dispex->IDispatchEx_iface.lpVtbl = &DispatchExVtbl;
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index 2962a0e..8b84aca 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -156,6 +156,7 @@ typedef struct {
 extern HINSTANCE MSXML_hInstance DECLSPEC_HIDDEN;
 
 void init_dispex(DispatchEx*,IUnknown*,dispex_static_data_t*) DECLSPEC_HIDDEN;
+void release_dispex(DispatchEx*) DECLSPEC_HIDDEN;
 BOOL dispex_query_interface(DispatchEx*,REFIID,void**) DECLSPEC_HIDDEN;
 
 /* memory allocation functions */
diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c
index 7219bd3..0e00b38 100644
--- a/dlls/msxml3/node.c
+++ b/dlls/msxml3/node.c
@@ -1110,6 +1110,7 @@ void destroy_xmlnode(xmlnode *This)
 {
     if(This->node)
         xmldoc_release(This->node->doc);
+    release_dispex(&This->dispex);
 }
 
 void init_xmlnode(xmlnode *This, xmlNodePtr node, IXMLDOMNode *node_iface, dispex_static_data_t *dispex_data)
@@ -1121,10 +1122,7 @@ void init_xmlnode(xmlnode *This, xmlNodePtr node, IXMLDOMNode *node_iface, dispe
     This->iface = node_iface;
     This->parent = NULL;
 
-    if(dispex_data)
-        init_dispex(&This->dispex, (IUnknown*)This->iface, dispex_data);
-    else
-        This->dispex.outer = NULL;
+    init_dispex(&This->dispex, dispex_data ? (IUnknown*)This->iface : NULL, dispex_data);
 }
 
 typedef struct {
diff --git a/dlls/msxml3/selection.c b/dlls/msxml3/selection.c
index c90c8c2..0e62a68 100644
--- a/dlls/msxml3/selection.c
+++ b/dlls/msxml3/selection.c
@@ -155,6 +155,7 @@ static ULONG WINAPI domselection_Release(
         xmlXPathFreeObject(This->result);
         xmldoc_release(This->node->doc);
         if (This->enumvariant) IEnumVARIANT_Release(This->enumvariant);
+        release_dispex(&This->dispex);
         heap_free(This);
     }
 
@@ -756,8 +757,9 @@ HRESULT create_selection(xmlNodePtr node, xmlChar* query, IXMLDOMNodeList **out)
     *out = NULL;
     if (!This || !ctxt || !query)
     {
-        hr = E_OUTOFMEMORY;
-        goto cleanup;
+        xmlXPathFreeContext(ctxt);
+        heap_free(This);
+        return E_OUTOFMEMORY;
     }
 
     This->IXMLDOMSelection_iface.lpVtbl = &domselection_vtbl;
@@ -765,6 +767,7 @@ HRESULT create_selection(xmlNodePtr node, xmlChar* query, IXMLDOMNodeList **out)
     This->resultPos = 0;
     This->node = node;
     This->enumvariant = NULL;
+    init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMSelection_iface, &domselection_dispex);
     xmldoc_add_ref(This->node->doc);
 
     ctxt->error = query_serror;
@@ -804,8 +807,6 @@ HRESULT create_selection(xmlNodePtr node, xmlChar* query, IXMLDOMNodeList **out)
         goto cleanup;
     }
 
-    init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMSelection_iface, &domselection_dispex);
-
     *out = (IXMLDOMNodeList*)&This->IXMLDOMSelection_iface;
     hr = S_OK;
     TRACE("found %d matches\n", xmlXPathNodeSetGetLength(This->result->nodesetval));
-- 
1.5.6.5


