Grant Paul : xmllite: Parse URLs in `DOCTYPE PUBLIC` DTDs.

Alexandre Julliard julliard at winehq.org
Tue Nov 22 16:34:01 CST 2016


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

Author: Grant Paul <grant at grantpaul.com>
Date:   Tue Nov 22 17:57:20 2016 +0300

xmllite: Parse URLs in `DOCTYPE PUBLIC` DTDs.

Signed-off-by: Grant Paul <git at grantpaul.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/xmllite/reader.c       |  51 +++++++++++---------
 dlls/xmllite/tests/reader.c | 112 ++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 136 insertions(+), 27 deletions(-)

diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c
index deab301..9484173 100644
--- a/dlls/xmllite/reader.c
+++ b/dlls/xmllite/reader.c
@@ -1601,8 +1601,9 @@ static HRESULT reader_parse_pub_literal(xmlreader *reader, strval *literal)
         reader_skipn(reader, 1);
         cur = reader_get_ptr(reader);
     }
-
     reader_init_strvalue(start, reader_get_cur(reader)-start, literal);
+    if (*cur == quote) reader_skipn(reader, 1);
+
     TRACE("%s\n", debug_strval(reader, literal));
     return S_OK;
 }
@@ -1612,34 +1613,38 @@ static HRESULT reader_parse_externalid(xmlreader *reader)
 {
     static WCHAR systemW[] = {'S','Y','S','T','E','M',0};
     static WCHAR publicW[] = {'P','U','B','L','I','C',0};
-    strval name;
+    strval name, sys;
     HRESULT hr;
     int cnt;
 
-    if (reader_cmp(reader, systemW))
-    {
-        if (reader_cmp(reader, publicW))
-            return S_FALSE;
-        else
-        {
-            strval pub;
+    if (!reader_cmp(reader, publicW)) {
+        strval pub;
 
-            /* public id */
-            reader_skipn(reader, 6);
-            cnt = reader_skipspaces(reader);
-            if (!cnt) return WC_E_WHITESPACE;
+        /* public id */
+        reader_skipn(reader, 6);
+        cnt = reader_skipspaces(reader);
+        if (!cnt) return WC_E_WHITESPACE;
 
-            hr = reader_parse_pub_literal(reader, &pub);
-            if (FAILED(hr)) return hr;
+        hr = reader_parse_pub_literal(reader, &pub);
+        if (FAILED(hr)) return hr;
 
-            reader_init_cstrvalue(publicW, strlenW(publicW), &name);
-            return reader_add_attr(reader, &name, &pub);
-        }
-    }
-    else
-    {
-        strval sys;
+        reader_init_cstrvalue(publicW, strlenW(publicW), &name);
+        hr = reader_add_attr(reader, &name, &pub);
+        if (FAILED(hr)) return hr;
 
+        cnt = reader_skipspaces(reader);
+        if (!cnt) return S_OK;
+
+        /* optional system id */
+        hr = reader_parse_sys_literal(reader, &sys);
+        if (FAILED(hr)) return S_OK;
+
+        reader_init_cstrvalue(systemW, strlenW(systemW), &name);
+        hr = reader_add_attr(reader, &name, &sys);
+        if (FAILED(hr)) return hr;
+
+        return S_OK;
+    } else if (!reader_cmp(reader, systemW)) {
         /* system id */
         reader_skipn(reader, 6);
         cnt = reader_skipspaces(reader);
@@ -1652,7 +1657,7 @@ static HRESULT reader_parse_externalid(xmlreader *reader)
         return reader_add_attr(reader, &name, &sys);
     }
 
-    return hr;
+    return S_FALSE;
 }
 
 /* [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' intSubset ']' S?)? '>' */
diff --git a/dlls/xmllite/tests/reader.c b/dlls/xmllite/tests/reader.c
index d0b6184..3658d52 100644
--- a/dlls/xmllite/tests/reader.c
+++ b/dlls/xmllite/tests/reader.c
@@ -1136,11 +1136,114 @@ static void test_read_full(void)
     IXmlReader_Release(reader);
 }
 
