Jacek Caban : xmllite: Fixed ReadValueChunk implementation.

Alexandre Julliard julliard at winehq.org
Wed Mar 22 15:52:35 CDT 2017


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Mar 21 16:19:24 2017 +0100

xmllite: Fixed ReadValueChunk implementation.

Mostly copy all characters to output buffer, but also minor fixes to
returned values found by tests.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/xmllite/reader.c       | 11 ++++---
 dlls/xmllite/tests/reader.c | 72 +++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 74 insertions(+), 9 deletions(-)

diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c
index c33d9bf..478830d 100644
--- a/dlls/xmllite/reader.c
+++ b/dlls/xmllite/reader.c
@@ -3328,18 +3328,17 @@ static HRESULT WINAPI xmlreader_ReadValueChunk(IXmlReader* iface, WCHAR *buffer,
     TRACE("(%p)->(%p %u %p)\n", reader, buffer, chunk_size, read);
 
     /* Value is already allocated, chunked reads are not possible. */
-    if (val->str) return S_FALSE;
+    len = !val->str && val->len ? min(chunk_size, val->len) : 0;
+    if (read) *read = len;
 
-    if (val->len)
+    if (len)
     {
-        len = min(chunk_size, val->len);
-        memcpy(buffer, reader_get_ptr2(reader, val->start), len);
+        memcpy(buffer, reader_get_ptr2(reader, val->start), len*sizeof(WCHAR));
         val->start += len;
         val->len -= len;
-        if (read) *read = len;
     }
 
-    return S_OK;
+    return len || !chunk_size ? S_OK : S_FALSE;
 }
 
 static HRESULT WINAPI xmlreader_GetBaseUri(IXmlReader* iface,
diff --git a/dlls/xmllite/tests/reader.c b/dlls/xmllite/tests/reader.c
index 47192f9..e91383f 100644
--- a/dlls/xmllite/tests/reader.c
+++ b/dlls/xmllite/tests/reader.c
@@ -46,6 +46,14 @@ static void free_str(WCHAR *str)
     HeapFree(GetProcessHeap(), 0, str);
 }
 
+static int strcmp_wa(const WCHAR *str1, const char *stra)
+{
+    WCHAR *str2 = a2w(stra);
+    int r = lstrcmpW(str1, str2);
+    free_str(str2);
+    return r;
+}
+
 static const char xmldecl_full[] = "\xef\xbb\xbf<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
 static const char xmldecl_short[] = "<?xml version=\"1.0\"?><RegistrationInfo/>";
 
@@ -1643,11 +1651,12 @@ todo_wine
 
 static void test_readvaluechunk(void)
 {
-    static const char testA[] = "<!-- comment1 -->";
+    static const char testA[] = "<!-- comment1 --><!-- comment2 -->";
     IXmlReader *reader;
     XmlNodeType type;
     IStream *stream;
     const WCHAR *value;
+    WCHAR buf[64];
     WCHAR b;
     HRESULT hr;
     UINT c;
@@ -1661,6 +1670,7 @@ static void test_readvaluechunk(void)
 
     hr = IXmlReader_Read(reader, &type);
     ok(hr == S_OK, "got %08x\n", hr);
+    ok(type == XmlNodeType_Comment, "type = %u\n", type);
 
     c = 0;
     b = 0;
@@ -1669,11 +1679,18 @@ static void test_readvaluechunk(void)
     ok(c == 1, "got %u\n", c);
     ok(b == ' ', "got %x\n", b);
 
+    c = 0;
+    b = 0xffff;
+    hr = IXmlReader_ReadValueChunk(reader, &b, 1, &c);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(c == 1, "got %u\n", c);
+    ok(b == 'c', "got %x\n", b);
+
     /* portion read as chunk is skipped from resulting node value */
     value = NULL;
     hr = IXmlReader_GetValue(reader, &value, NULL);
     ok(hr == S_OK, "got %08x\n", hr);
-    ok(value[0] == 'c', "got %s\n", wine_dbgstr_w(value));
+    ok(!strcmp_wa(value, "omment1 "), "got %s\n", wine_dbgstr_w(value));
 
     /* once value is returned/allocated it's not possible to read by chunk */
     c = 0;
@@ -1683,10 +1700,59 @@ static void test_readvaluechunk(void)
     ok(c == 0, "got %u\n", c);
     ok(b == 0, "got %x\n", b);
 
+    c = 0xdeadbeef;
+    hr = IXmlReader_ReadValueChunk(reader, buf, 0, &c);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(!c, "c = %u\n", c);
+
+    value = NULL;
+    hr = IXmlReader_GetValue(reader, &value, NULL);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(!strcmp_wa(value, "omment1 "), "got %s\n", wine_dbgstr_w(value));
+
+    /* read comment2 */
+    hr = IXmlReader_Read(reader, &type);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(type == XmlNodeType_Comment, "type = %u\n", type);
+
+    c = 0xdeadbeef;
+    hr = IXmlReader_ReadValueChunk(reader, buf, 0, &c);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(!c, "c = %u\n", c);
+
+    c = 0xdeadbeef;
+    memset(buf, 0xcc, sizeof(buf));
+    hr = IXmlReader_ReadValueChunk(reader, buf, sizeof(buf)/sizeof(WCHAR), &c);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(c == 10, "got %u\n", c);
+    ok(buf[c] == 0xcccc, "buffer overflow\n");
+    buf[c] = 0;
+    ok(!strcmp_wa(buf, " comment2 "), "buf = %s\n", wine_dbgstr_w(buf));
+
+    c = 0xdeadbeef;
+    memset(buf, 0xcc, sizeof(buf));
+    hr = IXmlReader_ReadValueChunk(reader, buf, sizeof(buf)/sizeof(WCHAR), &c);
+    ok(hr == S_FALSE, "got %08x\n", hr);
+    ok(!c, "got %u\n", c);
+
+    /* portion read as chunk is skipped from resulting node value */
+    value = NULL;
+    hr = IXmlReader_GetValue(reader, &value, NULL);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(!*value, "got %s\n", wine_dbgstr_w(value));
+
+    /* once value is returned/allocated it's not possible to read by chunk */
+    c = 0xdeadbeef;
+    b = 0xffff;
+    hr = IXmlReader_ReadValueChunk(reader, &b, 1, &c);
+    ok(hr == S_FALSE, "got %08x\n", hr);
+    ok(c == 0, "got %u\n", c);
+    ok(b == 0xffff, "got %x\n", b);
+
     value = NULL;
     hr = IXmlReader_GetValue(reader, &value, NULL);
     ok(hr == S_OK, "got %08x\n", hr);
-    ok(value[0] == 'c', "got %s\n", wine_dbgstr_w(value));
+    ok(!*value, "got %s\n", wine_dbgstr_w(value));
 
     IXmlReader_Release(reader);
     IStream_Release(stream);




More information about the wine-cvs mailing list