[PATCH 0/4] MR2928: xmllite/writer: Implement more APIs
Implements or at least tries to implement: WriteName WriteQualifiedName WriteNmToken WriteEntityRef Signed-off-by: David Kahurani <k.kahurani(a)gmail.com> -- https://gitlab.winehq.org/wine/wine/-/merge_requests/2928
From: David Kahurani <k.kahurani(a)gmail.com> Writes a qualified name to output after validating it. Signed-off-by: David Kahurani <k.kahurani(a)gmail.com> --- dlls/xmllite/tests/writer.c | 86 +++++++++++++++++++++++++++++++++++++ dlls/xmllite/writer.c | 48 ++++++++++++++++++--- 2 files changed, 129 insertions(+), 5 deletions(-) diff --git a/dlls/xmllite/tests/writer.c b/dlls/xmllite/tests/writer.c index 572b3a9fd67..7fc85624a45 100644 --- a/dlls/xmllite/tests/writer.c +++ b/dlls/xmllite/tests/writer.c @@ -1785,6 +1785,91 @@ static void test_WriteAttributeString(void) IXmlWriter_Release(writer); } +static void test_WriteName(void) +{ + IXmlWriter *writer; + IStream *stream; + HRESULT hr; + + hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteName(writer, L""); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteName(writer, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteName(writer, L"name"); + ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr); + + stream = writer_set_output(writer); + writer_set_property(writer, XmlWriterProperty_OmitXmlDeclaration); + + hr = IXmlWriter_WriteName(writer, L"name"); + ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr); + + IStream_Release(stream); + stream = writer_set_output(writer); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteName(writer, L"a:a:a"); + ok(hr == WC_E_NAMECHARACTER, "Unexpcted hr %#lx.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + CHECK_OUTPUT(stream, + "<a"); + + IStream_Release(stream); + stream = writer_set_output(writer); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteName(writer, L"name"); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteFullEndElement(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + CHECK_OUTPUT(stream, + "<a>name</a>"); + + IStream_Release(stream); + stream = writer_set_output(writer); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteName(writer, L""); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + CHECK_OUTPUT(stream, + "<a"); + + IStream_Release(stream); + IXmlWriter_Release(writer); +} + static void test_WriteFullEndElement(void) { IXmlWriter *writer; @@ -2971,4 +3056,5 @@ START_TEST(writer) test_WriteAttributes(); test_WriteNode(); test_WriteNodeShallow(); + test_WriteName(); } diff --git a/dlls/xmllite/writer.c b/dlls/xmllite/writer.c index 128d666e82c..88a85f9db9e 100644 --- a/dlls/xmllite/writer.c +++ b/dlls/xmllite/writer.c @@ -1543,25 +1543,63 @@ static HRESULT WINAPI xmlwriter_WriteFullEndElement(IXmlWriter *iface) static HRESULT WINAPI xmlwriter_WriteName(IXmlWriter *iface, LPCWSTR pwszName) { - xmlwriter *This = impl_from_IXmlWriter(iface); + xmlwriter *writer = impl_from_IXmlWriter(iface); + int length, count = 0; + const WCHAR *p = pwszName; - FIXME("%p %s\n", This, wine_dbgstr_w(pwszName)); + TRACE("%p %s\n", iface, wine_dbgstr_w(pwszName)); - switch (This->state) + if (is_empty_string(pwszName)) + return E_INVALIDARG; + + length = lstrlenW(pwszName); + + while ((p = wcschr(p, ':'))) + { + if (p == pwszName || p == (pwszName + length)) + return WC_E_NAMECHARACTER; + + count++; + p++; + } + + if (count > 1) + return WC_E_NAMECHARACTER; + + p = pwszName; + while (*p) + { + if (*p == ':') + { + p++; + continue; + } + + if (!is_ncnamechar(*p)) + return WC_E_NAMECHARACTER; + + p++; + } + + switch (writer->state) { case XmlWriterState_Initial: return E_UNEXPECTED; case XmlWriterState_Ready: case XmlWriterState_DocClosed: - This->state = XmlWriterState_DocClosed; + writer->state = XmlWriterState_DocClosed; return WR_E_INVALIDACTION; case XmlWriterState_InvalidEncoding: return MX_E_ENCODING; + case XmlWriterState_ElemStarted: + writer_close_starttag(writer); + break; default: ; } - return E_NOTIMPL; + write_output_buffer(writer->output, pwszName, length); + return S_OK; } static HRESULT WINAPI xmlwriter_WriteNmToken(IXmlWriter *iface, LPCWSTR pwszNmToken) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2928
From: David Kahurani <k.kahurani(a)gmail.com> Validate a name then write it. Signed-off-by: David Kahurani <k.kahurani(a)gmail.com> --- dlls/xmllite/tests/writer.c | 72 +++++++++++++++++++++++++++++++++++++ dlls/xmllite/writer.c | 31 +++++++++++++--- 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/dlls/xmllite/tests/writer.c b/dlls/xmllite/tests/writer.c index 7fc85624a45..ccb739509db 100644 --- a/dlls/xmllite/tests/writer.c +++ b/dlls/xmllite/tests/writer.c @@ -1870,6 +1870,77 @@ static void test_WriteName(void) IXmlWriter_Release(writer); } +static void test_WriteEntityRef(void) +{ + IXmlWriter *writer; + IStream *stream; + HRESULT hr; + + hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteEntityRef(writer, L""); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteEntityRef(writer, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteEntityRef(writer, L"name"); + ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr); + + stream = writer_set_output(writer); + + writer_set_property(writer, XmlWriterProperty_OmitXmlDeclaration); + + hr = IXmlWriter_WriteEntityRef(writer, L"name"); + ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr); + + IStream_Release(stream); + stream = writer_set_output(writer); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteEntityRef(writer, L"na:me"); + ok(hr == WC_E_NAMECHARACTER, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + CHECK_OUTPUT(stream, + "<a"); + + IStream_Release(stream); + stream = writer_set_output(writer); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteEntityRef(writer, L"name"); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteEndDocument(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteEntityRef(writer, L"name"); + ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + CHECK_OUTPUT(stream, + "<a>&name;</a>"); + + IStream_Release(stream); + IXmlWriter_Release(writer); +} + static void test_WriteFullEndElement(void) { IXmlWriter *writer; @@ -3057,4 +3128,5 @@ START_TEST(writer) test_WriteNode(); test_WriteNodeShallow(); test_WriteName(); + test_WriteEntityRef(); } diff --git a/dlls/xmllite/writer.c b/dlls/xmllite/writer.c index 88a85f9db9e..290806c30d4 100644 --- a/dlls/xmllite/writer.c +++ b/dlls/xmllite/writer.c @@ -1473,23 +1473,46 @@ static HRESULT WINAPI xmlwriter_WriteEndElement(IXmlWriter *iface) static HRESULT WINAPI xmlwriter_WriteEntityRef(IXmlWriter *iface, LPCWSTR pwszName) { - xmlwriter *This = impl_from_IXmlWriter(iface); + xmlwriter *writer = impl_from_IXmlWriter(iface); + const WCHAR *p = pwszName; + int count = 0; - FIXME("%p %s\n", This, wine_dbgstr_w(pwszName)); + TRACE("%p %s\n", iface, wine_dbgstr_w(pwszName)); - switch (This->state) + if (is_empty_string(pwszName)) + return E_INVALIDARG; + + while (*p) + { + if (!is_ncnamechar(*p)) + return WC_E_NAMECHARACTER; + + count++; + p++; + } + + switch (writer->state) { case XmlWriterState_Initial: return E_UNEXPECTED; case XmlWriterState_InvalidEncoding: return MX_E_ENCODING; case XmlWriterState_DocClosed: + case XmlWriterState_Ready: + writer->state = XmlWriterState_DocClosed; return WR_E_INVALIDACTION; + case XmlWriterState_ElemStarted: + writer_close_starttag(writer); + break; default: ; } - return E_NOTIMPL; + write_output_buffer_char(writer->output, '&'); + write_output_buffer(writer->output, pwszName, count); + write_output_buffer_char(writer->output, ';'); + + return S_OK; } static HRESULT WINAPI xmlwriter_WriteFullEndElement(IXmlWriter *iface) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2928
From: David Kahurani <k.kahurani(a)gmail.com> Validate and write a NmToken. --- dlls/xmllite/tests/writer.c | 72 +++++++++++++++++++++++++++++++++++++ dlls/xmllite/writer.c | 28 ++++++++++++--- 2 files changed, 95 insertions(+), 5 deletions(-) diff --git a/dlls/xmllite/tests/writer.c b/dlls/xmllite/tests/writer.c index ccb739509db..a739a3a1ad6 100644 --- a/dlls/xmllite/tests/writer.c +++ b/dlls/xmllite/tests/writer.c @@ -1941,6 +1941,77 @@ static void test_WriteEntityRef(void) IXmlWriter_Release(writer); } +static void test_WriteNmToken(void) +{ + IXmlWriter *writer; + IStream *stream; + HRESULT hr; + + hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteNmToken(writer, L"token"); + ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteNmToken(writer, L""); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteNmToken(writer, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + stream = writer_set_output(writer); + + hr = IXmlWriter_WriteNmToken(writer, L"token"); + ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr); + + IStream_Release(stream); + stream = writer_set_output(writer); + + writer_set_property(writer, XmlWriterProperty_OmitXmlDeclaration); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteNmToken(writer, L"na(a)me"); + ok(hr == WC_E_NAMECHARACTER, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + CHECK_OUTPUT(stream, + "<a"); + + IStream_Release(stream); + stream = writer_set_output(writer); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteNmToken(writer, L"na:me:x"); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteEndDocument(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteNmToken(writer, L"name"); + ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + CHECK_OUTPUT(stream, + "<a>na:me:x</a>"); + + IStream_Release(stream); + IXmlWriter_Release(writer); +} + static void test_WriteFullEndElement(void) { IXmlWriter *writer; @@ -3129,4 +3200,5 @@ START_TEST(writer) test_WriteNodeShallow(); test_WriteName(); test_WriteEntityRef(); + test_WriteNmToken(); } diff --git a/dlls/xmllite/writer.c b/dlls/xmllite/writer.c index 290806c30d4..5a4bde71f91 100644 --- a/dlls/xmllite/writer.c +++ b/dlls/xmllite/writer.c @@ -1627,25 +1627,43 @@ static HRESULT WINAPI xmlwriter_WriteName(IXmlWriter *iface, LPCWSTR pwszName) static HRESULT WINAPI xmlwriter_WriteNmToken(IXmlWriter *iface, LPCWSTR pwszNmToken) { - xmlwriter *This = impl_from_IXmlWriter(iface); + xmlwriter *writer = impl_from_IXmlWriter(iface); + const WCHAR *p = pwszNmToken; + int count = 0; - FIXME("%p %s\n", This, wine_dbgstr_w(pwszNmToken)); + TRACE("%p %s\n", iface, wine_dbgstr_w(pwszNmToken)); - switch (This->state) + if (is_empty_string(pwszNmToken)) + return E_INVALIDARG; + + while (*p) + { + if (!is_namechar(*p)) + return WC_E_NAMECHARACTER; + + p++; + count++; + } + + switch (writer->state) { case XmlWriterState_Initial: return E_UNEXPECTED; case XmlWriterState_Ready: case XmlWriterState_DocClosed: - This->state = XmlWriterState_DocClosed; + writer->state = XmlWriterState_DocClosed; return WR_E_INVALIDACTION; case XmlWriterState_InvalidEncoding: return MX_E_ENCODING; + case XmlWriterState_ElemStarted: + writer_close_starttag(writer); + break; default: ; } - return E_NOTIMPL; + write_output_buffer(writer->output, pwszNmToken, count); + return S_OK; } static HRESULT writer_write_node(IXmlWriter *writer, IXmlReader *reader, BOOL shallow, BOOL write_default_attributes) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2928
From: David Kahurani <k.kahurani(a)gmail.com> Validate a name, associate it with a prefix, if present thereof and write the qualified name to the buffer Signed-off-by: David Kahurani <k.kahurani(a)gmail.com> --- dlls/xmllite/tests/writer.c | 98 +++++++++++++++++++++++++++++++++++++ dlls/xmllite/writer.c | 32 ++++++++++-- 2 files changed, 126 insertions(+), 4 deletions(-) diff --git a/dlls/xmllite/tests/writer.c b/dlls/xmllite/tests/writer.c index a739a3a1ad6..1555a2f9f05 100644 --- a/dlls/xmllite/tests/writer.c +++ b/dlls/xmllite/tests/writer.c @@ -2012,6 +2012,103 @@ static void test_WriteNmToken(void) IXmlWriter_Release(writer); } +static void test_WriteQualifiedName(void) +{ + IXmlWriter *writer; + IStream *stream; + HRESULT hr; + + hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteQualifiedName(writer, L"", L"cd"); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteQualifiedName(writer, NULL, L"cd"); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteQualifiedName(writer, L"ab", L"xyz(a)xyz"); + ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteQualifiedName(writer, L"ab", NULL); + ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteQualifiedName(writer, L"ab", L"cd"); + ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr); + + stream = writer_set_output(writer); + + writer_set_property(writer, XmlWriterProperty_OmitXmlDeclaration); + + hr = IXmlWriter_WriteQualifiedName(writer, L"ab", L"cd"); + ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#lx.\n", hr); + + IStream_Release(stream); + stream = writer_set_output(writer); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteStartElement(writer, L"ab", L"a", L"cd"); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteQualifiedName(writer, L"a(a)b", L"cd"); + ok(hr == WC_E_NAMECHARACTER, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + CHECK_OUTPUT(stream, + "<ab:a"); + + IStream_Release(stream); + stream = writer_set_output(writer); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteStartElement(writer, L"ab", L"a", L"cd"); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteQualifiedName(writer, L"ab", L"de"); + ok(hr == WR_E_NAMESPACEUNDECLARED, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + CHECK_OUTPUT(stream, + "<ab:a xmlns:ab=\"cd\">"); + + IStream_Release(stream); + stream = writer_set_output(writer); + + writer_set_property(writer, XmlWriterProperty_OmitXmlDeclaration); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteStartElement(writer, NULL, L"a", L"cd"); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteStartElement(writer, NULL, L"b", L"gh"); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteQualifiedName(writer, L"xy", L"cd"); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_WriteEndDocument(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + CHECK_OUTPUT(stream, + "<a xmlns=\"cd\"><b xmlns=\"gh\">xy</b></a>"); + + IStream_Release(stream); + IXmlWriter_Release(writer); +} + static void test_WriteFullEndElement(void) { IXmlWriter *writer; @@ -3201,4 +3298,5 @@ START_TEST(writer) test_WriteName(); test_WriteEntityRef(); test_WriteNmToken(); + test_WriteQualifiedName(); } diff --git a/dlls/xmllite/writer.c b/dlls/xmllite/writer.c index 5a4bde71f91..2f022126363 100644 --- a/dlls/xmllite/writer.c +++ b/dlls/xmllite/writer.c @@ -1826,23 +1826,47 @@ static HRESULT WINAPI xmlwriter_WriteProcessingInstruction(IXmlWriter *iface, LP static HRESULT WINAPI xmlwriter_WriteQualifiedName(IXmlWriter *iface, LPCWSTR pwszLocalName, LPCWSTR pwszNamespaceUri) { - xmlwriter *This = impl_from_IXmlWriter(iface); + xmlwriter *writer = impl_from_IXmlWriter(iface); + struct ns *ns; + int local_len; - FIXME("%p %s %s\n", This, wine_dbgstr_w(pwszLocalName), wine_dbgstr_w(pwszNamespaceUri)); + TRACE("%p %s %s\n", writer, wine_dbgstr_w(pwszLocalName), wine_dbgstr_w(pwszNamespaceUri)); - switch (This->state) + if (is_empty_string(pwszLocalName)) + return E_INVALIDARG; + + if (is_valid_ncname(pwszLocalName, &local_len)) + return WC_E_NAMECHARACTER; + + switch (writer->state) { case XmlWriterState_Initial: return E_UNEXPECTED; case XmlWriterState_InvalidEncoding: return MX_E_ENCODING; + case XmlWriterState_Ready: case XmlWriterState_DocClosed: return WR_E_INVALIDACTION; + case XmlWriterState_ElemStarted: + writer_close_starttag(writer); + break; default: ; } - return E_NOTIMPL; + ns = writer_find_ns(writer, NULL, pwszNamespaceUri); + + if (!ns) + return WR_E_NAMESPACEUNDECLARED; + + if (ns->prefix) + { + write_output_buffer(writer->output, ns->prefix, ns->prefix_len); + write_output_buffer_char(writer->output, ':'); + } + + write_output_buffer(writer->output, pwszLocalName, local_len); + return S_OK; } static HRESULT WINAPI xmlwriter_WriteRaw(IXmlWriter *iface, LPCWSTR data) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2928
Nikolay Sivov (@nsivov) commented about dlls/xmllite/writer.c:
+ return WC_E_NAMECHARACTER; + + p = pwszName; + while (*p) + { + if (*p == ':') + { + p++; + continue; + } + + if (!is_ncnamechar(*p)) + return WC_E_NAMECHARACTER; + + p++; + } This could use the same sequence to validate NCName that the reader is using. My understanding is that WriteName() does not accept qualified names, but you don't have such tests.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/2928#note_34138
Nikolay Sivov (@nsivov) commented about dlls/xmllite/writer.c:
- FIXME("%p %s\n", This, wine_dbgstr_w(pwszName)); + TRACE("%p %s\n", iface, wine_dbgstr_w(pwszName));
- switch (This->state) + if (is_empty_string(pwszName)) + return E_INVALIDARG; + + while (*p) + { + if (!is_ncnamechar(*p)) + return WC_E_NAMECHARACTER; + + count++; + p++; + }
This does not look right. It probably should use https://www.w3.org/TR/xml/#NT-Name or similar, e.g. you should not be able to start with a dot. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/2928#note_34139
Nikolay Sivov (@nsivov) commented about dlls/xmllite/writer.c:
static HRESULT WINAPI xmlwriter_WriteQualifiedName(IXmlWriter *iface, LPCWSTR pwszLocalName, LPCWSTR pwszNamespaceUri) { - xmlwriter *This = impl_from_IXmlWriter(iface); + xmlwriter *writer = impl_from_IXmlWriter(iface); + struct ns *ns; + int local_len;
- FIXME("%p %s %s\n", This, wine_dbgstr_w(pwszLocalName), wine_dbgstr_w(pwszNamespaceUri)); + TRACE("%p %s %s\n", writer, wine_dbgstr_w(pwszLocalName), wine_dbgstr_w(pwszNamespaceUri)); Please match this with existing formatting. Also clean up argument names please.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/2928#note_34140
Nikolay Sivov (@nsivov) commented about dlls/xmllite/writer.c:
+ break; default: ; }
- return E_NOTIMPL; + ns = writer_find_ns(writer, NULL, pwszNamespaceUri); + + if (!ns) + return WR_E_NAMESPACEUNDECLARED; + + if (ns->prefix) + { + write_output_buffer(writer->output, ns->prefix, ns->prefix_len); + write_output_buffer_char(writer->output, ':'); + } I don't see a test for this.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/2928#note_34141
On Tue May 30 16:05:12 2023 +0000, Nikolay Sivov wrote:
This could use the same sequence to validate NCName that the reader is using. My understanding is that WriteName() does not accept qualified names, but you don't have such tests. I'm not sure this is NCName because it accepts colons, just not more than one colon.
Test passes: ``` hr = IXmlWriter_WriteName(writer, L"na:me"); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ``` More than one colon gets rejected, test passes: ``` hr = IXmlWriter_WriteName(writer, L"a:a:a"); ok(hr == WC_E_NAMECHARACTER, "Unexpected hr %#lx.\n", hr); ``` This led me to believe a qualified name is expected. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/2928#note_34220
On Wed May 31 13:22:35 2023 +0000, David Kahurani wrote:
I'm not sure this is NCName because it accepts colons, just not more than one colon. Test passes: ``` hr = IXmlWriter_WriteName(writer, L"na:me"); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ``` More than one colon gets rejected, test passes: ``` hr = IXmlWriter_WriteName(writer, L"a:a:a"); ok(hr == WC_E_NAMECHARACTER, "Unexpected hr %#lx.\n", hr); ``` This led me to believe a qualified name is expected. Unfortunately I hadn't included the first test because I wasn't sure what to include.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/2928#note_34222
This led me to believe a qualified name is expected.
Maybe it is, but you don't need to look for its separator ahead with wcschr(). Reader has something for qname that would be better to duplicate here - check prefix, skip separator, check local name. Duplicated separators will be caught by this. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/2928#note_34225
participants (3)
-
David Kahurani -
David Kahurani (@kahurani) -
Nikolay Sivov (@nsivov)