From 66ce00153bd35bb83a296f7eb31efec6d6e6768b Mon Sep 17 00:00:00 2001
From: Lukas Fleischer <calcurse@cryptocrack.de>
Date: Mon, 21 Jul 2014 22:56:37 +0200
Subject: Refactor new_tempfile()

Avoid preallocating buffers on the stack, use dynamic memory allocation
instead. Also, change the semantics of new_tempfile() so that it returns
the full name of the temporary file and fix all call sites.

Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
---
 src/calcurse.h |  3 +--
 src/config.c   | 22 +++++++++++-----------
 src/io.c       | 33 ++++++++++++++++++++-------------
 src/note.c     | 17 ++++++++---------
 src/utils.c    | 17 +++++++----------
 5 files changed, 47 insertions(+), 45 deletions(-)

(limited to 'src')

diff --git a/src/calcurse.h b/src/calcurse.h
index 887e224..0fc3f62 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -117,7 +117,6 @@
 
 #define STATUSHEIGHT  2
 #define MAX_NOTESIZ   40
-#define TMPEXTSIZ     6
 
 /* Format for appointment hours is: HH:MM */
 #define HRMIN_SIZE 6
@@ -1032,7 +1031,7 @@ long now(void);
 char *nowstr(void);
 void print_bool_option_incolor(WINDOW *, unsigned, int, int);
 const char *get_tempdir(void);
-char *new_tempfile(const char *, int);
+char *new_tempfile(const char *);
 int check_date(unsigned, unsigned, unsigned);
 int parse_date(const char *, enum datefmt, int *, int *, int *,
 	       struct date *);
diff --git a/src/config.c b/src/config.c
index 5ce7001..6cc3e6e 100644
--- a/src/config.c
+++ b/src/config.c
@@ -590,25 +590,21 @@ static int config_save_junk_cb(const char *data, void *status)
 /* Save the user configuration. */
 unsigned config_save(void)
 {
-	char tmppath[BUFSIZ];
-	char *tmpext;
+	char *tmpprefix = NULL, *tmppath = NULL;
 	struct config_save_status status;
 	int i;
+	int ret = 0;
 
 	if (read_only)
 		return 1;
 
-	strncpy(tmppath, get_tempdir(), BUFSIZ);
-	tmppath[BUFSIZ - 1] = '\0';
-	strncat(tmppath, "/" CONF_PATH_NAME ".", BUFSIZ - strlen(tmppath) - 1);
-	if ((tmpext = new_tempfile(tmppath, TMPEXTSIZ)) == NULL)
-		return 0;
-	strncat(tmppath, tmpext, BUFSIZ - strlen(tmppath) - 1);
-	mem_free(tmpext);
+	asprintf(&tmpprefix, "%s/%s", get_tempdir(), CONF_PATH_NAME);
+	if ((tmppath = new_tempfile(tmpprefix)) == NULL)
+		goto cleanup;
 
 	status.fp = fopen(tmppath, "w");
 	if (!status.fp)
-		return 0;
+		goto cleanup;
 
 	memset(status.done, 0, sizeof(status.done));
 
@@ -626,5 +622,9 @@ unsigned config_save(void)
 	if (io_file_cp(tmppath, path_conf))
 		unlink(tmppath);
 
-	return 1;
+	ret = 1;
+cleanup:
+	mem_free(tmpprefix);
+	mem_free(tmppath);
+	return ret;
 }
