msxml3: Escape '<','&','"' and '>' in attribute value.
This commit is contained in:
parent
b83d322dba
commit
d80ee5b3ae
|
@ -57,7 +57,7 @@ typedef enum
|
|||
MXWriter_LastProp
|
||||
} MXWRITER_PROPS;
|
||||
|
||||
typedef struct _mxwriter
|
||||
typedef struct
|
||||
{
|
||||
DispatchEx dispex;
|
||||
IMXWriter IMXWriter_iface;
|
||||
|
@ -106,6 +106,71 @@ static HRESULT bstr_from_xmlCharEncoding(xmlCharEncoding enc, BSTR *encoding)
|
|||
return *encoding ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* escapes special characters like:
|
||||
'<' -> "<"
|
||||
'&' -> "&"
|
||||
'"' -> """
|
||||
'>' -> ">"
|
||||
*/
|
||||
static WCHAR *get_escaped_string(const WCHAR *str, int *len)
|
||||
{
|
||||
static const WCHAR ltW[] = {'&','l','t',';'};
|
||||
static const WCHAR ampW[] = {'&','a','m','p',';'};
|
||||
static const WCHAR quotW[] = {'&','q','u','o','t',';'};
|
||||
static const WCHAR gtW[] = {'&','g','t',';'};
|
||||
|
||||
const int default_alloc = 100;
|
||||
const int grow_thresh = 10;
|
||||
int p = *len, conv_len;
|
||||
WCHAR *ptr, *ret;
|
||||
|
||||
/* default buffer size to something if length is unknown */
|
||||
conv_len = *len == -1 ? default_alloc : max(2**len, default_alloc);
|
||||
ptr = ret = heap_alloc(conv_len*sizeof(WCHAR));
|
||||
|
||||
while (*str && p)
|
||||
{
|
||||
if (ptr - ret > conv_len - grow_thresh)
|
||||
{
|
||||
int written = ptr - ret;
|
||||
conv_len *= 2;
|
||||
ptr = ret = heap_realloc(ret, conv_len*sizeof(WCHAR));
|
||||
ptr += written;
|
||||
}
|
||||
|
||||
switch (*str)
|
||||
{
|
||||
case '<':
|
||||
memcpy(ptr, ltW, sizeof(ltW));
|
||||
ptr += sizeof(ltW)/sizeof(WCHAR);
|
||||
break;
|
||||
case '&':
|
||||
memcpy(ptr, ampW, sizeof(ampW));
|
||||
ptr += sizeof(ampW)/sizeof(WCHAR);
|
||||
break;
|
||||
case '"':
|
||||
memcpy(ptr, quotW, sizeof(quotW));
|
||||
ptr += sizeof(quotW)/sizeof(WCHAR);
|
||||
break;
|
||||
case '>':
|
||||
memcpy(ptr, gtW, sizeof(gtW));
|
||||
ptr += sizeof(gtW)/sizeof(WCHAR);
|
||||
break;
|
||||
default:
|
||||
*ptr++ = *str;
|
||||
break;
|
||||
}
|
||||
|
||||
str++;
|
||||
if (*len != -1) p--;
|
||||
}
|
||||
|
||||
if (*len != -1) *len = ptr-ret;
|
||||
*++ptr = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* creates UTF-8 encoded prolog string with specified or store encoding value */
|
||||
static int write_prolog_buffer(const mxwriter *This, xmlCharEncoding enc, xmlOutputBufferPtr buffer)
|
||||
{
|
||||
|
@ -824,6 +889,7 @@ static HRESULT WINAPI mxwriter_saxcontent_startElement(
|
|||
for (i = 0; i < length; i++)
|
||||
{
|
||||
const WCHAR *str;
|
||||
WCHAR *escaped;
|
||||
INT len = 0;
|
||||
|
||||
hr = ISAXAttributes_getQName(attr, i, &str, &len);
|
||||
|
@ -842,8 +908,10 @@ static HRESULT WINAPI mxwriter_saxcontent_startElement(
|
|||
hr = ISAXAttributes_getValue(attr, i, &str, &len);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
s = xmlchar_from_wcharn(str, len);
|
||||
escaped = get_escaped_string(str, &len);
|
||||
s = xmlchar_from_wcharn(escaped, len);
|
||||
write_output_buffer_str(This, (char*)s);
|
||||
heap_free(escaped);
|
||||
heap_free(s);
|
||||
|
||||
write_output_buffer(This, "\"", 1);
|
||||
|
|
|
@ -737,7 +737,7 @@ static ULONG WINAPI isaxattributes_Release(ISAXAttributes* iface)
|
|||
|
||||
static HRESULT WINAPI isaxattributes_getLength(ISAXAttributes* iface, int *length)
|
||||
{
|
||||
*length = 2;
|
||||
*length = 3;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -763,17 +763,19 @@ static HRESULT WINAPI isaxattributes_getLocalName(
|
|||
|
||||
static HRESULT WINAPI isaxattributes_getQName(
|
||||
ISAXAttributes* iface,
|
||||
int nIndex,
|
||||
const WCHAR **pQName,
|
||||
int *pQNameLength)
|
||||
int index,
|
||||
const WCHAR **QName,
|
||||
int *QNameLength)
|
||||
{
|
||||
static const WCHAR attr1W[] = {'a',':','a','t','t','r','1','j','u','n','k',0};
|
||||
static const WCHAR attr2W[] = {'a','t','t','r','2','j','u','n','k',0};
|
||||
static const WCHAR attrqnamesW[][15] = {{'a',':','a','t','t','r','1','j','u','n','k',0},
|
||||
{'a','t','t','r','2','j','u','n','k',0},
|
||||
{'a','t','t','r','3',0}};
|
||||
static const int attrqnamelen[] = {7, 5, 5};
|
||||
|
||||
ok(nIndex == 0 || nIndex == 1, "invalid index received %d\n", nIndex);
|
||||
ok(index >= 0 && index <= 2, "invalid index received %d\n", index);
|
||||
|
||||
*pQName = (nIndex == 0) ? attr1W : attr2W;
|
||||
*pQNameLength = (nIndex == 0) ? 7 : 5;
|
||||
*QName = attrqnamesW[index];
|
||||
*QNameLength = attrqnamelen[index];
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -848,19 +850,18 @@ static HRESULT WINAPI isaxattributes_getTypeFromQName(
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI isaxattributes_getValue(
|
||||
ISAXAttributes* iface,
|
||||
int nIndex,
|
||||
const WCHAR ** pValue,
|
||||
int * nValue)
|
||||
static HRESULT WINAPI isaxattributes_getValue(ISAXAttributes* iface, int index,
|
||||
const WCHAR **value, int *nValue)
|
||||
{
|
||||
static const WCHAR attrval1W[] = {'a','1','j','u','n','k',0};
|
||||
static const WCHAR attrval2W[] = {'a','2','j','u','n','k',0};
|
||||
static const WCHAR attrvaluesW[][10] = {{'a','1','j','u','n','k',0},
|
||||
{'a','2','j','u','n','k',0},
|
||||
{'<','&','"','>',0}};
|
||||
static const int attrvalueslen[] = {2, 2, 4};
|
||||
|
||||
ok(nIndex == 0 || nIndex == 1, "invalid index received %d\n", nIndex);
|
||||
ok(index >= 0 && index <= 2, "invalid index received %d\n", index);
|
||||
|
||||
*pValue = (nIndex == 0) ? attrval1W : attrval2W;
|
||||
*nValue = 2;
|
||||
*value = attrvaluesW[index];
|
||||
*nValue = attrvalueslen[index];
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -2039,6 +2040,9 @@ struct writer_startendelement_t {
|
|||
ISAXAttributes *attr;
|
||||
};
|
||||
|
||||
static const char startelement_xml[] = "<uri:local a:attr1=\"a1\" attr2=\"a2\" attr3=\"<&">\">";
|
||||
static const char startendelement_xml[] = "<uri:local a:attr1=\"a1\" attr2=\"a2\" attr3=\"<&">\"/>";
|
||||
|
||||
static const struct writer_startendelement_t writer_startendelement[] = {
|
||||
/* 0 */
|
||||
{ &CLSID_MXXMLWriter, StartElement, NULL, NULL, NULL, NULL, E_INVALIDARG },
|
||||
|
@ -2120,17 +2124,17 @@ static const struct writer_startendelement_t writer_startendelement[] = {
|
|||
{ &CLSID_MXXMLWriter60, EndElement, "uri", "local", "uri:local2", "</uri:local2>", S_OK },
|
||||
|
||||
/* with attributes */
|
||||
{ &CLSID_MXXMLWriter, StartElement, "uri", "local", "uri:local", "<uri:local a:attr1=\"a1\" attr2=\"a2\">", S_OK, &saxattributes },
|
||||
{ &CLSID_MXXMLWriter, StartElement, "uri", "local", "uri:local", startelement_xml, S_OK, &saxattributes },
|
||||
/* 65 */
|
||||
{ &CLSID_MXXMLWriter30, StartElement, "uri", "local", "uri:local", "<uri:local a:attr1=\"a1\" attr2=\"a2\">", S_OK, &saxattributes },
|
||||
{ &CLSID_MXXMLWriter40, StartElement, "uri", "local", "uri:local", "<uri:local a:attr1=\"a1\" attr2=\"a2\">", S_OK, &saxattributes },
|
||||
{ &CLSID_MXXMLWriter60, StartElement, "uri", "local", "uri:local", "<uri:local a:attr1=\"a1\" attr2=\"a2\">", S_OK, &saxattributes },
|
||||
{ &CLSID_MXXMLWriter30, StartElement, "uri", "local", "uri:local", startelement_xml, S_OK, &saxattributes },
|
||||
{ &CLSID_MXXMLWriter40, StartElement, "uri", "local", "uri:local", startelement_xml, S_OK, &saxattributes },
|
||||
{ &CLSID_MXXMLWriter60, StartElement, "uri", "local", "uri:local", startelement_xml, S_OK, &saxattributes },
|
||||
/* empty elements */
|
||||
{ &CLSID_MXXMLWriter, StartEndElement, "uri", "local", "uri:local", "<uri:local a:attr1=\"a1\" attr2=\"a2\"/>", S_OK, &saxattributes },
|
||||
{ &CLSID_MXXMLWriter30, StartEndElement, "uri", "local", "uri:local", "<uri:local a:attr1=\"a1\" attr2=\"a2\"/>", S_OK, &saxattributes },
|
||||
{ &CLSID_MXXMLWriter, StartEndElement, "uri", "local", "uri:local", startendelement_xml, S_OK, &saxattributes },
|
||||
{ &CLSID_MXXMLWriter30, StartEndElement, "uri", "local", "uri:local", startendelement_xml, S_OK, &saxattributes },
|
||||
/* 70 */
|
||||
{ &CLSID_MXXMLWriter40, StartEndElement, "uri", "local", "uri:local", "<uri:local a:attr1=\"a1\" attr2=\"a2\"/>", S_OK, &saxattributes },
|
||||
{ &CLSID_MXXMLWriter60, StartEndElement, "uri", "local", "uri:local", "<uri:local a:attr1=\"a1\" attr2=\"a2\"/>", S_OK, &saxattributes },
|
||||
{ &CLSID_MXXMLWriter40, StartEndElement, "uri", "local", "uri:local", startendelement_xml, S_OK, &saxattributes },
|
||||
{ &CLSID_MXXMLWriter60, StartEndElement, "uri", "local", "uri:local", startendelement_xml, S_OK, &saxattributes },
|
||||
{ &CLSID_MXXMLWriter, StartEndElement, "", "", "", "</>", S_OK },
|
||||
{ &CLSID_MXXMLWriter30, StartEndElement, "", "", "", "</>", S_OK },
|
||||
{ &CLSID_MXXMLWriter40, StartEndElement, "", "", "", "</>", S_OK },
|
||||
|
|
Loading…
Reference in New Issue