fix(undo): undefined behavior with empty entry in 'undodir' (#38849)

Problem:  Undefined behavior when 'undodir' contains empty entry.
Solution: Don't try to remove trailing slashes from empty path. Also
          don't remove a colon on Windows while at it.
This commit is contained in:
zeertzjq
2026-04-07 14:49:05 +08:00
committed by GitHub
parent 6b0367481c
commit 2df2e72e0a
2 changed files with 17 additions and 7 deletions

View File

@@ -711,10 +711,8 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
dir_name[dir_len] = NUL;
// Remove trailing pathseps from directory name
char *p = &dir_name[dir_len - 1];
while (dir_len > 1 && vim_ispathsep(*p)) {
*p-- = NUL;
dir_len--;
while (dir_len > 1 && vim_ispathsep_nocolon(dir_name[dir_len - 1])) {
dir_name[--dir_len] = NUL;
}
bool has_directory = os_isdir(dir_name);
@@ -733,9 +731,9 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
if (has_directory) {
if (munged_name.data == NULL) {
munged_name = cbuf_to_string(ffname, ffname_len);
for (char *c = munged_name.data; *c != NUL; MB_PTR_ADV(c)) {
if (vim_ispathsep(*c)) {
*c = '%';
for (char *p = munged_name.data; *p != NUL; MB_PTR_ADV(p)) {
if (vim_ispathsep(*p)) {
*p = '%';
}
}
}

View File

@@ -225,3 +225,15 @@ describe(':undo! command', function()
)
end)
end)
describe("opening file when 'undofile' is on", function()
before_each(function()
clear({ args = { '--cmd', 'set undofile' } })
end)
it("does not crash when 'undodir' contains empty entry", function()
command('set undodir=,.')
command('edit test/functional/fixtures/bigfile.txt')
n.assert_alive()
end)
end)