[PATCH 03/10] opcservices: Fix path used for part URIs.

Nikolay Sivov nsivov at codeweavers.com
Wed Sep 19 06:19:31 CDT 2018


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/opcservices/factory.c           |  26 +++++-
 dlls/opcservices/tests/opcservices.c | 135 +++++++++++++++++++++++++++
 2 files changed, 159 insertions(+), 2 deletions(-)

diff --git a/dlls/opcservices/factory.c b/dlls/opcservices/factory.c
index 45e7ad71e4..9c04964498 100644
--- a/dlls/opcservices/factory.c
+++ b/dlls/opcservices/factory.c
@@ -320,19 +320,41 @@ static HRESULT WINAPI opc_factory_CreatePackageRootUri(IOpcFactory *iface, IOpcU
 
 static HRESULT WINAPI opc_factory_CreatePartUri(IOpcFactory *iface, LPCWSTR uri, IOpcPartUri **out)
 {
-    IUri *part_uri;
+    static const WCHAR rootW[] = {'/',0};
+    IUri *part_uri, *root_uri, *combined;
     HRESULT hr;
 
     TRACE("iface %p, uri %s, out %p.\n", iface, debugstr_w(uri), out);
 
+    if (!out)
+        return E_POINTER;
+
+    *out = NULL;
+
     if (FAILED(hr = CreateUri(uri, Uri_CREATE_ALLOW_RELATIVE, 0, &part_uri)))
     {
         WARN("Failed to create uri, hr %#x.\n", hr);
         return hr;
     }
 
-    hr = opc_part_uri_create(part_uri, NULL, out);
+    if (FAILED(hr = CreateUri(rootW, Uri_CREATE_ALLOW_RELATIVE, 0, &root_uri)))
+    {
+        WARN("Failed to create root uri, hr %#x.\n", hr);
+        IUri_Release(part_uri);
+        return hr;
+    }
+
+    hr = CoInternetCombineIUri(root_uri, part_uri, 0, &combined, 0);
+    IUri_Release(root_uri);
     IUri_Release(part_uri);
+    if (FAILED(hr))
+    {
+        WARN("Failed to combine URIs, hr %#x.\n", hr);
+        return hr;
+    }
+
+    hr = opc_part_uri_create(combined, NULL, out);
+    IUri_Release(combined);
     return hr;
 }
 
diff --git a/dlls/opcservices/tests/opcservices.c b/dlls/opcservices/tests/opcservices.c
index a96a5cf078..986aae468a 100644
--- a/dlls/opcservices/tests/opcservices.c
+++ b/dlls/opcservices/tests/opcservices.c
@@ -448,8 +448,15 @@ static void test_rel_part_uri(void)
     } rel_part_uri_tests[] =
     {
         { "/uri", "/_rels/uri.rels" },
+        { "/path/uri", "/path/_rels/uri.rels" },
+        { "path/uri", "/path/_rels/uri.rels" },
+        { "../path/uri", "/path/_rels/uri.rels" },
+        { "../../path/uri", "/path/_rels/uri.rels" },
         { "/uri.ext", "/_rels/uri.ext.rels" },
         { "/", "/_rels/.rels" },
+        { "uri", "/_rels/uri.rels" },
+        { "/path/../uri", "/_rels/uri.rels" },
+        { "/path/path/../../uri", "/_rels/uri.rels" },
         { "/_rels/uri.ext.rels", "", OPC_E_NONCONFORMING_URI },
     };
     static const struct
@@ -459,6 +466,7 @@ static void test_rel_part_uri(void)
     } is_rel_part_tests[] =
     {
         { "/uri", FALSE },
+        { "uri", FALSE },
         { "/_rels/uri", FALSE },
         { "/_rels/uri/uri", FALSE },
         { "/_rels/uri/uri.rels", FALSE },
@@ -558,6 +566,7 @@ static void test_rel_part_uri(void)
 
             hr = IOpcPartUri_GetRawUri(rel_uri, &str);
             ok(SUCCEEDED(hr), "Failed to get rel uri, hr %#x.\n", hr);
+        todo_wine_if(i == 3 || i == 4 || i == 8 || i == 9)
             ok(!lstrcmpW(str, rel_uriW), "%u: unexpected rel uri %s, expected %s.\n", i, wine_dbgstr_w(str),
                     wine_dbgstr_w(rel_uriW));
             SysFreeString(str);
@@ -1003,6 +1012,130 @@ static void test_relative_uri(void)
     IOpcFactory_Release(factory);
 }
 
