From 2370dd1cd0e2c9f7609ba064f50f6e6a88fba06d Mon Sep 17 00:00:00 2001 From: Silvan Calarco Date: Sat, 20 Mar 2021 14:05:02 +0100 Subject: [PATCH] headerlist.c: getXMLPackageNFV: support for complex requirements like "(name >= ver1 with name < ver2)" --- src/headerlist.c | 88 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 25 deletions(-) diff --git a/src/headerlist.c b/src/headerlist.c index f8bc454..09d566b 100644 --- a/src/headerlist.c +++ b/src/headerlist.c @@ -793,15 +793,15 @@ xmlNode* findXMLPackageByName(xmlNode *root_node, char* name) { int XMLFlagToInt(char *flag) { if (!flag) return RPMSENSE_ANY; - else if (!strcmp(flag, "EQ")) + else if (!strcmp(flag, "EQ") || !strcmp(flag, "=")) return RPMSENSE_EQUAL; - else if (!strcmp(flag, "LT")) + else if (!strcmp(flag, "LT") || !strcmp(flag, "<")) return RPMSENSE_LESS; - else if (!strcmp(flag, "LE")) + else if (!strcmp(flag, "LE") || !strcmp(flag, "<=")) return RPMSENSE_EQUAL | RPMSENSE_LESS; - else if (!strcmp(flag, "GT")) + else if (!strcmp(flag, "GT") || !strcmp(flag, ">")) return RPMSENSE_GREATER; - else if (!strcmp(flag, "GE")) + else if (!strcmp(flag, "GE") || !strcmp(flag, ">=")) return RPMSENSE_EQUAL | RPMSENSE_GREATER; return RPMSENSE_ANY; } @@ -868,7 +868,7 @@ void getXMLPackageChangelog(xmlNode *parent, void getXMLPackageNFV(xmlNode *parent, char ***name, uint_32 **flags, char ***version, int *count) { - char buf[PATH_MAX]; + char *n, buf[PATH_MAX]; *count = xmlChildElementCount(parent); if (*count == 0) { @@ -889,26 +889,64 @@ void getXMLPackageNFV(xmlNode *parent, char ***name, *count); return; } - (*name)[i] = (char*)findXMLAttributeByName(entry, "name"); - (*flags)[i] = XMLFlagToInt( - (char*)findXMLAttributeByName(entry, "flags")); - buf[0] = '\0'; - if ((*flags)[i] != RPMSENSE_ANY) { - char *epoch = (char*)findXMLAttributeByName(entry, "epoch"); - char *ver = (char*)findXMLAttributeByName(entry, "ver"); - char *rel = (char*)findXMLAttributeByName(entry, "rel"); - if (epoch && ver && rel) { - snprintf(buf, PATH_MAX,"%s:%s-%s", epoch, ver, rel); - free(epoch); - free(ver); - free(rel); - } else if (epoch && ver) { - snprintf(buf, PATH_MAX,"%s:%s", epoch, ver); - free(epoch); - free(ver); - } + n = (char*)findXMLAttributeByName(entry, "name"); + if (n[0] != '(') { + (*name)[i] = n; + (*flags)[i] = XMLFlagToInt( + (char*)findXMLAttributeByName(entry, "flags")); + buf[0] = '\0'; + if ((*flags)[i] != RPMSENSE_ANY) { + char *epoch = (char*)findXMLAttributeByName(entry, "epoch"); + char *ver = (char*)findXMLAttributeByName(entry, "ver"); + char *rel = (char*)findXMLAttributeByName(entry, "rel"); + if (epoch && ver && rel) { + snprintf(buf, PATH_MAX,"%s:%s-%s", epoch, ver, rel); + free(epoch); + free(ver); + free(rel); + } else if (epoch && ver) { + snprintf(buf, PATH_MAX,"%s:%s", epoch, ver); + free(epoch); + free(ver); + } + } + (*version)[i] = strdup(buf); + } else { + // Complex requirement like "(name >= ver1 with name < ver2)" + char n1[PATH_MAX], rel1[PATH_MAX], v1[PATH_MAX], + n2[PATH_MAX], rel2[PATH_MAX], v2[PATH_MAX], comp[PATH_MAX]; + int ret = sscanf(n,"%*1c%s %s %s %s %s %s %s%*1c", n1, rel1, v1, + comp, n2, rel2, v2); + if (ret == 7 && !strncmp(comp,"with",4)) { + free(n); + // Extend arrays + (*count)++; + char **newname = malloc(sizeof(char*) * *count); + uint_32 *newflags = malloc(sizeof(uint_32) * *count); + char **newversion = malloc(sizeof(char*) * *count); + memcpy(newname, *name, sizeof(name)); + memcpy(newflags, *flags, sizeof(flags)); + memcpy(newversion, *version, sizeof(version)); + free(*name); + free(*flags); + free(*version); + *name = newname; + *flags = newflags; + *version = newversion; + (*name)[i] = strdup(n1); + (*flags)[i] = XMLFlagToInt(rel1); + (*version)[i] = strdup(v1); + i++; + (*name)[i] = strdup(n2); + (*flags)[i] = XMLFlagToInt(rel2); + (*version)[i] = strdup(v2); + } else { + logmsg(LOG_WARNING,"getXMLPackageNFV: don't know how to process '%s'; ignoring", n); + (*name)[i] = n; + (*flags)[i] = RPMSENSE_ANY; + (*version)[i] = NULL; + } } - (*version)[i] = strdup(buf); i++; } }