mirror of
https://github.com/openSUSE/libsolv.git
synced 2026-02-05 12:45:46 +01:00
Fix misparsing of '&' in attributes with libxml2
For some reason libxml2 insists on re-escaping '&' characters by substituting them with "&". The rpm dependencies are stored in attributes, so this is not an academic matter. Undo the damage done by libxml2 by replacing all & occurences by a single '&'.
This commit is contained in:
@@ -53,6 +53,47 @@ character_data(void *userData, const XML_Char *s, int len)
|
||||
xmlp->lcontent += len;
|
||||
}
|
||||
|
||||
#ifdef WITH_LIBXML2
|
||||
static void fixup_att_inplace(char *at)
|
||||
{
|
||||
while ((at = strchr(at, '&')) != 0)
|
||||
{
|
||||
at++;
|
||||
if (!memcmp(at, "#38;", 4))
|
||||
memmove(at, at + 4, strlen(at + 4) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
static const xmlChar **fixup_atts(struct solv_xmlparser *xmlp, const xmlChar **atts)
|
||||
{
|
||||
size_t needsize = 0;
|
||||
size_t natts;
|
||||
char **at;
|
||||
|
||||
for (natts = 0; atts[natts]; natts++)
|
||||
if (strchr((char *)atts[natts], '&'))
|
||||
needsize += strlen((const char *)atts[natts]) + 1;
|
||||
if (!needsize)
|
||||
return atts;
|
||||
at = xmlp->attsdata = solv_realloc(xmlp->attsdata, (natts + 1) * sizeof(xmlChar *) + needsize);
|
||||
needsize = (natts + 1) * sizeof(xmlChar *);
|
||||
for (natts = 0; atts[natts]; natts++)
|
||||
{
|
||||
at[natts] = (char *)atts[natts];
|
||||
if (strchr(at[natts], '&'))
|
||||
{
|
||||
size_t l = strlen(at[natts]) + 1;
|
||||
memcpy((char *)at + needsize, at[natts], l);
|
||||
at[natts] = (char *)at + needsize;
|
||||
needsize += l;
|
||||
fixup_att_inplace(at[natts]);
|
||||
}
|
||||
}
|
||||
at[natts] = 0;
|
||||
return (const xmlChar **)at;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_LIBXML2
|
||||
static void
|
||||
start_element(void *userData, const xmlChar *name, const xmlChar **atts)
|
||||
@@ -97,6 +138,8 @@ start_element(void *userData, const char *name, const char **atts)
|
||||
static const char *nullattr;
|
||||
atts = (const xmlChar **)&nullattr;
|
||||
}
|
||||
else if (xmlp->state != oldstate)
|
||||
atts = fixup_atts(xmlp, atts);
|
||||
#endif
|
||||
if (xmlp->state != oldstate)
|
||||
xmlp->startelement(xmlp, xmlp->state, el->element, (const char **)atts);
|
||||
@@ -177,6 +220,7 @@ solv_xmlparser_free(struct solv_xmlparser *xmlp)
|
||||
queue_free(&xmlp->elementq);
|
||||
xmlp->content = solv_free(xmlp->content);
|
||||
xmlp->errstr = solv_free(xmlp->errstr);
|
||||
xmlp->attsdata = solv_free(xmlp->attsdata);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -30,6 +30,7 @@ struct solv_xmlparser {
|
||||
|
||||
Id *elementhelper;
|
||||
void *parser;
|
||||
void *attsdata;
|
||||
};
|
||||
|
||||
#define SOLV_XMLPARSER_OK 0
|
||||
|
||||
Reference in New Issue
Block a user