Module: wine Branch: master Commit: 65cbc12ac6e79073e937e5da3ea3de996e220be8 URL: http://source.winehq.org/git/wine.git/?a=commit;h=65cbc12ac6e79073e937e5da3e...
Author: Grant Paul grant@grantpaul.com Date: Tue Nov 22 17:57:20 2016 +0300
xmllite: Parse URLs in `DOCTYPE PUBLIC` DTDs.
Signed-off-by: Grant Paul git@grantpaul.com Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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();