oleaut32: Add a test for BSTR cache.

Dmitry Timoshkov dmitry at baikal.ru
Mon Jun 4 04:38:09 CDT 2012


This test imitates what pretty large and complex application does, and shows
that BSTR cache in Wine corrupts most of cached BSTR entries.
---
 dlls/oleaut32/tests/vartype.c |   97 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/dlls/oleaut32/tests/vartype.c b/dlls/oleaut32/tests/vartype.c
index 58b30b1..4650536 100644
--- a/dlls/oleaut32/tests/vartype.c
+++ b/dlls/oleaut32/tests/vartype.c
@@ -6072,6 +6072,102 @@ static void test_ChangeType_keep_dst(void)
      SysFreeString(bstr);
 }
 
+static int cache_entry(BSTR bstr, BSTR *cache, int cache_size)
+{
+    int i;
+
+    for (i = 0; i < cache_size; i++)
+    {
+        if (bstr == cache[i]) return i;
+    }
+
+    return -1;
+}
+
+static void test_ole_string_cache(void)
+{
+    BSTR bstr[16 * 16];
+    WCHAR str[16 * 16];
+    int i, j;
+    int good_length_entries, good_string_entries;
+
+    for (i = 0; i < sizeof(bstr)/sizeof(bstr[0]); i++)
+    {
+        int entry;
+
+        for (j = 0; j < 16; j++) str[j] = '0' + i % 10;
+        bstr[i] = SysAllocStringLen(str, i);
+        ok(bstr[i] != NULL, "SysAllocString failed\n");
+
+        entry = cache_entry(bstr[i], bstr, i);
+        ok(entry == -1, "bstr[%d] found in cache, index %d\n", i, entry);
+    }
+
+    for (i = 0; i < sizeof(bstr)/sizeof(bstr[0]); i++)
+    {
+        INTERNAL_BSTR *data = Get(bstr[i]);
+
+        for (j = 0; j < 16; j++) str[j] = '0' + i % 10;
+
+        ok(data->dwLen == i * sizeof(WCHAR), "%d: expected %d, got %d\n",
+           i, i * sizeof(WCHAR), data->dwLen);
+        ok(!memcmp(data->szString, str, i * sizeof(WCHAR)), "%d: expected %s, got %s\n",
+           i, wine_dbgstr_wn(str, i), wine_dbgstr_w(data->szString));
+    }
+
+    good_length_entries = good_string_entries = 0;
+
+    for (i = 0; i < sizeof(bstr)/sizeof(bstr[0]); i++)
+    {
+        int entry;
+        BSTR new_bstr;
+        INTERNAL_BSTR *data = Get(bstr[i]);
+
+        SysFreeString(bstr[i]);
+
+        for (j = 0; j < 16; j++) str[j] = 'a';
+        new_bstr = SysAllocStringLen(str, i);
+        ok(new_bstr != NULL, "SysAllocString failed\n");
+
+        entry = cache_entry(new_bstr, bstr, sizeof(bstr)/sizeof(bstr[0]));
+        ok(entry >= 0, "new_bstr with length %d is not in cache\n", i);
+
+        for (j = 0; j < 16; j++) str[j] = '0' + i % 10;
+
+        if (data->dwLen == i * sizeof(WCHAR))
+            good_length_entries++;
+        if (!memcmp(data->szString, str, i * sizeof(WCHAR)))
+            good_string_entries++;
+
+        SysFreeString(new_bstr);
+    }
+
+    trace("good_length_entries %d, good_string_entries %d\n", good_length_entries, good_string_entries);
+    ok(good_length_entries >= 190, "good_length_entries %d out of 256\n", good_length_entries);
+todo_wine
+    ok(good_string_entries >= 190, "good_string_entries %d out of 256\n", good_string_entries);
+
+    good_length_entries = good_string_entries = 0;
+
+    for (i = 0; i < sizeof(bstr)/sizeof(bstr[0]); i++)
+    {
+        INTERNAL_BSTR *data = Get(bstr[i]);
+
+        for (j = 0; j < 16; j++) str[j] = '0' + i % 10;
+
+        if (data->dwLen == i * sizeof(WCHAR))
+            good_length_entries++;
+        if (!memcmp(data->szString, str, i * sizeof(WCHAR)))
+            good_string_entries++;
+    }
+
+    trace("good_length_entries %d, good_string_entries %d\n", good_length_entries, good_string_entries);
+todo_wine
+    ok(good_length_entries >= 100, "good_length_entries %d out of 256\n", good_length_entries);
+todo_wine
+    ok(good_string_entries >= 190, "good_string_entries %d out of 256\n", good_string_entries);
+}
+
 START_TEST(vartype)
 {
   hOleaut32 = GetModuleHandleA("oleaut32.dll");
@@ -6348,6 +6444,7 @@ START_TEST(vartype)
   test_SysReAllocStringLen();
   test_BstrCopy();
   test_VarBstrCat();
+  test_ole_string_cache();
 
   test_IUnknownClear();
   test_IUnknownCopy();
-- 
1.7.10.1




More information about the wine-patches mailing list