msxml3: Unescape '&' back to '&' in attribute value.
This commit is contained in:
parent
387b5a3c12
commit
b1bf9a62f9
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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 A \t \r \n\r\n \n\"/>\n";
|
||||
"<a attr1=\" \r \n \tattr_value A & &\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 }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue