Subject: pkg/37031: realloc failing in audit-packages
To: None <pkg-manager@netbsd.org, gnats-admin@netbsd.org,>
From: None <dholland@eecs.harvard.edu>
List: pkgsrc-bugs
Date: 09/26/2007 21:00:01
>Number:         37031
>Category:       pkg
>Synopsis:       realloc failing in audit-packages
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Sep 26 21:00:00 +0000 2007
>Originator:     David A. Holland <dholland@eecs.harvard.edu>
>Release:        NetBSD 2.1.0_STABLE
>Organization:
   Harvard EECS
>Environment:
System: NetBSD bantha 2.1.0_STABLE NetBSD 2.1.0_STABLE (GENERIC) #3: Fri Dec  1 14:58:15 EST 2006  root@bantha:/usr/src/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:

audit-packages from pkg_install-20070916 bombs with 

   audit-packages: mkver realloc failed: Cannot allocate memory

>How-To-Repeat:

Update, build, install, run.

>Fix:

The problem turns out to be that it's doubling the size of an array
every time it adds one element. So, don't do that.

Index: files/lib/dewey.c
===================================================================
RCS file: /cvsroot/pkgsrc/pkgtools/pkg_install/files/lib/dewey.c,v
retrieving revision 1.7
diff -u -p -r1.7 dewey.c
--- files/lib/dewey.c	16 Sep 2007 19:03:52 -0000	1.7
+++ files/lib/dewey.c	26 Sep 2007 19:09:07 -0000
@@ -110,6 +110,28 @@ dewey_mktest(int *op, const char *test)
 }
 
 /*
+ * add to arr_t
+ */
+static void
+addcomponent(arr_t *ap, int x)
+{
+	if (ap->c >= ap->size) {
+		if (ap->size == 0) {
+			ap->size = 62;
+			if ((ap->v = malloc(ap->size * sizeof(int))) == NULL)
+				err(EXIT_FAILURE, "mkver malloc failed");
+		} else {
+			ap->size *= 2;
+			if ((ap->v = realloc(ap->v, ap->size * sizeof(int)))
+					== NULL)
+				err(EXIT_FAILURE, "mkver realloc failed");
+		}
+	}
+
+	ap->v[ap->c++] = x;
+}
+
+/*
  * make a component of a version number.
  * '.' encodes as Dot which is '0'
  * '_' encodes as 'patch level', or 'Dot', which is 0.
@@ -127,25 +149,16 @@ mkcomponent(arr_t *ap, const char *num)
 	int                 n;
 	const char             *cp;
 
-	if (ap->size == 0) {
-		ap->size = 62;
-		if ((ap->v = malloc(ap->size * sizeof(int))) == NULL)
-			err(EXIT_FAILURE, "mkver malloc failed");
-	} else {
-		ap->size *= 2;
-		if ((ap->v = realloc(ap->v, ap->size * sizeof(int))) == NULL)
-			err(EXIT_FAILURE, "mkver realloc failed");
-	}
 	if (isdigit((unsigned char)*num)) {
 		for (cp = num, n = 0 ; isdigit((unsigned char)*num) ; num++) {
 			n = (n * 10) + (*num - '0');
 		}
-		ap->v[ap->c++] = n;
+		addcomponent(ap, n);
 		return (int)(num - cp);
 	}
 	for (modp = modifiers ; modp->s ; modp++) {
 		if (strncasecmp(num, modp->s, modp->len) == 0) {
-			ap->v[ap->c++] = modp->t;
+			addcomponent(ap, modp->t);
 			return modp->len;
 		}
 	}
@@ -157,12 +170,9 @@ mkcomponent(arr_t *ap, const char *num)
 		return (int)(num - cp);
 	}
 	if (isalpha((unsigned char)*num)) {
-		ap->v[ap->c++] = Dot;
+		addcomponent(ap, Dot);
 		cp = strchr(alphas, tolower((unsigned char)*num));
-		ap->size *= 2;
-		if ((ap->v = realloc(ap->v, ap->size * sizeof(int))) == NULL)
-			err(EXIT_FAILURE, "mkver realloc failed");
-		ap->v[ap->c++] = (int)(cp - alphas) + 1;
+		addcomponent(ap, (int)(cp - alphas) + 1);
 		return 1;
 	}
 	return 1;