win: avoid duplicate separators in $PATH #12869

Seems like redundant env var separators (";" on Windows) in $PATH can
cause weird behavior. From #7377:

> After some time, system(['win32yank', '-o']) and system('win32yank -o')
> start returning different results: specifically first returns an
> empty string.
>
> 1. $PATH weirdly contains double semicolon followed by path to the
>    “installation directory” (unpacked directory from archive).
> 2. If I run `let $PATH=substitute($PATH, ';;', ';', 'g')` the problem is fixed.

close #7377
ref 224f99b85d
This commit is contained in:
Justin M. Keyes 2020-09-08 20:47:22 -07:00 committed by GitHub
parent df6b49b4ee
commit 59712f6dbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 4 deletions

View File

@ -1176,7 +1176,9 @@ bool os_setenv_append_path(const char *fname)
temp[0] = NUL;
} else {
xstrlcpy(temp, path, newlen);
xstrlcat(temp, ENV_SEPSTR, newlen);
if (ENV_SEPCHAR != path[pathlen - 1]) {
xstrlcat(temp, ENV_SEPSTR, newlen);
}
}
xstrlcat(temp, os_buf, newlen);
os_setenv("PATH", temp, 1);

View File

@ -78,15 +78,22 @@ describe('env.c', function()
end)
describe('os_setenv_append_path', function()
itp('appends /foo/bar to $PATH', function()
itp('appends :/foo/bar to $PATH', function()
local original_path = os.getenv('PATH')
eq(true, cimp.os_setenv_append_path(to_cstr('/foo/bar/baz')))
eq(true, cimp.os_setenv_append_path(to_cstr('/foo/bar/baz.exe')))
eq(original_path..':/foo/bar', os.getenv('PATH'))
end)
itp('avoids redundant separator when appending to $PATH #7377', function()
os_setenv('PATH', '/a/b/c:', true)
eq(true, cimp.os_setenv_append_path(to_cstr('/foo/bar/baz.exe')))
-- Must not have duplicate separators. #7377
eq('/a/b/c:/foo/bar', os.getenv('PATH'))
end)
itp('returns false if `fname` is not absolute', function()
local original_path = os.getenv('PATH')
eq(false, cimp.os_setenv_append_path(to_cstr('foo/bar/baz')))
eq(false, cimp.os_setenv_append_path(to_cstr('foo/bar/baz.exe')))
eq(original_path, os.getenv('PATH'))
end)
end)