[PATCH 1/4] dpkg --configure: plug a small memory leak
Free filename buffers when returning early from
deferred_configure_conffile().
While we’re at it, speed up the initialization of the buffer
cdr2. The current code scans cdr for its end unnecessarily,
twice, and then uses that length to calculate a buffer size about
40 bytes too large.
Also let the filename cdr acquire extensions in the same way as
cdr2. This should make it a little easier to change the
extension of cdr more often.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
src/configure.c | 36 ++++++++++++++++++++++--------------
1 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/src/configure.c b/src/configure.c
index 3ae745b..6c9b7da 100644
--- a/src/configure.c
+++ b/src/configure.c
@@ -73,8 +73,12 @@ deferred_configure_conffile(struct pkginfo *pkg, struct conffile *conff)
int useredited, distedited;
enum conffopt what;
struct stat stab;
- struct varbuf cdr = VARBUF_INIT, cdr2 = VARBUF_INIT;
- char *cdr2rest;
+ struct varbuf cdr = VARBUF_INIT, cdr2;
+ const int max_extension_sz = max(
+ max(sizeof(DPKGNEWEXT),
+ sizeof(DPKGOLDEXT)),
+ sizeof(DPKGDISTEXT));
+ char *cdrrest, *cdr2rest;
int r;
usenode = namenodetouse(findnamenode(conff->name, fnn_nocopy), pkg);
@@ -82,23 +86,29 @@ deferred_configure_conffile(struct pkginfo *pkg, struct conffile *conff)
r = conffderef(pkg, &cdr, usenode->name);
if (r == -1) {
conff->hash = EMPTY_HASH;
+ varbuffree(&cdr);
return;
}
md5hash(pkg, currenthash, cdr.buf);
- varbufreset(&cdr2);
- varbufaddstr(&cdr2, cdr.buf);
- varbufaddc(&cdr2, 0);
- /* XXX: Make sure there's enough room for extensions. */
- varbuf_grow(&cdr2, 50);
- cdr2rest = cdr2.buf + strlen(cdr.buf);
+ /* Make sure there's enough room for extensions. */
+ varbuf_grow(&cdr, max_extension_sz - 1);
+ varbufinit(&cdr2, cdr.used);
+ cdr.used -= max_extension_sz - 1;
+
+ varbufaddbuf(&cdr2, cdr.buf, cdr.used);
+ cdrrest = cdr.buf + cdr.used - 1;
+ cdr2rest = cdr2.buf + cdr2.used - 1;
/* From now on we can just strcpy(cdr2rest, extension); */
- strcpy(cdr2rest, DPKGNEWEXT);
/* If the .dpkg-new file is no longer there, ignore this one. */
+ strcpy(cdr2rest, DPKGNEWEXT);
if (lstat(cdr2.buf, &stab)) {
- if (errno == ENOENT)
+ if (errno == ENOENT) {
+ varbuffree(&cdr2);
+ varbuffree(&cdr);
return;
+ }
ohshite(_("unable to stat new dist conffile `%.250s'"), cdr2.buf);
}
md5hash(pkg, newdisthash, cdr2.buf);
@@ -159,11 +169,9 @@ deferred_configure_conffile(struct pkginfo *pkg, struct conffile *conff)
if (unlink(cdr2.buf) && errno != ENOENT)
warning(_("%s: failed to remove old backup '%.250s': %s"),
pkg->name, cdr2.buf, strerror(errno));
- cdr.used--;
- varbufaddstr(&cdr, DPKGDISTEXT);
- varbufaddc(&cdr, 0);
- strcpy(cdr2rest, DPKGNEWEXT);
+ strcpy(cdrrest, DPKGDISTEXT);
trig_file_activate(usenode, pkg);
+ strcpy(cdr2rest, DPKGNEWEXT);
if (rename(cdr2.buf, cdr.buf))
warning(_("%s: failed to rename '%.250s' to '%.250s': %s"),
pkg->name, cdr2.buf, cdr.buf, strerror(errno));
--
1.6.5.2
Reply to: