1
0
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:
Michael Schroeder
2021-09-20 15:10:38 +02:00
parent ed88075af8
commit 9a13593b43
2 changed files with 45 additions and 0 deletions

View File

@@ -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

View File

@@ -30,6 +30,7 @@ struct solv_xmlparser {
Id *elementhelper;
void *parser;
void *attsdata;
};
#define SOLV_XMLPARSER_OK 0