From 12ff14f8569f7d4817f528f716414645f4257b81 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Wed, 9 Jul 2014 01:23:51 -0500 Subject: [PATCH] fragments: handle sysroot dir munging directly in a smarter way Previously we just let the tuple system handle it, but pkg-config modules which do not define variables were able to get by the checks. While here, check to ensure we do not duplicate the sysroot dir twice if it is already defined in the pkg-config module file. Downstream bug: https://bugs.busybox.net/show_bug.cgi?id=5750 --- fragment.c | 29 +++++++++++++++++++++++++---- main.c | 11 ++++++++++- pkg.c | 21 +++++---------------- pkg.h | 4 ++-- tests/lib1/sysroot-dir.pc | 5 +++++ tests/run.sh.in | 5 +++++ 6 files changed, 52 insertions(+), 23 deletions(-) create mode 100644 tests/lib1/sysroot-dir.pc diff --git a/fragment.c b/fragment.c index 17a0a58..e921120 100644 --- a/fragment.c +++ b/fragment.c @@ -16,8 +16,29 @@ #include "pkg.h" #include "bsdstubs.h" +static inline char * +pkg_fragment_copy_munged(const char *source, unsigned int flags) +{ + char mungebuf[PKG_BUFSIZE]; + char *sysroot_dir; + + if (!(flags & PKGF_MUNGE_SYSROOT_PREFIX)) + return strdup(source); + + sysroot_dir = pkg_tuple_find_global("pc_sysrootdir"); + + if (*source != '/' || + (sysroot_dir != NULL && !strncmp(sysroot_dir, source, strlen(sysroot_dir)))) + return strdup(source); + + strlcpy(mungebuf, sysroot_dir, sizeof mungebuf); + strlcat(mungebuf, source, sizeof mungebuf); + + return strdup(mungebuf); +} + void -pkg_fragment_add(pkg_list_t *list, const char *string) +pkg_fragment_add(pkg_list_t *list, const char *string, unsigned int flags) { pkg_fragment_t *frag; @@ -26,7 +47,7 @@ pkg_fragment_add(pkg_list_t *list, const char *string) frag = calloc(sizeof(pkg_fragment_t), 1); frag->type = *(string + 1); - frag->data = strdup(string + 2); + frag->data = pkg_fragment_copy_munged(string + 2, flags); } else { @@ -156,7 +177,7 @@ pkg_fragment_free(pkg_list_t *list) } void -pkg_fragment_parse(pkg_list_t *list, pkg_list_t *vars, const char *value) +pkg_fragment_parse(pkg_list_t *list, pkg_list_t *vars, const char *value, unsigned int flags) { int i, argc; char **argv; @@ -165,7 +186,7 @@ pkg_fragment_parse(pkg_list_t *list, pkg_list_t *vars, const char *value) pkg_argv_split(repstr, &argc, &argv); for (i = 0; i < argc; i++) - pkg_fragment_add(list, argv[i]); + pkg_fragment_add(list, argv[i], flags); pkg_argv_free(argv); free(repstr); diff --git a/main.c b/main.c index a6f0494..ce07553 100644 --- a/main.c +++ b/main.c @@ -290,11 +290,20 @@ print_variable(pkg_t *pkg, void *data, unsigned int flags) { if (*(req->buf) == '\0') { - strlcpy(req->buf, var, sizeof(req->buf)); + memset(req->buf, 0, sizeof(req->buf)); + + if (*var == '/' && (flags & PKGF_MUNGE_SYSROOT_PREFIX)) + strlcat(req->buf, sysroot_dir, sizeof(req->buf)); + + strlcat(req->buf, var, sizeof(req->buf)); return; } strlcat(req->buf, " ", sizeof(req->buf)); + + if (*var == '/' && (flags & PKGF_MUNGE_SYSROOT_PREFIX)) + strlcat(req->buf, sysroot_dir, sizeof(req->buf)); + strlcat(req->buf, var, sizeof(req->buf)); } } diff --git a/pkg.c b/pkg.c index 9349a69..caed158 100644 --- a/pkg.c +++ b/pkg.c @@ -247,13 +247,13 @@ pkg_new_from_file(const char *filename, FILE *f, unsigned int flags) else if (!strcmp(key, "Version")) pkg->version = pkg_tuple_parse(&pkg->vars, value); else if (!strcasecmp(key, "CFLAGS")) - pkg_fragment_parse(&pkg->cflags, &pkg->vars, value); + pkg_fragment_parse(&pkg->cflags, &pkg->vars, value, flags); else if (!strcasecmp(key, "CFLAGS.private")) - pkg_fragment_parse(&pkg->cflags_private, &pkg->vars, value); + pkg_fragment_parse(&pkg->cflags_private, &pkg->vars, value, flags); else if (!strcasecmp(key, "LIBS")) - pkg_fragment_parse(&pkg->libs, &pkg->vars, value); + pkg_fragment_parse(&pkg->libs, &pkg->vars, value, flags); else if (!strcasecmp(key, "LIBS.private")) - pkg_fragment_parse(&pkg->libs_private, &pkg->vars, value); + pkg_fragment_parse(&pkg->libs_private, &pkg->vars, value, flags); else if (!strcmp(key, "Requires")) pkg_dependency_parse(pkg, &pkg->requires, value); else if (!strcmp(key, "Requires.private")) @@ -262,18 +262,7 @@ pkg_new_from_file(const char *filename, FILE *f, unsigned int flags) pkg_dependency_parse(pkg, &pkg->conflicts, value); break; case '=': - if (!(flags & PKGF_MUNGE_SYSROOT_PREFIX) || strcasecmp(key, "prefix")) - pkg_tuple_add(&pkg->vars, key, value); - else - { - char mungebuf[PKG_BUFSIZE]; - char *sysroot_dir = pkg_tuple_find_global("pc_sysrootdir"); - - strlcpy(mungebuf, sysroot_dir, sizeof mungebuf); - strlcat(mungebuf, value, sizeof mungebuf); - - pkg_tuple_add(&pkg->vars, key, mungebuf); - } + pkg_tuple_add(&pkg->vars, key, value); break; default: break; diff --git a/pkg.h b/pkg.h index 176f4cd..1ff5d3d 100644 --- a/pkg.h +++ b/pkg.h @@ -157,8 +157,8 @@ int pkg_argv_split(const char *src, int *argc, char ***argv); void pkg_argv_free(char **argv); /* fragment.c */ -void pkg_fragment_parse(pkg_list_t *list, pkg_list_t *vars, const char *value); -void pkg_fragment_add(pkg_list_t *list, const char *string); +void pkg_fragment_parse(pkg_list_t *list, pkg_list_t *vars, const char *value, unsigned int flags); +void pkg_fragment_add(pkg_list_t *list, const char *string, unsigned int flags); void pkg_fragment_copy(pkg_list_t *list, pkg_fragment_t *base, unsigned int flags); void pkg_fragment_delete(pkg_list_t *list, pkg_fragment_t *node); void pkg_fragment_free(pkg_list_t *list); diff --git a/tests/lib1/sysroot-dir.pc b/tests/lib1/sysroot-dir.pc new file mode 100644 index 0000000..8334c50 --- /dev/null +++ b/tests/lib1/sysroot-dir.pc @@ -0,0 +1,5 @@ +Name: sysroot-dir +Description: Package for testing whether sysroot dirs are repeated or not +Version: 1 +CFlags: -I/sysroot/include +Libs: -L/sysroot/lib -lfoo diff --git a/tests/run.sh.in b/tests/run.sh.in index 626bbd8..102dbbb 100644 --- a/tests/run.sh.in +++ b/tests/run.sh.in @@ -244,6 +244,11 @@ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --variable=foo case-sensitivity run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --variable=Foo case-sensitivity" \ "4" +run_test "PKG_CONFIG_PATH='${selfdir}/lib1' PKG_CONFIG_SYSROOT_DIR='/sysroot' ${1} --libs sysroot-dir" \ + '-L/sysroot/lib -lfoo' +run_test "PKG_CONFIG_PATH='${selfdir}/lib1' PKG_CONFIG_SYSROOT_DIR='/sysroot2' ${1} --libs sysroot-dir" \ + '-L/sysroot2/sysroot/lib -lfoo' + # 10) tests for internal getopt implementation with options at the end if [ "x@STRICT_MODE@" = "xno" ]; then run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} foo --libs" \