mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 19:38:20 +00:00
path.c: vim_FullName()
: Fix heap overflow #5737
- Clarify documentation. - Return `FAIL` and truncate if `fname` is too long. - Add tests.
This commit is contained in:
@@ -417,15 +417,11 @@ char *FullName_save(char *fname, bool force)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *buf = xmalloc(MAXPATHL);
|
char *buf = xmalloc(MAXPATHL);
|
||||||
char *new_fname = NULL;
|
if (vim_FullName(fname, buf, MAXPATHL, force) == FAIL) {
|
||||||
if (vim_FullName(fname, buf, MAXPATHL, force) != FAIL) {
|
xfree(buf);
|
||||||
new_fname = xstrdup(buf);
|
return xstrdup(fname);
|
||||||
} else {
|
|
||||||
new_fname = xstrdup(fname);
|
|
||||||
}
|
}
|
||||||
xfree(buf);
|
return buf;
|
||||||
|
|
||||||
return new_fname;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Saves the absolute path.
|
/// Saves the absolute path.
|
||||||
@@ -1649,30 +1645,37 @@ bool vim_isAbsName(char_u *name)
|
|||||||
|
|
||||||
/// Save absolute file name to "buf[len]".
|
/// Save absolute file name to "buf[len]".
|
||||||
///
|
///
|
||||||
/// @param fname is the filename to evaluate
|
/// @param fname filename to evaluate
|
||||||
/// @param[out] buf is the buffer for returning the absolute path for `fname`
|
/// @param[out] buf contains `fname` absolute path, or:
|
||||||
/// @param len is the length of `buf`
|
/// - truncated `fname` if longer than `len`
|
||||||
/// @param force is a flag to force expanding even if the path is absolute
|
/// - unmodified `fname` if absolute path fails or is a URL
|
||||||
|
/// @param len length of `buf`
|
||||||
|
/// @param force flag to force expanding even if the path is absolute
|
||||||
///
|
///
|
||||||
/// @return FAIL for failure, OK otherwise
|
/// @return FAIL for failure, OK otherwise
|
||||||
int vim_FullName(const char *fname, char *buf, size_t len, bool force)
|
int vim_FullName(const char *fname, char *buf, size_t len, bool force)
|
||||||
FUNC_ATTR_NONNULL_ARG(2)
|
FUNC_ATTR_NONNULL_ARG(2)
|
||||||
{
|
{
|
||||||
int retval = OK;
|
|
||||||
int url;
|
|
||||||
|
|
||||||
*buf = NUL;
|
*buf = NUL;
|
||||||
if (fname == NULL)
|
if (fname == NULL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
url = path_with_url(fname);
|
|
||||||
if (!url)
|
|
||||||
retval = path_get_absolute_path((char_u *)fname, (char_u *)buf, len, force);
|
|
||||||
if (url || retval == FAIL) {
|
|
||||||
/* something failed; use the file name (truncate when too long) */
|
|
||||||
xstrlcpy(buf, fname, len);
|
|
||||||
}
|
}
|
||||||
return retval;
|
|
||||||
|
if (strlen(fname) > (len - 1)) {
|
||||||
|
xstrlcpy(buf, fname, len); // truncate
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path_with_url(fname)) {
|
||||||
|
xstrlcpy(buf, fname, len);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rv = path_get_absolute_path((char_u *)fname, (char_u *)buf, len, force);
|
||||||
|
if (rv == FAIL) {
|
||||||
|
xstrlcpy(buf, fname, len); // something failed; use the filename
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the full resolved path for `fname`
|
/// Get the full resolved path for `fname`
|
||||||
|
@@ -336,6 +336,17 @@ describe('more path function', function()
|
|||||||
eq(FAIL, result)
|
eq(FAIL, result)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('fails safely if given length is wrong #5737', function()
|
||||||
|
local force_expansion = 1
|
||||||
|
local filename = 'foo/bar/bazzzzzzz/buz/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/a'
|
||||||
|
local too_short_len = 8
|
||||||
|
local buf = cstr(too_short_len, '')
|
||||||
|
local result = path.vim_FullName(filename, buf, too_short_len, force_expansion)
|
||||||
|
local expected = string.sub(filename, 1, (too_short_len - 1))
|
||||||
|
eq(expected, (ffi.string(buf)))
|
||||||
|
eq(FAIL, result)
|
||||||
|
end)
|
||||||
|
|
||||||
it('uses the filename if the filename is a URL', function()
|
it('uses the filename if the filename is a URL', function()
|
||||||
local force_expansion = 1
|
local force_expansion = 1
|
||||||
local filename = 'http://www.neovim.org'
|
local filename = 'http://www.neovim.org'
|
||||||
|
Reference in New Issue
Block a user