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.
This commit is contained in:
Benno Schulenberg 2016-05-18 21:04:39 +02:00
parent faf5227bc5
commit c9d1936f02
1 changed files with 15 additions and 7 deletions

View File

@ -325,7 +325,7 @@ int do_lockfile(const char *filename)
if (stat(lockfilename, &fileinfo) != -1) { if (stat(lockfilename, &fileinfo) != -1) {
ssize_t readtot = 0; ssize_t readtot = 0;
ssize_t readamt = 0; ssize_t readamt = 0;
char *lockbuf, *question, *promptstr; char *lockbuf, *question, *postedname, *promptstr;
int room, ans; int room, ans;
if ((lockfd = open(lockfilename, O_RDONLY)) < 0) { 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?"); question = _("File %s is being edited (by %s with %s, PID %d); continue?");
room = COLS - strlenpt(question) - strlenpt(lockuser) - strlenpt(lockprog) + 3; room = COLS - strlenpt(question) - strlenpt(lockuser) - strlenpt(lockprog) + 3;
if (room < 4) if (room < 4)
namecopy = mallocstrcpy(namecopy, "_"); postedname = mallocstrcpy(NULL, "_");
else if (room < strlenpt(filename)) else if (room < strlenpt(filename)) {
sprintf(namecopy, "...%s", display_string(filename, char *fragment = display_string(filename,
strlenpt(filename) - room + 3, room, FALSE)); 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), /* Allow extra space for username (14), program name (8), PID (3),
* and terminating \0 (1), minus the %s (2) for the file name. */ * and terminating \0 (1), minus the %s (2) for the file name. */
promptstr = charalloc(strlen(question) + 24 + strlen(namecopy)); promptstr = charalloc(strlen(question) + 24 + strlen(postedname));
sprintf(promptstr, question, namecopy, lockuser, lockprog, lockpid); sprintf(promptstr, question, postedname, lockuser, lockprog, lockpid);
free(postedname);
ans = do_yesno_prompt(FALSE, promptstr); ans = do_yesno_prompt(FALSE, promptstr);
free(promptstr); free(promptstr);