+static void test_combine_uri(void)
+{
+    static const struct
+    {
+        const char *uri;
+        const char *relative;
+        const char *combined;
+    }
+    combine_tests[] =
+    {
+        { "/", "path", "/path" },
+        { "/path1", "path2", "/path2" },
+        { "/path1", "../path2", "/path2" },
+        { "/path1/../path2", "path3", "/path3" },
+    };
+    IOpcFactory *factory;
+    unsigned int i;
+
+    factory = create_factory();
+
+    for (i = 0; i < ARRAY_SIZE(combine_tests); ++i)
+    {
+        WCHAR *uriW, *relativeW, *combinedW;
+        IOpcPartUri *combined_uri;
+        IUri *relative_uri;
+        IOpcUri *uri;
+        HRESULT hr;
+        BSTR str;
+
+        uriW = strdupAtoW(combine_tests[i].uri);
+        relativeW = strdupAtoW(combine_tests[i].relative);
+        combinedW = strdupAtoW(combine_tests[i].combined);
+
+        if (!strcmp(combine_tests[i].uri, "/"))
+            hr = IOpcFactory_CreatePackageRootUri(factory, &uri);
+        else
+            hr = IOpcFactory_CreatePartUri(factory, uriW, (IOpcPartUri **)&uri);
+
+        hr = CreateUri(relativeW, Uri_CREATE_ALLOW_RELATIVE, 0, &relative_uri);
+        ok(SUCCEEDED(hr), "%u: failed to create relative uri, hr %#x.\n", i, hr);
+
+        hr = IOpcUri_CombinePartUri(uri, relative_uri, &combined_uri);
+    todo_wine
+        ok(SUCCEEDED(hr), "%u: failed to combine uris, hr %#x.\n", i, hr);
+
+    if (SUCCEEDED(hr))
+    {
+        hr = IOpcPartUri_GetRawUri(combined_uri, &str);
+        ok(SUCCEEDED(hr), "%u: failed to get raw uri, hr %#x.\n", i, hr);
+        ok(!lstrcmpW(str, combinedW), "%u: unexpected uri %s.\n", i, wine_dbgstr_w(str));
+        SysFreeString(str);
+
+        IOpcPartUri_Release(combined_uri);
+    }
+        heap_free(uriW);
+        heap_free(relativeW);
+        heap_free(combinedW);
+
+        IOpcUri_Release(uri);
+        IUri_Release(relative_uri);
+    }
+
+    IOpcFactory_Release(factory);
+}
+
+static void test_create_part_uri(void)
+{
+    static const struct
+    {
+        const char *input;
+        const char *raw_uri;
+    }
+    create_part_uri_tests[] =
+    {
+        { "path", "/path" },
+        { "../path", "/path" },
+        { "../../path", "/path" },
+        { "/path", "/path" },
+        { "/path1/path2/path3/../path4", "/path1/path2/path4" },
+    };
+    IOpcFactory *factory;
+    unsigned int i;
+    HRESULT hr;
+
+    factory = create_factory();
+
+    for (i = 0; i < ARRAY_SIZE(create_part_uri_tests); ++i)
+    {
+        IOpcPartUri *part_uri;
+        WCHAR *inputW, *rawW;
+        IUri *uri;
+        BSTR str;
+        BOOL ret;
+
+        inputW = strdupAtoW(create_part_uri_tests[i].input);
+        rawW = strdupAtoW(create_part_uri_tests[i].raw_uri);
+
+        hr = IOpcFactory_CreatePartUri(factory, inputW, &part_uri);
+        ok(SUCCEEDED(hr), "%u: failed to create part uri, hr %#x.\n", i, hr);
+
+        hr = IOpcPartUri_GetRawUri(part_uri, &str);
+        ok(SUCCEEDED(hr), "Failed to get raw uri, hr %#x.\n", hr);
+    todo_wine_if(i == 1 || i == 2 || i == 4)
+        ok(!lstrcmpW(str, rawW), "%u: unexpected raw uri %s.\n", i, wine_dbgstr_w(str));
+        SysFreeString(str);
+
+        hr = CreateUri(rawW, Uri_CREATE_ALLOW_RELATIVE, 0, &uri);
+        ok(SUCCEEDED(hr), "Failed to create uri, hr %#x.\n", hr);
+
+        ret = FALSE;
+        hr = IOpcPartUri_IsEqual(part_uri, uri, &ret);
+        ok(SUCCEEDED(hr), "IsEqual failed, hr %#x.\n", hr);
+    todo_wine_if(i == 1 || i == 2 || i == 4)
+        ok(!!ret, "%u: unexpected result %d.\n", i, ret);
+
+        IOpcPartUri_Release(part_uri);
+
+        heap_free(inputW);
+        heap_free(rawW);
+    }
+
+    IOpcFactory_Release(factory);
+}
+
 START_TEST(opcservices)
 {
     IOpcFactory *factory;
@@ -1024,6 +1157,8 @@ START_TEST(opcservices)
     test_part_enumerator();
     test_rels_enumerator();
     test_relative_uri();
+    test_combine_uri();
+    test_create_part_uri();
 
     IOpcFactory_Release(factory);
 
-- 
2.18.0




More information about the wine-devel mailing list