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>
This commit is contained in:
Lukas Fleischer 2014-07-21 22:56:37 +02:00
parent 21fc7a4b74
commit 66ce00153b
5 changed files with 47 additions and 45 deletions

View File

@ -117,7 +117,6 @@
#define STATUSHEIGHT 2 #define STATUSHEIGHT 2
#define MAX_NOTESIZ 40 #define MAX_NOTESIZ 40
#define TMPEXTSIZ 6
/* Format for appointment hours is: HH:MM */ /* Format for appointment hours is: HH:MM */
#define HRMIN_SIZE 6 #define HRMIN_SIZE 6
@ -1032,7 +1031,7 @@ long now(void);
char *nowstr(void); char *nowstr(void);
void print_bool_option_incolor(WINDOW *, unsigned, int, int); void print_bool_option_incolor(WINDOW *, unsigned, int, int);
const char *get_tempdir(void); const char *get_tempdir(void);
char *new_tempfile(const char *, int); char *new_tempfile(const char *);
int check_date(unsigned, unsigned, unsigned); int check_date(unsigned, unsigned, unsigned);
int parse_date(const char *, enum datefmt, int *, int *, int *, int parse_date(const char *, enum datefmt, int *, int *, int *,
struct date *); struct date *);

View File

@ -590,25 +590,21 @@ static int config_save_junk_cb(const char *data, void *status)
/* Save the user configuration. */ /* Save the user configuration. */
unsigned config_save(void) unsigned config_save(void)
{ {
char tmppath[BUFSIZ]; char *tmpprefix = NULL, *tmppath = NULL;
char *tmpext;
struct config_save_status status; struct config_save_status status;
int i; int i;
int ret = 0;
if (read_only) if (read_only)
return 1; return 1;
strncpy(tmppath, get_tempdir(), BUFSIZ); asprintf(&tmpprefix, "%s/%s", get_tempdir(), CONF_PATH_NAME);
tmppath[BUFSIZ - 1] = '\0'; if ((tmppath = new_tempfile(tmpprefix)) == NULL)
strncat(tmppath, "/" CONF_PATH_NAME ".", BUFSIZ - strlen(tmppath) - 1); goto cleanup;
if ((tmpext = new_tempfile(tmppath, TMPEXTSIZ)) == NULL)
return 0;
strncat(tmppath, tmpext, BUFSIZ - strlen(tmppath) - 1);
mem_free(tmpext);
status.fp = fopen(tmppath, "w"); status.fp = fopen(tmppath, "w");
if (!status.fp) if (!status.fp)
return 0; goto cleanup;
memset(status.done, 0, sizeof(status.done)); memset(status.done, 0, sizeof(status.done));
@ -626,5 +622,9 @@ unsigned config_save(void)
if (io_file_cp(tmppath, path_conf)) if (io_file_cp(tmppath, path_conf))
unlink(tmppath); unlink(tmppath);
return 1; ret = 1;
cleanup:
mem_free(tmpprefix);
mem_free(tmppath);
return ret;
} }

View File

@ -1135,25 +1135,32 @@ void io_import_data(enum import_type type, const char *stream_name)
struct io_file *io_log_init(void) struct io_file *io_log_init(void)
{ {
char *logprefix, *logname; char *logprefix, *logname;
struct io_file *log; struct io_file *log = mem_malloc(sizeof(struct io_file));
asprintf(&logprefix, "%s/calcurse_log.", get_tempdir()); if (!log) {
logname = new_tempfile(logprefix, TMPEXTSIZ); ERROR_MSG(_("Warning: could not open temporary log file, Aborting..."));
RETVAL_IF(logname == NULL, 0, return NULL;
_("Warning: could not create temporary log file, Aborting...")); }
log = mem_malloc(sizeof(struct io_file)); asprintf(&logprefix, "%s/calcurse_log", get_tempdir());
RETVAL_IF(log == NULL, 0, logname = new_tempfile(logprefix);
_("Warning: could not open temporary log file, Aborting...")); if (!logname) {
snprintf(log->name, sizeof(log->name), "%s%s", logprefix, logname); ERROR_MSG(_("Warning: could not create temporary log file, Aborting..."));
mem_free(logprefix); goto error;
mem_free(logname); }
strncpy(log->name, logname, sizeof(log->name));
log->fd = fopen(log->name, "w"); log->fd = fopen(log->name, "w");
if (log->fd == NULL) { if (log->fd == NULL) {
ERROR_MSG(_("Warning: could not open temporary log file, Aborting...")); ERROR_MSG(_("Warning: could not open temporary log file, Aborting..."));
mem_free(log); goto error;
return 0;
} }
goto cleanup;
error:
mem_free(log);
log = NULL;
cleanup:
mem_free(logprefix);
mem_free(logname);
return log; return log;
} }

View File

@ -77,19 +77,14 @@ char *generate_note(const char *str)
/* Edit a note with an external editor. */ /* Edit a note with an external editor. */
void edit_note(char **note, const char *editor) void edit_note(char **note, const char *editor)
{ {
char tmppath[BUFSIZ]; char *tmpprefix = NULL, *tmppath = NULL;
char *tmpext;
char *notepath = NULL; char *notepath = NULL;
char *sha1 = mem_malloc(SHA1_DIGESTLEN * 2 + 1); char *sha1 = mem_malloc(SHA1_DIGESTLEN * 2 + 1);
FILE *fp; FILE *fp;
strncpy(tmppath, get_tempdir(), BUFSIZ); asprintf(&tmpprefix, "%s/calcurse-note", get_tempdir());
tmppath[BUFSIZ - 1] = '\0'; if ((tmppath = new_tempfile(tmpprefix)) == NULL)
strncat(tmppath, "/calcurse-note.", BUFSIZ - strlen(tmppath) - 1); goto cleanup;
if ((tmpext = new_tempfile(tmppath, TMPEXTSIZ)) == NULL)
return;
strncat(tmppath, tmpext, BUFSIZ - strlen(tmppath) - 1);
mem_free(tmpext);
if (*note != NULL) { if (*note != NULL) {
asprintf(&notepath, "%s%s", path_notes, *note); asprintf(&notepath, "%s%s", path_notes, *note);
@ -113,6 +108,10 @@ void edit_note(char **note, const char *editor)
} }
unlink(tmppath); unlink(tmppath);
cleanup:
mem_free(tmpprefix);
mem_free(tmppath);
} }
/* View a note in an external pager. */ /* View a note in an external pager. */

View File

@ -619,21 +619,16 @@ const char *get_tempdir(void)
* Create a new unique file, and return a newly allocated string which contains * Create a new unique file, and return a newly allocated string which contains
* the random part of the file name. * 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]; char *fullname;
int prefix_len, fd; int fd;
FILE *file; FILE *file;
if (prefix == NULL) if (prefix == NULL)
return NULL; return NULL;
prefix_len = strlen(prefix); asprintf(&fullname, "%s.XXXXXX", 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';
if ((fd = mkstemp(fullname)) == -1 if ((fd = mkstemp(fullname)) == -1
|| (file = fdopen(fd, "w+")) == NULL) { || (file = fdopen(fd, "w+")) == NULL) {
if (fd != -1) { 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"), ERROR_MSG(_("temporary file \"%s\" could not be created"),
fullname); fullname);
mem_free(fullname);
return NULL; return NULL;
} }
fclose(file); fclose(file);
return mem_strdup(fullname + prefix_len); return fullname;
} }
/* /*