0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 8.1.0470: pointer ownership around fname_expand() is unclear

Problem:    Pointer ownership around fname_expand() is unclear.
Solution:   Allow b_ffname and b_sfname to point to the same allocated memory,
            only free one.  Update comments.
This commit is contained in:
Bram Moolenaar
2018-10-11 19:27:47 +02:00
parent 108e7b422b
commit 3d6014f033
5 changed files with 55 additions and 28 deletions

View File

@@ -663,8 +663,11 @@ aucmd_abort:
workshop_file_closed_lineno((char *)buf->b_ffname, workshop_file_closed_lineno((char *)buf->b_ffname,
(int)buf->b_last_cursor.lnum); (int)buf->b_last_cursor.lnum);
#endif #endif
vim_free(buf->b_ffname); if (buf->b_sfname != buf->b_ffname)
vim_free(buf->b_sfname); VIM_CLEAR(buf->b_sfname);
else
buf->b_sfname = NULL;
VIM_CLEAR(buf->b_ffname);
if (buf->b_prev == NULL) if (buf->b_prev == NULL)
firstbuf = buf->b_next; firstbuf = buf->b_next;
else else
@@ -1877,11 +1880,13 @@ curbuf_reusable(void)
*/ */
buf_T * buf_T *
buflist_new( buflist_new(
char_u *ffname, /* full path of fname or relative */ char_u *ffname_arg, // full path of fname or relative
char_u *sfname, /* short fname or NULL */ char_u *sfname_arg, // short fname or NULL
linenr_T lnum, /* preferred cursor line */ linenr_T lnum, // preferred cursor line
int flags) /* BLN_ defines */ int flags) // BLN_ defines
{ {
char_u *ffname = ffname_arg;
char_u *sfname = sfname_arg;
buf_T *buf; buf_T *buf;
#ifdef UNIX #ifdef UNIX
stat_T st; stat_T st;
@@ -1890,7 +1895,7 @@ buflist_new(
if (top_file_num == 1) if (top_file_num == 1)
hash_init(&buf_hashtab); hash_init(&buf_hashtab);
fname_expand(curbuf, &ffname, &sfname); /* will allocate ffname */ fname_expand(curbuf, &ffname, &sfname); // will allocate ffname
/* /*
* If file name already exists in the list, update the entry. * If file name already exists in the list, update the entry.
@@ -1997,8 +2002,11 @@ buflist_new(
if ((ffname != NULL && (buf->b_ffname == NULL || buf->b_sfname == NULL)) if ((ffname != NULL && (buf->b_ffname == NULL || buf->b_sfname == NULL))
|| buf->b_wininfo == NULL) || buf->b_wininfo == NULL)
{ {
VIM_CLEAR(buf->b_ffname); if (buf->b_sfname != buf->b_ffname)
VIM_CLEAR(buf->b_sfname); VIM_CLEAR(buf->b_sfname);
else
buf->b_sfname = NULL;
VIM_CLEAR(buf->b_ffname);
if (buf != curbuf) if (buf != curbuf)
free_buffer(buf); free_buffer(buf);
return NULL; return NULL;
@@ -3103,7 +3111,8 @@ buflist_name_nr(
} }
/* /*
* Set the file name for "buf"' to 'ffname', short file name to 'sfname'. * Set the file name for "buf"' to "ffname_arg", short file name to
* "sfname_arg".
* The file name with the full path is also remembered, for when :cd is used. * The file name with the full path is also remembered, for when :cd is used.
* Returns FAIL for failure (file name already in use by other buffer) * Returns FAIL for failure (file name already in use by other buffer)
* OK otherwise. * OK otherwise.
@@ -3111,10 +3120,12 @@ buflist_name_nr(
int int
setfname( setfname(
buf_T *buf, buf_T *buf,
char_u *ffname, char_u *ffname_arg,
char_u *sfname, char_u *sfname_arg,
int message) /* give message when buffer already exists */ int message) /* give message when buffer already exists */
{ {
char_u *ffname = ffname_arg;
char_u *sfname = sfname_arg;
buf_T *obuf = NULL; buf_T *obuf = NULL;
#ifdef UNIX #ifdef UNIX
stat_T st; stat_T st;
@@ -3123,8 +3134,11 @@ setfname(
if (ffname == NULL || *ffname == NUL) if (ffname == NULL || *ffname == NUL)
{ {
/* Removing the name. */ /* Removing the name. */
VIM_CLEAR(buf->b_ffname); if (buf->b_sfname != buf->b_ffname)
VIM_CLEAR(buf->b_sfname); VIM_CLEAR(buf->b_sfname);
else
buf->b_sfname = NULL;
VIM_CLEAR(buf->b_ffname);
#ifdef UNIX #ifdef UNIX
st.st_dev = (dev_T)-1; st.st_dev = (dev_T)-1;
#endif #endif
@@ -3175,8 +3189,9 @@ setfname(
# endif # endif
fname_case(sfname, 0); /* set correct case for short file name */ fname_case(sfname, 0); /* set correct case for short file name */
#endif #endif
vim_free(buf->b_ffname); if (buf->b_sfname != buf->b_ffname)
vim_free(buf->b_sfname); vim_free(buf->b_sfname);
vim_free(buf->b_ffname);
buf->b_ffname = ffname; buf->b_ffname = ffname;
buf->b_sfname = sfname; buf->b_sfname = sfname;
} }
@@ -3210,6 +3225,7 @@ buf_set_name(int fnum, char_u *name)
buf = buflist_findnr(fnum); buf = buflist_findnr(fnum);
if (buf != NULL) if (buf != NULL)
{ {
if (buf->b_sfname != buf->b_ffname)
vim_free(buf->b_sfname); vim_free(buf->b_sfname);
vim_free(buf->b_ffname); vim_free(buf->b_ffname);
buf->b_ffname = vim_strsave(name); buf->b_ffname = vim_strsave(name);
@@ -4820,8 +4836,12 @@ fix_fname(char_u *fname)
} }
/* /*
* Make "ffname" a full file name, set "sfname" to "ffname" if not NULL. * Make "*ffname" a full file name, set "*sfname" to "*ffname" if not NULL.
* "ffname" becomes a pointer to allocated memory (or NULL). * "*ffname" becomes a pointer to allocated memory (or NULL).
* When resolving a link both "*sfname" and "*ffname" will point to the same
* allocated memory.
* The "*ffname" and "*sfname" pointer values on call will not be freed.
* Note that the resulting "*ffname" pointer should be considered not allocaed.
*/ */
void void
fname_expand( fname_expand(
@@ -4829,18 +4849,18 @@ fname_expand(
char_u **ffname, char_u **ffname,
char_u **sfname) char_u **sfname)
{ {
if (*ffname == NULL) /* if no file name given, nothing to do */ if (*ffname == NULL) // no file name given, nothing to do
return; return;
if (*sfname == NULL) /* if no short file name given, use ffname */ if (*sfname == NULL) // no short file name given, use ffname
*sfname = *ffname; *sfname = *ffname;
*ffname = fix_fname(*ffname); /* expand to full path */ *ffname = fix_fname(*ffname); // expand to full path
#ifdef FEAT_SHORTCUT #ifdef FEAT_SHORTCUT
if (!buf->b_p_bin) if (!buf->b_p_bin)
{ {
char_u *rfname; char_u *rfname;
/* If the file name is a shortcut file, use the file it links to. */ // If the file name is a shortcut file, use the file it links to.
rfname = mch_resolve_shortcut(*ffname); rfname = mch_resolve_shortcut(*ffname);
if (rfname != NULL) if (rfname != NULL)
{ {

View File

@@ -3648,8 +3648,8 @@ check_readonly(int *forceit, buf_T *buf)
} }
/* /*
* Try to abandon current file and edit a new or existing file. * Try to abandon the current file and edit a new or existing file.
* "fnum" is the number of the file, if zero use ffname/sfname. * "fnum" is the number of the file, if zero use "ffname_arg"/"sfname_arg".
* "lnum" is the line number for the cursor in the new file (if non-zero). * "lnum" is the line number for the cursor in the new file (if non-zero).
* *
* Return: * Return:
@@ -3661,12 +3661,14 @@ check_readonly(int *forceit, buf_T *buf)
int int
getfile( getfile(
int fnum, int fnum,
char_u *ffname, char_u *ffname_arg,
char_u *sfname, char_u *sfname_arg,
int setpm, int setpm,
linenr_T lnum, linenr_T lnum,
int forceit) int forceit)
{ {
char_u *ffname = ffname_arg;
char_u *sfname = sfname_arg;
int other; int other;
int retval; int retval;
char_u *free_me = NULL; char_u *free_me = NULL;

View File

@@ -6187,6 +6187,7 @@ shorten_buf_fname(buf_T *buf, char_u *dirname, int force)
|| buf->b_sfname == NULL || buf->b_sfname == NULL
|| mch_isFullName(buf->b_sfname))) || mch_isFullName(buf->b_sfname)))
{ {
if (buf->b_sfname != buf->b_ffname)
VIM_CLEAR(buf->b_sfname); VIM_CLEAR(buf->b_sfname);
p = shorten_fname(buf->b_ffname, dirname); p = shorten_fname(buf->b_ffname, dirname);
if (p != NULL) if (p != NULL)

View File

@@ -1972,9 +1972,11 @@ struct file_buffer
* b_fname is the same as b_sfname, unless ":cd" has been done, * b_fname is the same as b_sfname, unless ":cd" has been done,
* then it is the same as b_ffname (NULL for no name). * then it is the same as b_ffname (NULL for no name).
*/ */
char_u *b_ffname; /* full path file name */ char_u *b_ffname; // full path file name, allocated
char_u *b_sfname; /* short file name */ char_u *b_sfname; // short file name, allocated, may be equal to
char_u *b_fname; /* current file name */ // b_ffname
char_u *b_fname; // current file name, points to b_ffname or
// b_sfname
#ifdef UNIX #ifdef UNIX
int b_dev_valid; /* TRUE when b_dev has a valid number */ int b_dev_valid; /* TRUE when b_dev has a valid number */

View File

@@ -792,6 +792,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
470,
/**/ /**/
469, 469,
/**/ /**/