From c9d1936f02a81fbc2b3e4d351b92bedaf5ca2d94 Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Wed, 18 May 2016 21:04:39 +0200 Subject: [PATCH] files: don't reuse a variable that may have been modified by dirname() The variable 'namecopy' has been passed to dirname(), so it is likely to have been changed when it contains a slash. So, use a new variable instead. Also, free the result of display_string(). This fixes https://savannah.gnu.org/bugs/?47956. --- src/files.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/files.c b/src/files.c index fbf81cfb..4b07ed07 100644 --- a/src/files.c +++ b/src/files.c @@ -325,7 +325,7 @@ int do_lockfile(const char *filename) if (stat(lockfilename, &fileinfo) != -1) { ssize_t readtot = 0; ssize_t readamt = 0; - char *lockbuf, *question, *promptstr; + char *lockbuf, *question, *postedname, *promptstr; int room, ans; if ((lockfd = open(lockfilename, O_RDONLY)) < 0) { @@ -361,15 +361,23 @@ int do_lockfile(const char *filename) question = _("File %s is being edited (by %s with %s, PID %d); continue?"); room = COLS - strlenpt(question) - strlenpt(lockuser) - strlenpt(lockprog) + 3; if (room < 4) - namecopy = mallocstrcpy(namecopy, "_"); - else if (room < strlenpt(filename)) - sprintf(namecopy, "...%s", display_string(filename, - strlenpt(filename) - room + 3, room, FALSE)); + postedname = mallocstrcpy(NULL, "_"); + else if (room < strlenpt(filename)) { + char *fragment = display_string(filename, + strlenpt(filename) - room + 3, room, FALSE); + postedname = charalloc(strlen(fragment) + 4); + strcpy(postedname, "..."); + strcat(postedname, fragment); + free(fragment); + } else + postedname = mallocstrcpy(NULL, filename); /* Allow extra space for username (14), program name (8), PID (3), * and terminating \0 (1), minus the %s (2) for the file name. */ - promptstr = charalloc(strlen(question) + 24 + strlen(namecopy)); - sprintf(promptstr, question, namecopy, lockuser, lockprog, lockpid); + promptstr = charalloc(strlen(question) + 24 + strlen(postedname)); + sprintf(promptstr, question, postedname, lockuser, lockprog, lockpid); + free(postedname); + ans = do_yesno_prompt(FALSE, promptstr); free(promptstr);