commit:     737cbc7da8473b7f2cd98b18201bf438c7e6c8c7
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Tue Apr 30 07:52:27 2019 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Tue Apr 30 07:52:27 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=737cbc7d

libq/cache: fix some issues (likely bugs #684252 and #684476)

cache_next_pkg: fix package traversal and cat_ctx shoveling
cache_read_file_ebuild: fix key parsing (not to loop forever)
cache_pkg_read: open correct file for ebuild case

Bug: https://bugs.gentoo.org/684252
Bug: https://bugs.gentoo.org/684476
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>

 libq/cache.c | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/libq/cache.c b/libq/cache.c
index efc47bc..504b6d3 100644
--- a/libq/cache.c
+++ b/libq/cache.c
@@ -144,14 +144,17 @@ cache_next_pkg(cache_cat_ctx *cat_ctx)
                                q_vdb_ctx *pkgdir = ctx->ebuilddir_ctx;
 
                                if (pkgdir == NULL)
-                                       pkgdir = ctx->ebuilddir_ctx = 
xzalloc(sizeof(q_vdb_ctx));
+                                       pkgdir = ctx->ebuilddir_ctx = 
xmalloc(sizeof(q_vdb_ctx));
+                               memset(ctx->ebuilddir_ctx, '\0', 
sizeof(*ctx->ebuilddir_ctx));
 
                                if ((ctx->ebuilddir_pkg_ctx = 
q_vdb_next_pkg(cat_ctx)) == NULL)
                                        return NULL;
 
                                pkgdir->portroot_fd = -1;
                                pkgdir->vdb_fd = cat_ctx->fd;
-                               pkgdir->dir = NULL;
+                               pkgdir->do_sort = ctx->do_sort;
+                               pkgdir->repo = ctx->repo;
+                               pkgdir->cachetype = ctx->cachetype;
 
                                ctx->ebuilddir_cat_ctx =
                                        q_vdb_open_cat(pkgdir, 
ctx->ebuilddir_pkg_ctx->name);
@@ -159,6 +162,7 @@ cache_next_pkg(cache_cat_ctx *cat_ctx)
 
                        ret = q_vdb_next_pkg(ctx->ebuilddir_cat_ctx);
                        if (ret == NULL) {
+                               q_vdb_close_cat(ctx->ebuilddir_cat_ctx);
                                ctx->ebuilddir_pkg_ctx = NULL;
                        } else {
                                if ((p = strstr(ret->name, ".ebuild")) == NULL) 
{
@@ -166,7 +170,7 @@ cache_next_pkg(cache_cat_ctx *cat_ctx)
                                        ret = NULL;
                                } else {
                                        /* "zap" the pkg such that it looks 
like CAT/P */
-                                       ret->cat_ctx = cat_ctx;
+                                       ret->cat_ctx->name = cat_ctx->name;
                                        *p = '\0';
                                }
                        }
@@ -366,6 +370,7 @@ cache_read_file_ebuild(cache_pkg_ctx *pkg_ctx)
        char *q;
        char *r;
        char **key;
+       bool findnl;
 
        if ((f = fdopen(pkg_ctx->fd, "r")) == NULL)
                goto err;
@@ -382,8 +387,6 @@ cache_read_file_ebuild(cache_pkg_ctx *pkg_ctx)
 
        p = ret->_data;
        do {
-               if ((p = strchr(p, '\n')) == NULL)
-                       break;
                q = p;
                while (*p >= 'A' && *p <= 'Z')
                        p++;
@@ -411,11 +414,12 @@ cache_read_file_ebuild(cache_pkg_ctx *pkg_ctx)
 #undef match_key
                }
 
+               findnl = true;
                if (key != NULL) {
                        q = p;
                        if (*q == '"' || *q == '\'') {
                                /* find matching quote */
-                               q = ++p;
+                               q = p;
                                do {
                                        while (*p != '\0' && *p != *q)
                                                p++;
@@ -428,14 +432,20 @@ cache_read_file_ebuild(cache_pkg_ctx *pkg_ctx)
                                        }
                                        break;
                                } while (1);
+                               q++;
                        } else {
                                /* find first whitespace */
                                while (!isspace((int)*p))
                                        p++;
+                               if (*p == '\n')
+                                       findnl = false;
                        }
-                       *p = '\0';
+                       *p++ = '\0';
                        *key = q;
                }
+
+               if (findnl && (p = strchr(p, '\n')) != NULL)
+                       p++;
        } while (p != NULL);
 
        fclose(f);
@@ -458,8 +468,17 @@ cache_pkg_read(cache_pkg_ctx *pkg_ctx)
        cache_ctx *ctx = (cache_ctx *)(pkg_ctx->cat_ctx->ctx);
 
        if (pkg_ctx->fd == -1) {
-               pkg_ctx->fd = openat(pkg_ctx->cat_ctx->fd, pkg_ctx->name,
-                               O_RDONLY|O_CLOEXEC);
+               if (ctx->cachetype != CACHE_EBUILD) {
+                       pkg_ctx->fd = openat(pkg_ctx->cat_ctx->fd, 
pkg_ctx->name,
+                                       O_RDONLY|O_CLOEXEC);
+               } else {
+                       char *p = (char *)pkg_ctx->name;
+                       p += strlen(p);
+                       *p = '.';
+                       pkg_ctx->fd = openat(pkg_ctx->cat_ctx->fd, 
pkg_ctx->name,
+                                       O_RDONLY|O_CLOEXEC);
+                       *p = '\0';
+               }
                if (pkg_ctx->fd == -1)
                        return NULL;
        }

Reply via email to