From 455f5f2380f6375539593778d321064bc9381de3 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 6 Feb 2017 01:19:30 +0300 Subject: [PATCH] xmllite: Handle char references within text nodes. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/xmllite/reader.c | 16 +++++++++------- dlls/xmllite/tests/reader.c | 38 +++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c index 1e3c7aa47fa..9bb0d56d346 100644 --- a/dlls/xmllite/reader.c +++ b/dlls/xmllite/reader.c @@ -2382,6 +2382,8 @@ static HRESULT reader_parse_chardata(xmlreader *reader) while (*ptr) { + static const WCHAR ampW[] = {'&',0}; + /* CDATA closing sequence ']]>' is not allowed */ if (ptr[0] == ']' && ptr[1] == ']' && ptr[2] == '>') return WC_E_CDSECTEND; @@ -2398,11 +2400,15 @@ static HRESULT reader_parse_chardata(xmlreader *reader) return S_OK; } - reader_skipn(reader, 1); - /* this covers a case when text has leading whitespace chars */ if (!is_wchar_space(*ptr)) reader->nodetype = XmlNodeType_Text; - ptr++; + + if (!reader_cmp(reader, ampW)) + reader_parse_reference(reader); + else + reader_skipn(reader, 1); + + ptr = reader_get_ptr(reader); } return S_OK; @@ -2413,7 +2419,6 @@ static HRESULT reader_parse_content(xmlreader *reader) { static const WCHAR cdstartW[] = {'<','!','[','C','D','A','T','A','[',0}; static const WCHAR etagW[] = {'<','/',0}; - static const WCHAR ampW[] = {'&',0}; if (reader->resumestate != XmlReadResumeState_Initial) { @@ -2448,9 +2453,6 @@ static HRESULT reader_parse_content(xmlreader *reader) if (!reader_cmp(reader, cdstartW)) return reader_parse_cdata(reader); - if (!reader_cmp(reader, ampW)) - return reader_parse_reference(reader); - if (!reader_cmp(reader, ltW)) return reader_parse_element(reader); diff --git a/dlls/xmllite/tests/reader.c b/dlls/xmllite/tests/reader.c index dc586e8ada2..f7f738e6820 100644 --- a/dlls/xmllite/tests/reader.c +++ b/dlls/xmllite/tests/reader.c @@ -2049,6 +2049,43 @@ static void test_namespaceuri(void) IXmlReader_Release(reader); } +static void test_read_charref(void) +{ + static const char testA[] = "dză"; + static const WCHAR chardataW[] = {0x01f3,0x0103,0}; + const WCHAR *value; + IXmlReader *reader; + XmlNodeType type; + IStream *stream; + HRESULT hr; + + hr = CreateXmlReader(&IID_IXmlReader, (void **)&reader, NULL); + ok(hr == S_OK, "S_OK, got %08x\n", hr); + + stream = create_stream_on_data(testA, sizeof(testA)); + hr = IXmlReader_SetInput(reader, (IUnknown *)stream); + ok(hr == S_OK, "got %08x\n", hr); + + hr = IXmlReader_Read(reader, &type); + ok(hr == S_OK, "got %08x\n", hr); + ok(type == XmlNodeType_Element, "Unexpected node type %d\n", type); + + hr = IXmlReader_Read(reader, &type); + ok(hr == S_OK, "got %08x\n", hr); + ok(type == XmlNodeType_Text, "Unexpected node type %d\n", type); + + hr = IXmlReader_GetValue(reader, &value, NULL); + ok(hr == S_OK, "got %08x\n", hr); + ok(!lstrcmpW(value, chardataW), "Text value : %s\n", wine_dbgstr_w(value)); + + hr = IXmlReader_Read(reader, &type); + ok(hr == S_OK, "got %08x\n", hr); + ok(type == XmlNodeType_EndElement, "Unexpected node type %d\n", type); + + IXmlReader_Release(reader); + IStream_Release(stream); +} + START_TEST(reader) { test_reader_create(); @@ -2070,4 +2107,5 @@ START_TEST(reader) test_reader_properties(); test_prefix(); test_namespaceuri(); + test_read_charref(); }