changeset 28067:bd1b1353e8fa

Don't use a static buffer to hold a full filename, since it could possibly overflow depending on where someone's config directory is. This Zephyr code is as old as I am, but looks like oh-my-God-what's-wrong- with-that. Fixes #9801.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Thu, 30 Jul 2009 03:26:37 +0000
parents aeaf60a83b84
children dca0bc0371dc 7da3bf6d3b2c
files libpurple/protocols/zephyr/ZVariables.c
diffstat 1 files changed, 63 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/zephyr/ZVariables.c	Wed Jul 29 19:31:27 2009 +0000
+++ b/libpurple/protocols/zephyr/ZVariables.c	Thu Jul 30 03:26:37 2009 +0000
@@ -18,27 +18,32 @@
 #include <pwd.h>
 #endif
 
-static int get_localvarfile __P((char *bfr));
+static char *get_localvarfile __P((void));
 static char *get_varval __P((char *fn, char *val));
 static int varline __P((char *bfr, char *var));
 
 char *ZGetVariable(var)
     char *var;
 {
-    char varfile[128], *ret;
+	char *varfile, *ret;
+
+	if ((varfile = get_localvarfile()) == NULL)
+		return ((char *)0);
 
-    if (get_localvarfile(varfile))
-	return ((char *)0);
-
-    if ((ret = get_varval(varfile, var)) != ZERR_NONE)
-	return (ret);
+	if ((ret = get_varval(varfile, var)) != ZERR_NONE) {
+		g_free(varfile);
+		return ret;
+	}
 
 #ifdef WIN32
-    sprintf(varfile, "C:\\zephyr\\zephyr.var");
+	varfile = g_strdup("C:\\zephyr\\zephyr.var");
 #else
-    sprintf(varfile, "%s/zephyr.vars", CONFDIR);
+	varfile = g_strdup_printf("%s/zephyr.vars", CONFDIR);
 #endif
-    return (get_varval(varfile, var));
+	ret = get_varval(varfile, var);
+	g_free(varfile);
+
+	return ret;
 }
 
 Code_t ZSetVariable(var, value)
@@ -47,18 +52,20 @@
 {
     int written;
     FILE *fpin, *fpout;
-    char varfile[128], varfilebackup[128], varbfr[512];
+    char *varfile, *varfilebackup, varbfr[512];
 
     written = 0;
 	
-    if (get_localvarfile(varfile))
+    if ((varfile = get_localvarfile()) == NULL)
 	return (ZERR_INTERNAL);
 
-    (void) strcpy(varfilebackup, varfile);
-    (void) strcat(varfilebackup, ".backup");
+    varfilebackup = g_strconcat(varfile, ".backup", NULL);
 	
-    if (!(fpout = fopen(varfilebackup, "w")))
+    if (!(fpout = fopen(varfilebackup, "w"))) {
+	g_free(varfile);
+	g_free(varfilebackup);
 	return (errno);
+    }
     if ((fpin = fopen(varfile, "r")) != NULL) {
 	while (fgets(varbfr, sizeof varbfr, fpin) != (char *) 0) {
 	    if (varbfr[strlen(varbfr)-1] < ' ')
@@ -74,10 +81,18 @@
     } 
     if (!written)
 	fprintf(fpout, "%s = %s\n", var, value);
-    if (fclose(fpout) == EOF)
-	    return(EIO);		/* can't rely on errno */
-    if (rename(varfilebackup, varfile))
+    if (fclose(fpout) == EOF) {
+    	g_free(varfilebackup);
+    	g_free(varfile);
+	return(EIO);		/* can't rely on errno */
+    }
+    if (rename(varfilebackup, varfile)) {
+	g_free(varfilebackup);
+	g_free(varfile);
 	return (errno);
+    }
+    g_free(varfilebackup);
+    g_free(varfile);
     return (ZERR_NONE);
 }	
 
@@ -85,16 +100,18 @@
     char *var;
 {
     FILE *fpin, *fpout;
-    char varfile[128], varfilebackup[128], varbfr[512];
+    char *varfile, *varfilebackup, varbfr[512];
 
-    if (get_localvarfile(varfile))
+    if ((varfile = get_localvarfile()) == NULL)
 	return (ZERR_INTERNAL);
 
-    (void) strcpy(varfilebackup, varfile);
-    (void) strcat(varfilebackup, ".backup");
+    varfilebackup = g_strconcat(varfile, ".backup", NULL);
 	
-    if (!(fpout = fopen(varfilebackup, "w")))
+    if (!(fpout = fopen(varfilebackup, "w"))) {
+	g_free(varfile);
+	g_free(varfilebackup);
 	return (errno);
+    }
     if ((fpin = fopen(varfile, "r")) != NULL) {
 	while (fgets(varbfr, sizeof varbfr, fpin) != (char *) 0) {
 	    if (varbfr[strlen(varbfr)-1] < ' ')
@@ -104,42 +121,45 @@
 	}
 	(void) fclose(fpin);		/* don't care about read close errs */
     } 
-    if (fclose(fpout) == EOF)
-	    return(EIO);		/* errno isn't reliable */
-    if (rename(varfilebackup, varfile))
+    if (fclose(fpout) == EOF) {
+	g_free(varfilebackup);
+	g_free(varfile);
+	return(EIO);		/* errno isn't reliable */
+    }
+    if (rename(varfilebackup, varfile)) {
+	g_free(varfilebackup);
+	g_free(varfile);
 	return (errno);
+    }
+    g_free(varfilebackup);
+    g_free(varfile);
     return (ZERR_NONE);
 }	
 
-static int get_localvarfile(bfr)
-    char *bfr;
+static char *get_localvarfile(void)
 {
-    const char *envptr;
+    const char *base;
 #ifndef WIN32
     struct passwd *pwd;
-    envptr = purple_home_dir();
+    base = purple_home_dir();
 #else
-    envptr = getenv("HOME");
-    if (!envptr)
-        envptr = getenv("HOMEPATH");
-    if (!envptr) 
-        envptr = "C:\\";
+    base = getenv("HOME");
+    if (!base)
+        base = getenv("HOMEPATH");
+    if (!base) 
+        base = "C:\\";
 #endif
-    if (envptr)
-	(void) strcpy(bfr, envptr);
-    else {
+    if (!base) {
 #ifndef WIN32
 	if (!(pwd = getpwuid((int) getuid()))) {
 	    fprintf(stderr, "Zephyr internal failure: Can't find your entry in /etc/passwd\n");
-	    return (1);
+	    return NULL;
 	}
-	(void) strcpy(bfr, pwd->pw_dir);
+	base = pwd->pw_dir;
 #endif
     }
 
-    (void) strcat(bfr, "/");
-    (void) strcat(bfr, ".zephyr.vars");
-    return (0);
+    return g_strconcat(base, "/.zephyr.vars", NULL);
 } 
 	
 static char *get_varval(fn, var)