parse: improve version parsing resiliency

pull/1/merge
William Pitcock 2011-07-26 19:51:04 -05:00
parent 5869405054
commit 91d61a76a2
1 changed files with 19 additions and 6 deletions

25
parse.c
View File

@ -121,6 +121,8 @@ typedef enum {
INSIDE_VERSION = 5 INSIDE_VERSION = 5
} parse_state_t; } parse_state_t;
#define DEBUG_PARSE 0
static pkg_dependency_t * static pkg_dependency_t *
pkg_dependency_add(pkg_dependency_t *head, const char *package, const char *version, pkg_comparator_t compare) pkg_dependency_add(pkg_dependency_t *head, const char *package, const char *version, pkg_comparator_t compare)
{ {
@ -129,7 +131,7 @@ pkg_dependency_add(pkg_dependency_t *head, const char *package, const char *vers
dep = calloc(sizeof(pkg_dependency_t), 1); dep = calloc(sizeof(pkg_dependency_t), 1);
dep->package = strdup(package); dep->package = strdup(package);
if (dep->version != NULL) if (version != NULL)
dep->version = strdup(version); dep->version = strdup(version);
dep->compare = compare; dep->compare = compare;
@ -138,10 +140,13 @@ pkg_dependency_add(pkg_dependency_t *head, const char *package, const char *vers
if (dep->prev != NULL) if (dep->prev != NULL)
dep->prev->next = dep; dep->prev->next = dep;
#if DEBUG_PARSE
fprintf(stderr, "--> %s %d %s\n", dep->package, dep->compare, dep->version);
#endif
return dep; return dep;
} }
#define DEBUG_PARSE 0
#define MODULE_SEPARATOR(c) ((c) == ',' || isspace ((c))) #define MODULE_SEPARATOR(c) ((c) == ',' || isspace ((c)))
#define OPERATOR_CHAR(c) ((c) == '<' || (c) == '>' || (c) == '!' || (c) == '=') #define OPERATOR_CHAR(c) ((c) == '<' || (c) == '>' || (c) == '!' || (c) == '=')
@ -182,6 +187,7 @@ parse_deplist(pkg_t *pkg, const char *depends)
char *package, *version; char *package, *version;
strncpy(buf, kvdepends, BUFSIZ); strncpy(buf, kvdepends, BUFSIZ);
strncat(buf, " ", BUFSIZ);
free(kvdepends); free(kvdepends);
while (*ptr) while (*ptr)
@ -192,7 +198,6 @@ parse_deplist(pkg_t *pkg, const char *depends)
if (!MODULE_SEPARATOR(*ptr)) if (!MODULE_SEPARATOR(*ptr))
state = INSIDE_MODULE_NAME; state = INSIDE_MODULE_NAME;
compare = PKG_ANY;
break; break;
case INSIDE_MODULE_NAME: case INSIDE_MODULE_NAME:
@ -236,7 +241,7 @@ parse_deplist(pkg_t *pkg, const char *depends)
if (state == OUTSIDE_MODULE) if (state == OUTSIDE_MODULE)
{ {
deplist = pkg_dependency_add(deplist, package, NULL, PKG_ANY); deplist = pkg_dependency_add(deplist, package, NULL, compare);
if (deplist_head == NULL) if (deplist_head == NULL)
deplist_head = deplist; deplist_head = deplist;
@ -252,6 +257,8 @@ parse_deplist(pkg_t *pkg, const char *depends)
free(version); free(version);
version = NULL; version = NULL;
} }
compare = PKG_ANY;
} }
break; break;
@ -303,6 +310,10 @@ parse_deplist(pkg_t *pkg, const char *depends)
break; break;
case AFTER_OPERATOR: case AFTER_OPERATOR:
#if DEBUG_PARSE
fprintf(stderr, "Found op: %d\n", compare);
#endif
if (!isspace(*ptr)) if (!isspace(*ptr))
{ {
vstart = ptr; vstart = ptr;
@ -313,13 +324,13 @@ parse_deplist(pkg_t *pkg, const char *depends)
case INSIDE_VERSION: case INSIDE_VERSION:
if (MODULE_SEPARATOR(*ptr) || *(ptr + 1) == '\0') if (MODULE_SEPARATOR(*ptr) || *(ptr + 1) == '\0')
{ {
version = strndup(vstart, ptr - vstart); version = strndup(vstart, (ptr - vstart));
state = OUTSIDE_MODULE; state = OUTSIDE_MODULE;
#if DEBUG_PARSE #if DEBUG_PARSE
fprintf(stderr, "Found version: %s\n", version); fprintf(stderr, "Found version: %s\n", version);
#endif #endif
deplist = pkg_dependency_add(deplist, package, version, PKG_ANY); deplist = pkg_dependency_add(deplist, package, version, compare);
if (deplist_head == NULL) if (deplist_head == NULL)
deplist_head = deplist; deplist_head = deplist;
@ -335,6 +346,8 @@ parse_deplist(pkg_t *pkg, const char *depends)
free(version); free(version);
version = NULL; version = NULL;
} }
compare = PKG_ANY;
} }
if (state == OUTSIDE_MODULE) if (state == OUTSIDE_MODULE)