Jacek Caban : msxml3: Fix string length handling in I[VB]SAXContentHandler ::characters.
Alexandre Julliard
julliard at winehq.org
Tue Jul 2 15:32:03 CDT 2019
Module: wine
Branch: master
Commit: 73af53c4bca6cc56b4fccc8139cc564715c08e99
URL: https://source.winehq.org/git/wine.git/?a=commit;h=73af53c4bca6cc56b4fccc8139cc564715c08e99
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Jun 18 16:55:40 2019 +0200
msxml3: Fix string length handling in I[VB]SAXContentHandler::characters.
Windows crashes when -1 length is passed. Escaping should just copy
embedded null bytes.
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/msxml3/mxwriter.c | 10 +++---
dlls/msxml3/tests/saxreader.c | 72 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 76 insertions(+), 6 deletions(-)
diff --git a/dlls/msxml3/mxwriter.c b/dlls/msxml3/mxwriter.c
index 10be250..a5bfdf1 100644
--- a/dlls/msxml3/mxwriter.c
+++ b/dlls/msxml3/mxwriter.c
@@ -498,10 +498,10 @@ static WCHAR *get_escaped_string(const WCHAR *str, escape_mode mode, int *len)
WCHAR *ptr, *ret;
/* default buffer size to something if length is unknown */
- conv_len = *len == -1 ? default_alloc : max(2**len, default_alloc);
+ conv_len = max(2**len, default_alloc);
ptr = ret = heap_alloc(conv_len*sizeof(WCHAR));
- while (*str && p)
+ while (p)
{
if (ptr - ret > conv_len - grow_thresh)
{
@@ -539,10 +539,10 @@ static WCHAR *get_escaped_string(const WCHAR *str, escape_mode mode, int *len)
}
str++;
- if (*len != -1) p--;
+ p--;
}
- if (*len != -1) *len = ptr-ret;
+ *len = ptr-ret;
*++ptr = 0;
return ret;
@@ -2206,7 +2206,7 @@ static HRESULT WINAPI VBSAXContentHandler_characters(IVBSAXContentHandler *iface
if (!chars)
return E_POINTER;
- return ISAXContentHandler_characters(&This->ISAXContentHandler_iface, *chars, -1);
+ return ISAXContentHandler_characters(&This->ISAXContentHandler_iface, *chars, SysStringLen(*chars));
}
static HRESULT WINAPI VBSAXContentHandler_ignorableWhitespace(IVBSAXContentHandler *iface, BSTR *chars)
diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c
index eeef5b6..d1076f5 100644
--- a/dlls/msxml3/tests/saxreader.c
+++ b/dlls/msxml3/tests/saxreader.c
@@ -3950,10 +3950,13 @@ static const struct writer_characters_t writer_characters[] = {
static void test_mxwriter_characters(void)
{
static const WCHAR chardataW[] = {'T','E','S','T','C','H','A','R','D','A','T','A',' ','.',0};
+ static const WCHAR embedded_nullbytes[] = {'a',0,'b',0,0,0,'c',0};
const struct writer_characters_t *table = writer_characters;
+ IVBSAXContentHandler *vb_content;
ISAXContentHandler *content;
IMXWriter *writer;
VARIANT dest;
+ BSTR str;
HRESULT hr;
int i = 0;
@@ -3964,6 +3967,9 @@ static void test_mxwriter_characters(void)
hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
EXPECT_HR(hr, S_OK);
+ hr = IMXWriter_QueryInterface(writer, &IID_IVBSAXContentHandler, (void**)&vb_content);
+ EXPECT_HR(hr, S_OK);
+
hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
EXPECT_HR(hr, S_OK);
@@ -3976,6 +3982,10 @@ static void test_mxwriter_characters(void)
hr = ISAXContentHandler_characters(content, chardataW, 0);
EXPECT_HR(hr, S_OK);
+ str = _bstr_("VbChars");
+ hr = IVBSAXContentHandler_characters(vb_content, &str);
+ EXPECT_HR(hr, S_OK);
+
hr = ISAXContentHandler_characters(content, chardataW, ARRAY_SIZE(chardataW) - 1);
EXPECT_HR(hr, S_OK);
@@ -3983,13 +3993,14 @@ static void test_mxwriter_characters(void)
hr = IMXWriter_get_output(writer, &dest);
EXPECT_HR(hr, S_OK);
ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
- ok(!lstrcmpW(_bstr_("TESTCHARDATA ."), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
+ ok(!lstrcmpW(_bstr_("VbCharsTESTCHARDATA ."), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
VariantClear(&dest);
hr = ISAXContentHandler_endDocument(content);
EXPECT_HR(hr, S_OK);
ISAXContentHandler_Release(content);
+ IVBSAXContentHandler_Release(vb_content);
IMXWriter_Release(writer);
/* try empty characters data to see if element is closed */
@@ -4025,6 +4036,65 @@ static void test_mxwriter_characters(void)
ISAXContentHandler_Release(content);
IMXWriter_Release(writer);
+ /* test embedded null bytes */
+ hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IMXWriter, (void**)&writer);
+ EXPECT_HR(hr, S_OK);
+
+ hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
+ EXPECT_HR(hr, S_OK);
+
+ hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
+ EXPECT_HR(hr, S_OK);
+
+ hr = ISAXContentHandler_startDocument(content);
+ EXPECT_HR(hr, S_OK);
+
+ hr = ISAXContentHandler_characters(content, embedded_nullbytes, ARRAY_SIZE(embedded_nullbytes));
+ EXPECT_HR(hr, S_OK);
+
+ V_VT(&dest) = VT_EMPTY;
+ hr = IMXWriter_get_output(writer, &dest);
+ EXPECT_HR(hr, S_OK);
+ ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
+ ok(SysStringLen(V_BSTR(&dest)) == ARRAY_SIZE(embedded_nullbytes), "unexpected len %d\n", SysStringLen(V_BSTR(&dest)));
+ ok(!memcmp(V_BSTR(&dest), embedded_nullbytes, ARRAY_SIZE(embedded_nullbytes)),
+ "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
+ VariantClear(&dest);
+
+ ISAXContentHandler_Release(content);
+ IMXWriter_Release(writer);
+
+ hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IMXWriter, (void**)&writer);
+ EXPECT_HR(hr, S_OK);
+
+ hr = IMXWriter_QueryInterface(writer, &IID_IVBSAXContentHandler, (void**)&vb_content);
+ EXPECT_HR(hr, S_OK);
+
+ hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
+ EXPECT_HR(hr, S_OK);
+
+ hr = IVBSAXContentHandler_startDocument(vb_content);
+ EXPECT_HR(hr, S_OK);
+
+ str = SysAllocStringLen(embedded_nullbytes, ARRAY_SIZE(embedded_nullbytes));
+ hr = IVBSAXContentHandler_characters(vb_content, &str);
+ EXPECT_HR(hr, S_OK);
+ SysFreeString(str);
+
+ V_VT(&dest) = VT_EMPTY;
+ hr = IMXWriter_get_output(writer, &dest);
+ EXPECT_HR(hr, S_OK);
+ ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
+ ok(SysStringLen(V_BSTR(&dest)) == ARRAY_SIZE(embedded_nullbytes), "unexpected len %d\n", SysStringLen(V_BSTR(&dest)));
+ ok(!memcmp(V_BSTR(&dest), embedded_nullbytes, ARRAY_SIZE(embedded_nullbytes)),
+ "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
+ VariantClear(&dest);
+
+ IVBSAXContentHandler_Release(vb_content);
+ IMXWriter_Release(writer);
+
/* batch tests */
while (table->clsid)
{
More information about the wine-cvs
mailing list