Don't call basename() and dirname() in an unportable way.

POSIX allows these functions to modify their input buffer, so that they
have storage for the return value. Pull copies of the filename before
calling these utility functions.
This commit is contained in:
Ed Schouten 2016-07-28 15:17:12 +00:00
parent 45eff3df96
commit 6718ba1851

View File

@ -301,6 +301,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag)
{ {
struct stat sb; struct stat sb;
ssize_t len; ssize_t len;
char *dirbuf, *basebuf;
static char *p = NULL; static char *p = NULL;
static size_t plen = 0; static size_t plen = 0;
int c; int c;
@ -389,9 +390,14 @@ mf_fgets(SPACE *sp, enum e_spflag spflag)
if ((size_t)len > sizeof(oldfname)) if ((size_t)len > sizeof(oldfname))
errx(1, "%s: name too long", fname); errx(1, "%s: name too long", fname);
} }
if ((dirbuf = strdup(fname)) == NULL ||
(basebuf = strdup(fname)) == NULL)
err(1, "strdup");
len = snprintf(tmpfname, sizeof(tmpfname), len = snprintf(tmpfname, sizeof(tmpfname),
"%s/.!%ld!%s", dirname(fname), (long)getpid(), "%s/.!%ld!%s", dirname(dirbuf), (long)getpid(),
basename(fname)); basename(basebuf));
free(dirbuf);
free(basebuf);
if ((size_t)len >= sizeof(tmpfname)) if ((size_t)len >= sizeof(tmpfname))
errx(1, "%s: name too long", fname); errx(1, "%s: name too long", fname);
unlink(tmpfname); unlink(tmpfname);