Nikolay Sivov : msxml3: Fix putref_schemas()/get_schemas() behaviour on NULL pointer.

Alexandre Julliard julliard at winehq.org
Mon Jul 2 13:22:02 CDT 2012


Module: wine
Branch: master
Commit: 2b5dd13a0ab6f59a6976ccaffd254a911f6218eb
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2b5dd13a0ab6f59a6976ccaffd254a911f6218eb

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sun Jul  1 22:27:17 2012 +0400

msxml3: Fix putref_schemas()/get_schemas() behaviour on NULL pointer.

---

 dlls/msxml3/domdoc.c       |   33 ++++++++++++--------
 dlls/msxml3/tests/domdoc.c |   73 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+), 13 deletions(-)

diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index 5097ff6..080eb3d 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -2553,22 +2553,23 @@ static HRESULT WINAPI domdoc_get_namespaces(
 
 static HRESULT WINAPI domdoc_get_schemas(
     IXMLDOMDocument3* iface,
-    VARIANT* var1 )
+    VARIANT* schema )
 {
     domdoc *This = impl_from_IXMLDOMDocument3( iface );
-    HRESULT hr = S_FALSE;
     IXMLDOMSchemaCollection2* cur_schema = This->properties->schemaCache;
+    HRESULT hr = S_FALSE;
 
-    TRACE("(%p)->(%p)\n", This, var1);
+    TRACE("(%p)->(%p)\n", This, schema);
 
-    VariantInit(var1); /* Test shows we don't call VariantClear here */
-    V_VT(var1) = VT_NULL;
+    V_VT(schema) = VT_NULL;
+    /* just to reset pointer part, cause that's what application is expected to use */
+    V_DISPATCH(schema) = NULL;
 
     if(cur_schema)
     {
-        hr = IXMLDOMSchemaCollection2_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
+        hr = IXMLDOMSchemaCollection2_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(schema));
         if(SUCCEEDED(hr))
-            V_VT(var1) = VT_DISPATCH;
+            V_VT(schema) = VT_DISPATCH;
     }
     return hr;
 }
@@ -2585,13 +2586,19 @@ static HRESULT WINAPI domdoc_putref_schemas(
     switch(V_VT(&schema))
     {
     case VT_UNKNOWN:
-        hr = IUnknown_QueryInterface(V_UNKNOWN(&schema), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
-        break;
-
+        if (V_UNKNOWN(&schema))
+        {
+            hr = IUnknown_QueryInterface(V_UNKNOWN(&schema), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
+            break;
+        }
+        /* fallthrough */
     case VT_DISPATCH:
-        hr = IDispatch_QueryInterface(V_DISPATCH(&schema), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
-        break;
-
+        if (V_DISPATCH(&schema))
+        {
+            hr = IDispatch_QueryInterface(V_DISPATCH(&schema), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
+            break;
+        }
+        /* fallthrough */
     case VT_NULL:
     case VT_EMPTY:
         hr = S_OK;
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index 58b170c..5dc2581 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -12055,6 +12055,78 @@ static void test_put_data(void)
     free_bstrs();
 }
 
+static void test_putref_schemas(void)
+{
+    IXMLDOMSchemaCollection *cache;
+    IXMLDOMDocument2 *doc;
+    VARIANT schema;
+    HRESULT hr;
+
+    doc = create_document(&IID_IXMLDOMDocument2);
+    if (!doc) return;
+    cache = create_cache(&IID_IXMLDOMSchemaCollection);
+
+    /* set to NULL iface when no schema is set */
+    V_VT(&schema) = VT_DISPATCH;
+    V_DISPATCH(&schema) = NULL;
+    hr = IXMLDOMDocument2_putref_schemas(doc, schema);
+    EXPECT_HR(hr, S_OK);
+
+    V_VT(&schema) = VT_UNKNOWN;
+    V_UNKNOWN(&schema) = NULL;
+    hr = IXMLDOMDocument2_putref_schemas(doc, schema);
+    EXPECT_HR(hr, S_OK);
+
+    /* set as VT_DISPATCH, reset with it */
+    V_VT(&schema) = VT_DISPATCH;
+    V_DISPATCH(&schema) = (IDispatch*)cache;
+    hr = IXMLDOMDocument2_putref_schemas(doc, schema);
+    EXPECT_HR(hr, S_OK);
+
+    V_DISPATCH(&schema) = NULL;
+    hr = IXMLDOMDocument2_get_schemas(doc, &schema);
+    EXPECT_HR(hr, S_OK);
+    ok(V_DISPATCH(&schema) == (IDispatch*)cache, "got %p\n", V_DISPATCH(&schema));
+
+    V_VT(&schema) = VT_DISPATCH;
+    V_DISPATCH(&schema) = NULL;
+    hr = IXMLDOMDocument2_putref_schemas(doc, schema);
+    EXPECT_HR(hr, S_OK);
+
+    V_DISPATCH(&schema) = (IDispatch*)0xdeadbeef;
+    V_VT(&schema) = VT_I2;
+    hr = IXMLDOMDocument2_get_schemas(doc, &schema);
+    EXPECT_HR(hr, S_FALSE);
+    ok(V_DISPATCH(&schema) == NULL, "got %p\n", V_DISPATCH(&schema));
+    ok(V_VT(&schema) == VT_NULL, "got %d\n", V_VT(&schema));
+
+    /* set as VT_UNKNOWN, reset with it */
+    V_VT(&schema) = VT_UNKNOWN;
+    V_UNKNOWN(&schema) = (IUnknown*)cache;
+    hr = IXMLDOMDocument2_putref_schemas(doc, schema);
+    EXPECT_HR(hr, S_OK);
+
+    V_DISPATCH(&schema) = NULL;
+    hr = IXMLDOMDocument2_get_schemas(doc, &schema);
+    EXPECT_HR(hr, S_OK);
+    ok(V_DISPATCH(&schema) == (IDispatch*)cache, "got %p\n", V_DISPATCH(&schema));
+
+    V_VT(&schema) = VT_UNKNOWN;
+    V_UNKNOWN(&schema) = NULL;
+    hr = IXMLDOMDocument2_putref_schemas(doc, schema);
+    EXPECT_HR(hr, S_OK);
+
+    V_DISPATCH(&schema) = (IDispatch*)0xdeadbeef;
+    V_VT(&schema) = VT_I2;
+    hr = IXMLDOMDocument2_get_schemas(doc, &schema);
+    EXPECT_HR(hr, S_FALSE);
+    ok(V_DISPATCH(&schema) == NULL, "got %p\n", V_DISPATCH(&schema));
+    ok(V_VT(&schema) == VT_NULL, "got %d\n", V_VT(&schema));
+
+    IXMLDOMSchemaCollection_Release(cache);
+    IXMLDOMDocument2_Release(doc);
+}
+
 START_TEST(domdoc)
 {
     IXMLDOMDocument *doc;
@@ -12134,6 +12206,7 @@ START_TEST(domdoc)
     test_nodeValue();
     test_get_namespaces();
     test_put_data();
+    test_putref_schemas();
 
     test_xsltemplate();
 




More information about the wine-cvs mailing list