-static const char test_dtd[] =
+static const char test_public_dtd[] =
+    "<!DOCTYPE testdtd PUBLIC \"pubid\" \"externalid uri\" >";
+
+static void test_read_public_dtd(void)
+{
+    static const WCHAR sysvalW[] = {'e','x','t','e','r','n','a','l','i','d',' ','u','r','i',0};
+    static const WCHAR pubvalW[] = {'p','u','b','i','d',0};
+    static const WCHAR dtdnameW[] = {'t','e','s','t','d','t','d',0};
+    static const WCHAR sysW[] = {'S','Y','S','T','E','M',0};
+    static const WCHAR pubW[] = {'P','U','B','L','I','C',0};
+    IXmlReader *reader;
+    const WCHAR *str;
+    XmlNodeType type;
+    IStream *stream;
+    UINT len, count;
+    HRESULT hr;
+
+    hr = CreateXmlReader(&IID_IXmlReader, (void**)&reader, NULL);
+    ok(hr == S_OK, "S_OK, got %08x\n", hr);
+
+    hr = IXmlReader_SetProperty(reader, XmlReaderProperty_DtdProcessing, DtdProcessing_Parse);
+    ok(hr == S_OK, "got 0x%8x\n", hr);
+
+    stream = create_stream_on_data(test_public_dtd, sizeof(test_public_dtd));
+    hr = IXmlReader_SetInput(reader, (IUnknown*)stream);
+    ok(hr == S_OK, "got %08x\n", hr);
+
+    type = XmlNodeType_None;
+    hr = IXmlReader_Read(reader, &type);
+    ok(hr == S_OK, "got 0x%8x\n", hr);
+    ok(type == XmlNodeType_DocumentType, "got type %d\n", type);
+
+    count = 0;
+    hr = IXmlReader_GetAttributeCount(reader, &count);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(count == 2, "got %d\n", count);
+
+    hr = IXmlReader_MoveToFirstAttribute(reader);
+    ok(hr == S_OK, "got %08x\n", hr);
+
+    type = XmlNodeType_None;
+    hr = IXmlReader_GetNodeType(reader, &type);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(type == XmlNodeType_Attribute, "got %d\n", type);
+
+    len = 0;
+    str = NULL;
+    hr = IXmlReader_GetLocalName(reader, &str, &len);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(len == lstrlenW(pubW), "got %u\n", len);
+    ok(!lstrcmpW(str, pubW), "got %s\n", wine_dbgstr_w(str));
+
+    len = 0;
+    str = NULL;
+    hr = IXmlReader_GetValue(reader, &str, &len);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(len == lstrlenW(pubvalW), "got %u\n", len);
+    ok(!lstrcmpW(str, pubvalW), "got %s\n", wine_dbgstr_w(str));
+
+    hr = IXmlReader_MoveToNextAttribute(reader);
+    ok(hr == S_OK, "got %08x\n", hr);
+
+    type = XmlNodeType_None;
+    hr = IXmlReader_GetNodeType(reader, &type);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(type == XmlNodeType_Attribute, "got %d\n", type);
+
+    len = 0;
+    str = NULL;
+    hr = IXmlReader_GetLocalName(reader, &str, &len);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(len == lstrlenW(sysW), "got %u\n", len);
+    ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str));
+
+    len = 0;
+    str = NULL;
+    hr = IXmlReader_GetValue(reader, &str, &len);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(len == lstrlenW(sysvalW), "got %u\n", len);
+    ok(!lstrcmpW(str, sysvalW), "got %s\n", wine_dbgstr_w(str));
+
+    hr = IXmlReader_MoveToElement(reader);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    len = 0;
+    str = NULL;
+    hr = IXmlReader_GetLocalName(reader, &str, &len);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+todo_wine {
+    ok(len == lstrlenW(dtdnameW), "got %u\n", len);
+    ok(!lstrcmpW(str, dtdnameW), "got %s\n", wine_dbgstr_w(str));
+}
+    len = 0;
+    str = NULL;
+    hr = IXmlReader_GetQualifiedName(reader, &str, &len);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(len == lstrlenW(dtdnameW), "got %u\n", len);
+    ok(!lstrcmpW(str, dtdnameW), "got %s\n", wine_dbgstr_w(str));
+
+    IStream_Release(stream);
+    IXmlReader_Release(reader);
+}
+
+static const char test_system_dtd[] =
     "<!DOCTYPE testdtd SYSTEM \"externalid uri\" >"
     "<!-- comment -->";
 
-static void test_read_dtd(void)
+static void test_read_system_dtd(void)
 {
     static const WCHAR sysvalW[] = {'e','x','t','e','r','n','a','l','i','d',' ','u','r','i',0};
     static const WCHAR dtdnameW[] = {'t','e','s','t','d','t','d',0};
@@ -1158,7 +1261,7 @@ static void test_read_dtd(void)
     hr = IXmlReader_SetProperty(reader, XmlReaderProperty_DtdProcessing, DtdProcessing_Parse);
     ok(hr == S_OK, "got 0x%8x\n", hr);
 
-    stream = create_stream_on_data(test_dtd, sizeof(test_dtd));
+    stream = create_stream_on_data(test_system_dtd, sizeof(test_system_dtd));
     hr = IXmlReader_SetInput(reader, (IUnknown*)stream);
     ok(hr == S_OK, "got %08x\n", hr);
 
@@ -1811,7 +1914,8 @@ START_TEST(reader)
     test_read_cdata();
     test_read_comment();
     test_read_pi();
-    test_read_dtd();
+    test_read_system_dtd();
+    test_read_public_dtd();
     test_read_element();
     test_isemptyelement();
     test_read_text();




More information about the wine-cvs mailing list