diff --git a/src/io.c b/src/io.c
index 70f0ede..5bdba77 100644
--- a/src/io.c
+++ b/src/io.c
@@ -1135,25 +1135,32 @@ void io_import_data(enum import_type type, const char *stream_name)
 struct io_file *io_log_init(void)
 {
 	char *logprefix, *logname;
-	struct io_file *log;
+	struct io_file *log = mem_malloc(sizeof(struct io_file));
 
-	asprintf(&logprefix, "%s/calcurse_log.", get_tempdir());
-	logname = new_tempfile(logprefix, TMPEXTSIZ);
-	RETVAL_IF(logname == NULL, 0,
-		  _("Warning: could not create temporary log file, Aborting..."));
-	log = mem_malloc(sizeof(struct io_file));
-	RETVAL_IF(log == NULL, 0,
-		  _("Warning: could not open temporary log file, Aborting..."));
-	snprintf(log->name, sizeof(log->name), "%s%s", logprefix, logname);
-	mem_free(logprefix);
-	mem_free(logname);
+	if (!log) {
+		ERROR_MSG(_("Warning: could not open temporary log file, Aborting..."));
+		return NULL;
+	}
+	asprintf(&logprefix, "%s/calcurse_log", get_tempdir());
+	logname = new_tempfile(logprefix);
+	if (!logname) {
+		ERROR_MSG(_("Warning: could not create temporary log file, Aborting..."));
+		goto error;
+	}
+	strncpy(log->name, logname, sizeof(log->name));
 	log->fd = fopen(log->name, "w");
 	if (log->fd == NULL) {
 		ERROR_MSG(_("Warning: could not open temporary log file, Aborting..."));
-		mem_free(log);
-		return 0;
+		goto error;
 	}
 
+	goto cleanup;
+error:
+	mem_free(log);
+	log = NULL;
+cleanup:
+	mem_free(logprefix);
+	mem_free(logname);
 	return log;
 }
 
diff --git a/src/note.c b/src/note.c
index ce627b9..e98dd1d 100644
--- a/src/note.c
+++ b/src/note.c
@@ -77,19 +77,14 @@ char *generate_note(const char *str)
 /* Edit a note with an external editor. */
 void edit_note(char **note, const char *editor)
 {
-	char tmppath[BUFSIZ];
-	char *tmpext;
+	char *tmpprefix = NULL, *tmppath = NULL;
 	char *notepath = NULL;
 	char *sha1 = mem_malloc(SHA1_DIGESTLEN * 2 + 1);
 	FILE *fp;
 
-	strncpy(tmppath, get_tempdir(), BUFSIZ);
-	tmppath[BUFSIZ - 1] = '\0';
-	strncat(tmppath, "/calcurse-note.", BUFSIZ - strlen(tmppath) - 1);
-	if ((tmpext = new_tempfile(tmppath, TMPEXTSIZ)) == NULL)
-		return;
-	strncat(tmppath, tmpext, BUFSIZ - strlen(tmppath) - 1);
-	mem_free(tmpext);
+	asprintf(&tmpprefix, "%s/calcurse-note", get_tempdir());
+	if ((tmppath = new_tempfile(tmpprefix)) == NULL)
+		goto cleanup;
 
 	if (*note != NULL) {
 		asprintf(&notepath, "%s%s", path_notes, *note);
@@ -113,6 +108,10 @@ void edit_note(char **note, const char *editor)
 	}
 
 	unlink(tmppath);
+
+cleanup:
+	mem_free(tmpprefix);
+	mem_free(tmppath);
 }
 
 /* View a note in an external pager. */
diff --git a/src/utils.c b/src/utils.c
index 34bdd5e..527dec8 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -619,21 +619,16 @@ const char *get_tempdir(void)
  * Create a new unique file, and return a newly allocated string which contains
  * the random part of the file name.
  */
-char *new_tempfile(const char *prefix, int trailing_len)
+char *new_tempfile(const char *prefix)
 {
-	char fullname[BUFSIZ];
-	int prefix_len, fd;
+	char *fullname;
+	int fd;
 	FILE *file;
 
 	if (prefix == NULL)
 		return NULL;
 
-	prefix_len = strlen(prefix);
-	if (prefix_len + trailing_len >= BUFSIZ)
-		return NULL;
-	memcpy(fullname, prefix, prefix_len);
-	memset(fullname + prefix_len, 'X', trailing_len);
-	fullname[prefix_len + trailing_len] = '\0';
+	asprintf(&fullname, "%s.XXXXXX", prefix);
 	if ((fd = mkstemp(fullname)) == -1
 	    || (file = fdopen(fd, "w+")) == NULL) {
 		if (fd != -1) {
@@ -642,11 +637,13 @@ char *new_tempfile(const char *prefix, int trailing_len)
 		}
 		ERROR_MSG(_("temporary file \"%s\" could not be created"),
 			  fullname);
+
+		mem_free(fullname);
 		return NULL;
 	}
 	fclose(file);
 
-	return mem_strdup(fullname + prefix_len);
+	return fullname;
 }
 
 /*
-- 
cgit v1.2.3-70-g09d2