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@codeweavers.com> Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1bb98982d6
commit
73af53c4bc
|
@ -498,10 +498,10 @@ static WCHAR *get_escaped_string(const WCHAR *str, escape_mode mode, int *len)
|
||||||
WCHAR *ptr, *ret;
|
WCHAR *ptr, *ret;
|
||||||
|
|
||||||
/* default buffer size to something if length is unknown */
|
/* 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));
|
ptr = ret = heap_alloc(conv_len*sizeof(WCHAR));
|
||||||
|
|
||||||
while (*str && p)
|
while (p)
|
||||||
{
|
{
|
||||||
if (ptr - ret > conv_len - grow_thresh)
|
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++;
|
str++;
|
||||||
if (*len != -1) p--;
|
p--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*len != -1) *len = ptr-ret;
|
*len = ptr-ret;
|
||||||
*++ptr = 0;
|
*++ptr = 0;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -2206,7 +2206,7 @@ static HRESULT WINAPI VBSAXContentHandler_characters(IVBSAXContentHandler *iface
|
||||||
if (!chars)
|
if (!chars)
|
||||||
return E_POINTER;
|
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)
|
static HRESULT WINAPI VBSAXContentHandler_ignorableWhitespace(IVBSAXContentHandler *iface, BSTR *chars)
|
||||||
|
|
|
@ -3950,10 +3950,13 @@ static const struct writer_characters_t writer_characters[] = {
|
||||||
static void test_mxwriter_characters(void)
|
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 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;
|
const struct writer_characters_t *table = writer_characters;
|
||||||
|
IVBSAXContentHandler *vb_content;
|
||||||
ISAXContentHandler *content;
|
ISAXContentHandler *content;
|
||||||
IMXWriter *writer;
|
IMXWriter *writer;
|
||||||
VARIANT dest;
|
VARIANT dest;
|
||||||
|
BSTR str;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
@ -3964,6 +3967,9 @@ static void test_mxwriter_characters(void)
|
||||||
hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
|
hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
|
||||||
EXPECT_HR(hr, S_OK);
|
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);
|
hr = IMXWriter_put_omitXMLDeclaration(writer, VARIANT_TRUE);
|
||||||
EXPECT_HR(hr, S_OK);
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
@ -3976,6 +3982,10 @@ static void test_mxwriter_characters(void)
|
||||||
hr = ISAXContentHandler_characters(content, chardataW, 0);
|
hr = ISAXContentHandler_characters(content, chardataW, 0);
|
||||||
EXPECT_HR(hr, S_OK);
|
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);
|
hr = ISAXContentHandler_characters(content, chardataW, ARRAY_SIZE(chardataW) - 1);
|
||||||
EXPECT_HR(hr, S_OK);
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
@ -3983,13 +3993,14 @@ static void test_mxwriter_characters(void)
|
||||||
hr = IMXWriter_get_output(writer, &dest);
|
hr = IMXWriter_get_output(writer, &dest);
|
||||||
EXPECT_HR(hr, S_OK);
|
EXPECT_HR(hr, S_OK);
|
||||||
ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
|
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);
|
VariantClear(&dest);
|
||||||
|
|
||||||
hr = ISAXContentHandler_endDocument(content);
|
hr = ISAXContentHandler_endDocument(content);
|
||||||
EXPECT_HR(hr, S_OK);
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
ISAXContentHandler_Release(content);
|
ISAXContentHandler_Release(content);
|
||||||
|
IVBSAXContentHandler_Release(vb_content);
|
||||||
IMXWriter_Release(writer);
|
IMXWriter_Release(writer);
|
||||||
|
|
||||||
/* try empty characters data to see if element is closed */
|
/* try empty characters data to see if element is closed */
|
||||||
|
@ -4025,6 +4036,65 @@ static void test_mxwriter_characters(void)
|
||||||
ISAXContentHandler_Release(content);
|
ISAXContentHandler_Release(content);
|
||||||
IMXWriter_Release(writer);
|
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 */
|
/* batch tests */
|
||||||
while (table->clsid)
|
while (table->clsid)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue