Bladeren bron

adk/tools/pkgmaker: Fix memleak in toupperstr()

The function allocated a fresh buffer upon every call but callers didn't
care to free the returned value.

To solve this in a most simple way, make the function non-reentrant,
returning a pointer to a local, statically allocated buffer which is
being overwritten upon each consecutive call.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Phil Sutter 1 jaar geleden
bovenliggende
commit
316ba77dcd
1 gewijzigde bestanden met toevoegingen van 42 en 16 verwijderingen
  1. 42 16
      adk/tools/pkgmaker.c

+ 42 - 16
adk/tools/pkgmaker.c

@@ -19,6 +19,7 @@
 
 #include <ctype.h>
 #include <dirent.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -290,22 +291,44 @@ static char *tolowerstr(char *string) {
 
 static char *toupperstr(char *string) {
 
+	static char *sdup = NULL;
+	static int sduplen = 0;
 	int i;
-	char *str;
-	
+
+	if (!string) {
+		free(sdup);
+		sduplen = 0;
+		return NULL;
+	}
+
+	if (sduplen <= strlen(string)) {
+		sduplen = strlen(string) + 1;
+		sdup = realloc(sdup, sduplen);
+		if (!sdup)
+			fatal_error("%s: memory allocation failed: %s\n",
+				    __func__, strerror(errno));
+	}
+
 	/* transform to uppercase variable name */
-	str = strdup(string);
-	for (i=0; i<(int)strlen(str); i++) {
-		if (str[i] == '+')
-			str[i] = 'X';
-		if (str[i] == '-')
-			str[i] = '_';
-		/* remove negation here, useful for package host depends */
-		if (str[i] == '!')
-			str[i] = '_';
-		str[i] = toupper(str[i]);
+	for (i = 0; i < strlen(string) + 1; i++) {
+		switch (string[i]) {
+		case '+':
+			sdup[i] = 'X';
+			break;
+		case '-':
+			sdup[i] = '_';
+			break;
+		case '!':
+			sdup[i] = '_';
+			break;
+		case '\0':
+			sdup[i] = '\0';
+			break;
+		default:
+			sdup[i] = toupper(string[i]);
+		}
 	}
-	return(str);
+	return sdup;
 }
 
 
@@ -463,10 +486,12 @@ int main() {
 									icfg = fopen(runtime, "a");
 									if (icfg == NULL)
 										continue;
-									if (strncmp("busybox", sname, 7) == 0)
-										fprintf(icfg, "config ADK_RUNTIME_START_%s_%s\n", toupperstr(sname), toupperstr(sname2));
-									else
+									if (strncmp("busybox", sname, 7) == 0) {
+										fprintf(icfg, "config ADK_RUNTIME_START_%s", toupperstr(sname));
+										fprintf(icfg, "_%s\n", toupperstr(sname2));
+									} else {
 										fprintf(icfg, "config ADK_RUNTIME_START_%s\n", toupperstr(sname));
+									}
 									fprintf(icfg, "\tprompt \"Start %s on boot\"\n", sname2);
 									fprintf(icfg, "\ttristate\n");
 									if (strncmp("busybox", sname, 7) == 0)
@@ -1282,6 +1307,7 @@ int main() {
 				fatal_error("removing file failed.");
 		}
 	}
+	toupperstr(NULL);
 	closedir(pkglistdir);
 	return(0);
 }