msxml3: Unescape '&' back to '&' in attribute value.

This commit is contained in:
Nikolay Sivov 2013-07-31 10:31:04 +04:00 committed by Alexandre Julliard
parent 387b5a3c12
commit b1bf9a62f9
2 changed files with 46 additions and 4 deletions

View File

@ -1265,6 +1265,49 @@ static const struct ISAXAttributesVtbl isaxattributes_vtbl =
isaxattributes_getValueFromQName
};
/* Libxml2 escapes '&' back to char reference '&' in attribute value,
so when document has escaped value with '&' it's parsed to '&' and then
escaped to '&'. This function takes care of ampersands only. */
static BSTR saxreader_get_unescaped_value(const xmlChar *buf, int len)
{
static const WCHAR ampescW[] = {'&','#','3','8',';',0};
WCHAR *dest, *ptrW, *str;
DWORD str_len;
BSTR bstr;
if (!buf)
return NULL;
str_len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0);
if (len != -1) str_len++;
str = heap_alloc(str_len*sizeof(WCHAR));
if (!str) return NULL;
MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, str, str_len);
if (len != -1) str[str_len-1] = 0;
ptrW = str;
while ((dest = strstrW(ptrW, ampescW)))
{
WCHAR *src;
/* leave first '&' from a reference as a value */
src = dest + (sizeof(ampescW)/sizeof(WCHAR) - 1);
dest++;
/* move together with null terminator */
memmove(dest, src, (strlenW(src) + 1)*sizeof(WCHAR));
ptrW++;
}
bstr = SysAllocString(str);
heap_free(str);
return bstr;
}
static HRESULT SAXAttributes_populate(saxlocator *locator,
int nb_namespaces, const xmlChar **xmlNamespaces,
int nb_attributes, const xmlChar **xmlAttributes)
@ -1317,8 +1360,7 @@ static HRESULT SAXAttributes_populate(saxlocator *locator,
attrs[i].szURI = find_element_uri(locator, xmlAttributes[i*5+2]);
attrs[i].szLocalname = bstr_from_xmlChar(xmlAttributes[i*5]);
attrs[i].szValue = bstr_from_xmlCharN(xmlAttributes[i*5+3],
xmlAttributes[i*5+4]-xmlAttributes[i*5+3]);
attrs[i].szValue = saxreader_get_unescaped_value(xmlAttributes[i*5+3], xmlAttributes[i*5+4]-xmlAttributes[i*5+3]);
attrs[i].szQName = QName_from_xmlChar(xmlAttributes[i*5+1],
xmlAttributes[i*5]);
}

View File

@ -888,10 +888,10 @@ static struct call_entry xmlspaceattr_test_alternate[] = {
/* attribute value normalization test */
static const char attribute_normalize[] =
"<?xml version=\"1.0\" ?>\n"
"<a attr1=\" \r \n \tattr_value &#65; \t \r \n\r\n \n\"/>\n";
"<a attr1=\" \r \n \tattr_value &#65; &#38; &amp;\t \r \n\r\n \n\"/>\n";
static struct attribute_entry attribute_norm_attrs[] = {
{ "", "attr1", "attr1", " attr_value A " },
{ "", "attr1", "attr1", " attr_value A & & " },
{ NULL }
};