1 |
commit: c8bf4b933d88520d7a9ad6f856412e62772f044f |
2 |
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun Jan 19 16:31:23 2020 +0000 |
4 |
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Jan 19 16:31:23 2020 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=c8bf4b93 |
7 |
|
8 |
libq/tree: fix Coverity 206560 Resource leak |
9 |
|
10 |
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org> |
11 |
|
12 |
libq/tree.c | 52 +++++++++++++++++++++++++++++++++++++--------------- |
13 |
1 file changed, 37 insertions(+), 15 deletions(-) |
14 |
|
15 |
diff --git a/libq/tree.c b/libq/tree.c |
16 |
index 94f9665..2efdb7c 100644 |
17 |
--- a/libq/tree.c |
18 |
+++ b/libq/tree.c |
19 |
@@ -138,8 +138,12 @@ tree_open_binpkg(const char *sroot, const char *spkg) |
20 |
ret->cachetype = CACHE_BINPKGS; |
21 |
|
22 |
snprintf(buf, sizeof(buf), "%s%s/%s", sroot, spkg, binpkg_packages); |
23 |
- if (eat_file(buf, &ret->pkgs, &ret->pkgslen)) |
24 |
+ if (eat_file(buf, &ret->pkgs, &ret->pkgslen)) { |
25 |
ret->cachetype = CACHE_PACKAGES; |
26 |
+ } else if (ret->pkgs != NULL) { |
27 |
+ free(ret->pkgs); |
28 |
+ ret->pkgs = NULL; |
29 |
+ } |
30 |
} |
31 |
|
32 |
return ret; |
33 |
@@ -1237,10 +1241,12 @@ tree_foreach_packages(tree_ctx *ctx, tree_pkg_cb callback, void *priv) |
34 |
|
35 |
/* reused for every entry */ |
36 |
tree_cat_ctx *cat = NULL; |
37 |
- tree_pkg_ctx *pkg = xzalloc(sizeof(tree_pkg_ctx)); |
38 |
- tree_pkg_meta *meta = xzalloc(sizeof(tree_pkg_meta)); |
39 |
+ tree_pkg_ctx pkg; |
40 |
+ tree_pkg_meta meta; |
41 |
depend_atom *atom = NULL; |
42 |
|
43 |
+ memset(&meta, 0, sizeof(meta)); |
44 |
+ |
45 |
do { |
46 |
/* find next line */ |
47 |
c = NULL; |
48 |
@@ -1257,32 +1263,41 @@ tree_foreach_packages(tree_ctx *ctx, tree_pkg_cb callback, void *priv) |
49 |
if (atom != NULL) { |
50 |
size_t pkgnamelen; |
51 |
|
52 |
+ memset(&pkg, 0, sizeof(pkg)); |
53 |
+ |
54 |
/* store meta ptr in repo->pkgs, such that get_pkg_meta |
55 |
* can grab it from there (for free) */ |
56 |
- ctx->pkgs = (char *)meta; |
57 |
+ c = ctx->pkgs; |
58 |
+ ctx->pkgs = (char *)&meta; |
59 |
|
60 |
if (cat == NULL || strcmp(cat->name, atom->CATEGORY) != 0) |
61 |
{ |
62 |
- if (cat != NULL) |
63 |
+ if (cat != NULL) { |
64 |
+ atom_implode((depend_atom *)cat->pkg_ctxs); |
65 |
+ cat->pkg_ctxs = NULL; |
66 |
tree_close_cat(cat); |
67 |
- pkg->cat_ctx = cat = tree_open_cat(ctx, atom->CATEGORY); |
68 |
+ } |
69 |
+ pkg.cat_ctx = cat = tree_open_cat(ctx, atom->CATEGORY); |
70 |
+ cat->pkg_ctxs = (tree_pkg_ctx **)atom; /* for name */ |
71 |
} |
72 |
pkgnamelen = snprintf(pkgname, sizeof(pkgname), |
73 |
"%s.tbz2", atom->PF); |
74 |
pkgname[pkgnamelen - (sizeof(".tbz2") - 1)] = '\0'; |
75 |
- pkg->name = pkgname; |
76 |
- pkg->slot = meta->Q_SLOT == NULL ? (char *)"0" : meta->Q_SLOT; |
77 |
- pkg->repo = ctx->repo; |
78 |
- pkg->atom = atom; |
79 |
- pkg->fd = 0; /* intentional, meta has already been read */ |
80 |
+ pkg.name = pkgname; |
81 |
+ pkg.slot = meta.Q_SLOT == NULL ? (char *)"0" : meta.Q_SLOT; |
82 |
+ pkg.repo = ctx->repo; |
83 |
+ pkg.atom = atom; |
84 |
+ pkg.fd = 0; /* intentional, meta has already been read */ |
85 |
|
86 |
/* do call callback with pkg_atom (populate cat and pkg) */ |
87 |
- ret |= callback(pkg, priv); |
88 |
+ ret |= callback(&pkg, priv); |
89 |
|
90 |
- atom_implode(atom); |
91 |
+ ctx->pkgs = c; |
92 |
+ if (atom != (depend_atom *)cat->pkg_ctxs) |
93 |
+ atom_implode(atom); |
94 |
} |
95 |
|
96 |
- memset(meta, 0, sizeof(meta[0])); |
97 |
+ memset(&meta, 0, sizeof(meta)); |
98 |
atom = NULL; |
99 |
if (len > 0) { /* hop over \n */ |
100 |
p++; |
101 |
@@ -1318,7 +1333,7 @@ tree_foreach_packages(tree_ctx *ctx, tree_pkg_cb callback, void *priv) |
102 |
#define match_key(X) match_key2(X,X) |
103 |
#define match_key2(X,Y) \ |
104 |
} else if (strcmp(p, #X) == 0) { \ |
105 |
- meta->Q_##Y = c |
106 |
+ meta.Q_##Y = c |
107 |
match_key(DEFINED_PHASES); |
108 |
match_key(DEPEND); |
109 |
match_key2(DESC, DESCRIPTION); |
110 |
@@ -1339,8 +1354,15 @@ tree_foreach_packages(tree_ctx *ctx, tree_pkg_cb callback, void *priv) |
111 |
p = q; |
112 |
} while (len > 0); |
113 |
|
114 |
+ if (cat != NULL) { |
115 |
+ atom_implode((depend_atom *)cat->pkg_ctxs); |
116 |
+ cat->pkg_ctxs = NULL; |
117 |
+ tree_close_cat(cat); |
118 |
+ } |
119 |
+ |
120 |
/* ensure we don't free a garbage pointer */ |
121 |
ctx->repo = NULL; |
122 |
+ ctx->do_sort = false; |
123 |
|
124 |
return ret; |
125 |
} |