Patch 8.1.0470
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.
Files: src/buffer.c, src/structs.h, src/fileio.c, src/ex_cmds.c
*** ../vim-8.1.0469/src/buffer.c 2018-09-30 21:43:17.175693433 +0200
--- src/buffer.c 2018-10-11 19:00:11.004662173 +0200
***************
*** 663,670 ****
workshop_file_closed_lineno((char *)buf->b_ffname,
(int)buf->b_last_cursor.lnum);
#endif
! vim_free(buf->b_ffname);
! vim_free(buf->b_sfname);
if (buf->b_prev == NULL)
firstbuf = buf->b_next;
else
--- 663,673 ----
workshop_file_closed_lineno((char *)buf->b_ffname,
(int)buf->b_last_cursor.lnum);
#endif
! if (buf->b_sfname != buf->b_ffname)
! VIM_CLEAR(buf->b_sfname);
! else
! buf->b_sfname = NULL;
! VIM_CLEAR(buf->b_ffname);
if (buf->b_prev == NULL)
firstbuf = buf->b_next;
else
***************
*** 1877,1887 ****
*/
buf_T *
buflist_new(
! char_u *ffname, /* full path of fname or relative */
! char_u *sfname, /* short fname or NULL */
! linenr_T lnum, /* preferred cursor line */
! int flags) /* BLN_ defines */
{
buf_T *buf;
#ifdef UNIX
stat_T st;
--- 1880,1892 ----
*/
buf_T *
buflist_new(
! char_u *ffname_arg, // full path of fname or relative
! char_u *sfname_arg, // short fname or NULL
! linenr_T lnum, // preferred cursor line
! int flags) // BLN_ defines
{
+ char_u *ffname = ffname_arg;
+ char_u *sfname = sfname_arg;
buf_T *buf;
#ifdef UNIX
stat_T st;
***************
*** 1890,1896 ****
if (top_file_num == 1)
hash_init(&buf_hashtab);
! fname_expand(curbuf, &ffname, &sfname); /* will allocate ffname */
/*
* If file name already exists in the list, update the entry.
--- 1895,1901 ----
if (top_file_num == 1)
hash_init(&buf_hashtab);
! fname_expand(curbuf, &ffname, &sfname); // will allocate ffname
/*
* If file name already exists in the list, update the entry.
***************
*** 1997,2004 ****
if ((ffname != NULL && (buf->b_ffname == NULL || buf->b_sfname == NULL))
|| buf->b_wininfo == NULL)
{
VIM_CLEAR(buf->b_ffname);
- VIM_CLEAR(buf->b_sfname);
if (buf != curbuf)
free_buffer(buf);
return NULL;
--- 2002,2012 ----
if ((ffname != NULL && (buf->b_ffname == NULL || buf->b_sfname == NULL))
|| buf->b_wininfo == NULL)
{
+ if (buf->b_sfname != buf->b_ffname)
+ VIM_CLEAR(buf->b_sfname);
+ else
+ buf->b_sfname = NULL;
VIM_CLEAR(buf->b_ffname);
if (buf != curbuf)
free_buffer(buf);
return NULL;
***************
*** 3103,3109 ****
}
/*
! * Set the file name for "buf"' to 'ffname', short file name to 'sfname'.
* 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)
* OK otherwise.
--- 3111,3118 ----
}
/*
! * 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.
* Returns FAIL for failure (file name already in use by other buffer)
* OK otherwise.
***************
*** 3111,3120 ****
int
setfname(
buf_T *buf,
! char_u *ffname,
! char_u *sfname,
int message) /* give message when buffer already
exists */
{
buf_T *obuf = NULL;
#ifdef UNIX
stat_T st;
--- 3120,3131 ----
int
setfname(
buf_T *buf,
! char_u *ffname_arg,
! char_u *sfname_arg,
int message) /* give message when buffer already
exists */
{
+ char_u *ffname = ffname_arg;
+ char_u *sfname = sfname_arg;
buf_T *obuf = NULL;
#ifdef UNIX
stat_T st;
***************
*** 3123,3130 ****
if (ffname == NULL || *ffname == NUL)
{
/* Removing the name. */
VIM_CLEAR(buf->b_ffname);
- VIM_CLEAR(buf->b_sfname);
#ifdef UNIX
st.st_dev = (dev_T)-1;
#endif
--- 3134,3144 ----
if (ffname == NULL || *ffname == NUL)
{
/* Removing the name. */
+ if (buf->b_sfname != buf->b_ffname)
+ VIM_CLEAR(buf->b_sfname);
+ else
+ buf->b_sfname = NULL;
VIM_CLEAR(buf->b_ffname);
#ifdef UNIX
st.st_dev = (dev_T)-1;
#endif
***************
*** 3175,3182 ****
# endif
fname_case(sfname, 0); /* set correct case for short file name */
#endif
vim_free(buf->b_ffname);
- vim_free(buf->b_sfname);
buf->b_ffname = ffname;
buf->b_sfname = sfname;
}
--- 3189,3197 ----
# endif
fname_case(sfname, 0); /* set correct case for short file name */
#endif
+ if (buf->b_sfname != buf->b_ffname)
+ vim_free(buf->b_sfname);
vim_free(buf->b_ffname);
buf->b_ffname = ffname;
buf->b_sfname = sfname;
}
***************
*** 3210,3216 ****
buf = buflist_findnr(fnum);
if (buf != NULL)
{
! vim_free(buf->b_sfname);
vim_free(buf->b_ffname);
buf->b_ffname = vim_strsave(name);
buf->b_sfname = NULL;
--- 3225,3232 ----
buf = buflist_findnr(fnum);
if (buf != NULL)
{
! if (buf->b_sfname != buf->b_ffname)
! vim_free(buf->b_sfname);
vim_free(buf->b_ffname);
buf->b_ffname = vim_strsave(name);
buf->b_sfname = NULL;
***************
*** 4820,4827 ****
}
/*
! * Make "ffname" a full file name, set "sfname" to "ffname" if not NULL.
! * "ffname" becomes a pointer to allocated memory (or NULL).
*/
void
fname_expand(
--- 4836,4847 ----
}
/*
! * Make "*ffname" a full file name, set "*sfname" to "*ffname" if not 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
fname_expand(
***************
*** 4829,4846 ****
char_u **ffname,
char_u **sfname)
{
! if (*ffname == NULL) /* if no file name given, nothing to do */
return;
! if (*sfname == NULL) /* if no short file name given, use ffname */
*sfname = *ffname;
! *ffname = fix_fname(*ffname); /* expand to full path */
#ifdef FEAT_SHORTCUT
if (!buf->b_p_bin)
{
char_u *rfname;
! /* If the file name is a shortcut file, use the file it links to. */
rfname = mch_resolve_shortcut(*ffname);
if (rfname != NULL)
{
--- 4849,4866 ----
char_u **ffname,
char_u **sfname)
{
! if (*ffname == NULL) // no file name given, nothing to do
return;
! if (*sfname == NULL) // no short file name given, use ffname
*sfname = *ffname;
! *ffname = fix_fname(*ffname); // expand to full path
#ifdef FEAT_SHORTCUT
if (!buf->b_p_bin)
{
char_u *rfname;
! // If the file name is a shortcut file, use the file it links to.
rfname = mch_resolve_shortcut(*ffname);
if (rfname != NULL)
{
*** ../vim-8.1.0469/src/structs.h 2018-10-02 18:25:41.420867587 +0200
--- src/structs.h 2018-10-11 17:45:36.197140877 +0200
***************
*** 1972,1980 ****
* 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).
*/
! char_u *b_ffname; /* full path file name */
! char_u *b_sfname; /* short file name */
! char_u *b_fname; /* current file name */
#ifdef UNIX
int b_dev_valid; /* TRUE when b_dev has a valid number */
--- 1972,1982 ----
* 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).
*/
! char_u *b_ffname; // full path file name, allocated
! char_u *b_sfname; // short file name, allocated, may be equal to
! // b_ffname
! char_u *b_fname; // current file name, points to b_ffname or
! // b_sfname
#ifdef UNIX
int b_dev_valid; /* TRUE when b_dev has a valid number */
*** ../vim-8.1.0469/src/fileio.c 2018-09-30 21:43:17.187693348 +0200
--- src/fileio.c 2018-10-11 18:50:41.084975167 +0200
***************
*** 6187,6193 ****
|| buf->b_sfname == NULL
|| mch_isFullName(buf->b_sfname)))
{
! VIM_CLEAR(buf->b_sfname);
p = shorten_fname(buf->b_ffname, dirname);
if (p != NULL)
{
--- 6187,6194 ----
|| buf->b_sfname == NULL
|| mch_isFullName(buf->b_sfname)))
{
! if (buf->b_sfname != buf->b_ffname)
! VIM_CLEAR(buf->b_sfname);
p = shorten_fname(buf->b_ffname, dirname);
if (p != NULL)
{
*** ../vim-8.1.0469/src/ex_cmds.c 2018-10-09 21:49:30.447622031 +0200
--- src/ex_cmds.c 2018-10-11 19:01:12.524192986 +0200
***************
*** 3648,3655 ****
}
/*
! * Try to abandon current file and edit a new or existing file.
! * "fnum" is the number of the file, if zero use ffname/sfname.
* "lnum" is the line number for the cursor in the new file (if non-zero).
*
* Return:
--- 3648,3655 ----
}
/*
! * Try to abandon the current file and edit a new or existing file.
! * "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).
*
* Return:
***************
*** 3661,3672 ****
int
getfile(
int fnum,
! char_u *ffname,
! char_u *sfname,
int setpm,
linenr_T lnum,
int forceit)
{
int other;
int retval;
char_u *free_me = NULL;
--- 3661,3674 ----
int
getfile(
int fnum,
! char_u *ffname_arg,
! char_u *sfname_arg,
int setpm,
linenr_T lnum,
int forceit)
{
+ char_u *ffname = ffname_arg;
+ char_u *sfname = sfname_arg;
int other;
int retval;
char_u *free_me = NULL;
*** ../vim-8.1.0469/src/version.c 2018-10-11 17:39:09.173107491 +0200
--- src/version.c 2018-10-11 18:57:27.585905972 +0200
***************
*** 794,795 ****
--- 794,797 ----
{ /* Add new patch number below this line */
+ /**/
+ 470,
/**/
--
hundred-and-one symptoms of being an internet addict:
189. You put your e-mail address in the upper left-hand corner of envelopes.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.