[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[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: