[6/7] msxml3: Fix putref_schemas()/get_schemas() behaviour on NULL pointer

Nikolay Sivov nsivov at codeweavers.com
Mon Jul 2 02:13:41 CDT 2012


http://bugs.winehq.org/show_bug.cgi?id=30551
-------------- next part --------------
>From 5d55418ce859c75cc2ebbe5d414b13b94d7b6324 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Sun, 1 Jul 2012 22:27:17 +0400
Subject: [PATCH 7/8] 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();
 
-- 
1.5.6.5




More information about the wine-patches mailing list