From 297e18f2c8d08055502938bcee35f15f0dd7af0e Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Tue, 26 Jul 2022 17:08:48 +0000 Subject: [PATCH] tuple: add flags parameter to pkgconf_tuple_parse --- libpkgconf/dependency.c | 2 +- libpkgconf/fragment.c | 5 ++-- libpkgconf/libpkgconf.h | 6 ++-- libpkgconf/pkg.c | 20 ++++++------- libpkgconf/tuple.c | 65 +++++++++++++++++++++++++++++++---------- 5 files changed, 67 insertions(+), 31 deletions(-) diff --git a/libpkgconf/dependency.c b/libpkgconf/dependency.c index 8602a2b..08dcbb2 100644 --- a/libpkgconf/dependency.c +++ b/libpkgconf/dependency.c @@ -434,7 +434,7 @@ pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_h void pkgconf_dependency_parse(pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist, const char *depends, unsigned int flags) { - char *kvdepends = pkgconf_tuple_parse(client, &pkg->vars, depends); + char *kvdepends = pkgconf_tuple_parse(client, &pkg->vars, depends, pkg->flags); pkgconf_dependency_parse_str(client, deplist, kvdepends, flags); free(kvdepends); diff --git a/libpkgconf/fragment.c b/libpkgconf/fragment.c index 80d9ba2..9a618c8 100644 --- a/libpkgconf/fragment.c +++ b/libpkgconf/fragment.c @@ -663,15 +663,16 @@ pkgconf_fragment_free(pkgconf_list_t *list) * :param pkgconf_client_t* client: The pkgconf client being accessed. * :param pkgconf_list_t* list: The `fragment list` to add the fragment entries to. * :param pkgconf_list_t* vars: A list of variables to use for variable substitution. + * :param uint flags: Any parsing flags to be aware of. * :param char* value: The string to parse into fragments. * :return: true on success, false on parse error */ bool -pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value) +pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value, unsigned int flags) { int i, ret, argc; char **argv; - char *repstr = pkgconf_tuple_parse(client, vars, value); + char *repstr = pkgconf_tuple_parse(client, vars, value, flags); PKGCONF_TRACE(client, "post-subst: [%s] -> [%s]", value, repstr); diff --git a/libpkgconf/libpkgconf.h b/libpkgconf/libpkgconf.h index 4634047..ec71c25 100644 --- a/libpkgconf/libpkgconf.h +++ b/libpkgconf/libpkgconf.h @@ -346,7 +346,7 @@ typedef struct pkgconf_fragment_render_ops_ { } pkgconf_fragment_render_ops_t; typedef bool (*pkgconf_fragment_filter_func_t)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data); -PKGCONF_API bool pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value); +PKGCONF_API bool pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value, unsigned int flags); PKGCONF_API void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string); PKGCONF_API void pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private); PKGCONF_API void pkgconf_fragment_copy_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base); @@ -362,9 +362,9 @@ PKGCONF_API bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, PKGCONF_API char *pkgconf_fgetline(char *line, size_t size, FILE *stream); /* tuple.c */ -PKGCONF_API pkgconf_tuple_t *pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *parent, const char *key, const char *value, bool parse); +PKGCONF_API pkgconf_tuple_t *pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *parent, const char *key, const char *value, bool parse, unsigned int flags); PKGCONF_API char *pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key); -PKGCONF_API char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *list, const char *value); +PKGCONF_API char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *list, const char *value, unsigned int flags); PKGCONF_API void pkgconf_tuple_free(pkgconf_list_t *list); PKGCONF_API void pkgconf_tuple_free_entry(pkgconf_tuple_t *tuple, pkgconf_list_t *list); PKGCONF_API void pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value); diff --git a/libpkgconf/pkg.c b/libpkgconf/pkg.c index 1998b6d..28bbc26 100644 --- a/libpkgconf/pkg.c +++ b/libpkgconf/pkg.c @@ -92,7 +92,7 @@ pkgconf_pkg_parser_tuple_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, cons (void) lineno; char **dest = (char **)((char *) pkg + offset); - *dest = pkgconf_tuple_parse(client, &pkg->vars, value); + *dest = pkgconf_tuple_parse(client, &pkg->vars, value, pkg->flags); } static void @@ -105,7 +105,7 @@ pkgconf_pkg_parser_version_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, co char **dest = (char **)((char *) pkg + offset); /* cut at any detected whitespace */ - p = pkgconf_tuple_parse(client, &pkg->vars, value); + p = pkgconf_tuple_parse(client, &pkg->vars, value, pkg->flags); len = strcspn(p, " \t"); if (len != strlen(p)) @@ -124,7 +124,7 @@ static void pkgconf_pkg_parser_fragment_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value) { pkgconf_list_t *dest = (pkgconf_list_t *)((char *) pkg + offset); - bool ret = pkgconf_fragment_parse(client, dest, &pkg->vars, value); + bool ret = pkgconf_fragment_parse(client, dest, &pkg->vars, value, pkg->flags); if (!ret) { @@ -312,10 +312,10 @@ pkgconf_pkg_parser_value_set(void *opaque, const size_t lineno, const char *keyw pkgconf_strlcpy(newvalue, pkg->prefix->value, sizeof newvalue); pkgconf_strlcat(newvalue, canonicalized_value + strlen(pkg->orig_prefix->value), sizeof newvalue); - pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, newvalue, false); + pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, newvalue, false, pkg->flags); } else if (strcmp(keyword, pkg->owner->prefix_varname) || !(pkg->owner->flags & PKGCONF_PKG_PKGF_REDEFINE_PREFIX)) - pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, value, true); + pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, value, true, pkg->flags); else { char pathbuf[PKGCONF_ITEM_SIZE]; @@ -324,12 +324,12 @@ pkgconf_pkg_parser_value_set(void *opaque, const size_t lineno, const char *keyw if (relvalue != NULL) { char *prefix_value = convert_path_to_value(relvalue); - pkg->orig_prefix = pkgconf_tuple_add(pkg->owner, &pkg->vars, "orig_prefix", canonicalized_value, true); - pkg->prefix = pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, prefix_value, false); + pkg->orig_prefix = pkgconf_tuple_add(pkg->owner, &pkg->vars, "orig_prefix", canonicalized_value, true, pkg->flags); + pkg->prefix = pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, prefix_value, false, pkg->flags); free(prefix_value); } else - pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, value, true); + pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, value, true, pkg->flags); } } @@ -409,7 +409,7 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE * pkg->pc_filedir = pkg_get_parent_dir(pkg); char *pc_filedir_value = convert_path_to_value(pkg->pc_filedir); - pkgconf_tuple_add(client, &pkg->vars, "pcfiledir", pc_filedir_value, true); + pkgconf_tuple_add(client, &pkg->vars, "pcfiledir", pc_filedir_value, true, pkg->flags); free(pc_filedir_value); /* If pc_filedir is outside of sysroot_dir, override sysroot_dir for this @@ -417,7 +417,7 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE * * See https://github.com/pkgconf/pkgconf/issues/213 */ if (client->sysroot_dir && strncmp(pkg->pc_filedir, client->sysroot_dir, strlen(client->sysroot_dir))) - pkgconf_tuple_add(client, &pkg->vars, "pc_sysrootdir", "", false); + pkgconf_tuple_add(client, &pkg->vars, "pc_sysrootdir", "", false, pkg->flags); /* make module id */ if ((idptr = strrchr(pkg->filename, PKG_DIR_SEP_S)) != NULL) diff --git a/libpkgconf/tuple.c b/libpkgconf/tuple.c index 08c9c82..cf0103e 100644 --- a/libpkgconf/tuple.c +++ b/libpkgconf/tuple.c @@ -45,7 +45,7 @@ void pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value) { - pkgconf_tuple_add(client, &client->global_vars, key, value, false); + pkgconf_tuple_add(client, &client->global_vars, key, value, false, 0); } /* @@ -161,6 +161,45 @@ dequote(const char *value) return buf; } +static const char * +find_sysroot(const pkgconf_client_t *client, pkgconf_list_t *vars) +{ + const char *sysroot_dir; + + sysroot_dir = pkgconf_tuple_find(client, vars, "pc_sysrootdir"); + if (sysroot_dir == NULL) + sysroot_dir = client->sysroot_dir; + + return sysroot_dir; +} + +static bool +should_rewrite_sysroot(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *buf, unsigned int flags) +{ + const char *sysroot_dir; + + if (flags & PKGCONF_PKG_PROPF_UNINSTALLED && !(client->flags & PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES)) + return false; + + sysroot_dir = find_sysroot(client, vars); + if (sysroot_dir == NULL) + return false; + + if (*buf != '/') + return false; + + if (!strcmp(sysroot_dir, "/")) + return false; + + if (strlen(buf) <= strlen(sysroot_dir)) + return false; + + if (strstr(buf + strlen(sysroot_dir), sysroot_dir) == NULL) + return false; + + return true; +} + /* * !doc * @@ -177,7 +216,7 @@ dequote(const char *value) * :rtype: pkgconf_tuple_t * */ pkgconf_tuple_t * -pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key, const char *value, bool parse) +pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key, const char *value, bool parse, unsigned int flags) { char *dequote_value; pkgconf_tuple_t *tuple = calloc(sizeof(pkgconf_tuple_t), 1); @@ -190,7 +229,7 @@ pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *list, const ch tuple->key = strdup(key); if (parse) - tuple->value = pkgconf_tuple_parse(client, list, dequote_value); + tuple->value = pkgconf_tuple_parse(client, list, dequote_value, flags); else tuple->value = strdup(dequote_value); @@ -233,18 +272,19 @@ pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const c /* * !doc * - * .. c:function:: char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value) + * .. c:function:: char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value, unsigned int flags) * * Parse an expression for variable substitution. * * :param pkgconf_client_t* client: The pkgconf client object to access. * :param pkgconf_list_t* list: The variable list to search for variables (along side the global variable list). * :param char* value: The ``key=value`` string to parse. + * :param uint flags: Any flags to consider while parsing. * :return: the variable data with any variables substituted * :rtype: char * */ char * -pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value) +pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value, unsigned int flags) { char buf[PKGCONF_BUFSIZE]; const char *ptr; @@ -302,7 +342,7 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const if (kv != NULL) { - parsekv = pkgconf_tuple_parse(client, vars, kv); + parsekv = pkgconf_tuple_parse(client, vars, kv, flags); strncpy(bptr, parsekv, PKGCONF_BUFSIZE - (bptr - buf)); bptr += strlen(parsekv); @@ -329,18 +369,13 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const * safe to skip ahead in the string to scan for our sysroot dir. * * Finally, we call pkgconf_path_relocate() to clean the path of spurious elements. + * + * New in 1.9: Only attempt to rewrite the sysroot if we are not processing an uninstalled package. */ - const char *sysroot_dir = pkgconf_tuple_find(client, vars, "pc_sysrootdir"); - if (sysroot_dir == NULL) - sysroot_dir = client->sysroot_dir; - - if (*buf == '/' && - sysroot_dir != NULL && - strcmp(sysroot_dir, "/") != 0 && - strlen(buf) > strlen(sysroot_dir) && - strstr(buf + strlen(sysroot_dir), sysroot_dir) != NULL) + if (should_rewrite_sysroot(client, vars, buf, flags)) { char cleanpath[PKGCONF_ITEM_SIZE]; + const char *sysroot_dir = find_sysroot(client, vars); pkgconf_strlcpy(cleanpath, buf + strlen(sysroot_dir), sizeof cleanpath); pkgconf_path_relocate(cleanpath, sizeof cleanpath);