Permalink
Browse files

patch 8.0.1012: MS-Windows: problem with $HOME when is was set intern…

…ally

Problem:    MS-Windows: Problem with $HOME when is was set internally.
Solution:   Only use the $HOME default internally. (Yasuhiro Matsumoto, closes
            #2013)
  • Loading branch information...
brammool committed Aug 29, 2017
1 parent 97f65fa commit 48340b62e812dc9280f621a2eb6db76d43555c66
Showing with 163 additions and 35 deletions.
  1. +1 −0 src/Makefile
  2. +34 −34 src/misc1.c
  3. +2 −1 src/testdir/Make_all.mak
  4. +124 −0 src/testdir/test_windows_home.vim
  5. +2 −0 src/version.c
View
@@ -2278,6 +2278,7 @@ test_arglist \
test_visual \
test_window_cmd \
test_window_id \
test_windows_home \
test_writefile \
test_alot_latin \
test_alot_utf8 \
View
@@ -3750,10 +3750,33 @@ init_homedir(void)
var = mch_getenv((char_u *)"HOME");
#endif
if (var != NULL && *var == NUL) /* empty is same as not set */
var = NULL;
#ifdef WIN3264
/*
* Typically, $HOME is not defined on Windows, unless the user has
* specifically defined it for Vim's sake. However, on Windows NT
* platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for
* each user. Try constructing $HOME from these.
*/
if (var == NULL || *var == NULL)
{
char_u *homedrive, *homepath;
homedrive = mch_getenv((char_u *)"HOMEDRIVE");
homepath = mch_getenv((char_u *)"HOMEPATH");
if (homepath == NULL || *homepath == NUL)
homepath = (char_u *)"\\";
if (homedrive != NULL
&& STRLEN(homedrive) + STRLEN(homepath) < MAXPATHL)
{
sprintf((char *)NameBuff, "%s%s", homedrive, homepath);
if (NameBuff[0] != NUL)
var = NameBuff;
}
}
if (var == NULL)
var = mch_getenv((char_u *)"USERPROFILE");
/*
* Weird but true: $HOME may contain an indirect reference to another
* variable, esp. "%USERPROFILE%". Happens when $USERPROFILE isn't set
@@ -3774,40 +3797,14 @@ init_homedir(void)
{
vim_snprintf((char *)NameBuff, MAXPATHL, "%s%s", exp, p + 1);
var = NameBuff;
/* Also set $HOME, it's needed for _viminfo. */
vim_setenv((char_u *)"HOME", NameBuff);
}
}
}
/*
* Typically, $HOME is not defined on Windows, unless the user has
* specifically defined it for Vim's sake. However, on Windows NT
* platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for
* each user. Try constructing $HOME from these.
*/
if (var == NULL)
{
char_u *homedrive, *homepath;
homedrive = mch_getenv((char_u *)"HOMEDRIVE");
homepath = mch_getenv((char_u *)"HOMEPATH");
if (homepath == NULL || *homepath == NUL)
homepath = (char_u *)"\\";
if (homedrive != NULL
&& STRLEN(homedrive) + STRLEN(homepath) < MAXPATHL)
{
sprintf((char *)NameBuff, "%s%s", homedrive, homepath);
if (NameBuff[0] != NUL)
{
var = NameBuff;
/* Also set $HOME, it's needed for _viminfo. */
vim_setenv((char_u *)"HOME", NameBuff);
}
}
}
if (var != NULL && *var == NUL) /* empty is same as not set */
var = NULL;
# if defined(FEAT_MBYTE)
# ifdef FEAT_MBYTE
if (enc_utf8 && var != NULL)
{
int len;
@@ -3823,16 +3820,15 @@ init_homedir(void)
}
}
# endif
#endif
#if defined(MSWIN)
/*
* Default home dir is C:/
* Best assumption we can make in such a situation.
*/
if (var == NULL)
var = (char_u *)"C:/";
#endif
if (var != NULL)
{
#ifdef UNIX
@@ -4661,6 +4657,10 @@ home_replace(
homedir_env_orig = homedir_env = mch_getenv((char_u *)"SYS$LOGIN");
#else
homedir_env_orig = homedir_env = mch_getenv((char_u *)"HOME");
#endif
#ifdef WIN3264
if (homedir_env == NULL)
homedir_env_orig = homedir_env = mch_getenv((char_u *)"USERPROFILE");
#endif
/* Empty is the same as not set. */
if (homedir_env != NULL && *homedir_env == NUL)
View
@@ -205,7 +205,8 @@ NEW_TESTS = test_arabic.res \
test_writefile.res \
test_alot_latin.res \
test_alot_utf8.res \
test_alot.res
test_alot.res \
test_windows_home.res
# Explicit dependencies.
@@ -0,0 +1,124 @@
" Test for $HOME on Windows.
if !has('win32')
finish
endif
let s:env = {}
func s:restore_env()
for i in keys(s:env)
exe 'let ' . i . '=s:env["' . i . '"]'
endfor
endfunc
func s:save_env(...)
for i in a:000
exe 'let s:env["' . i . '"]=' . i
endfor
endfunc
func s:unlet_env(...)
for i in a:000
exe 'let ' . i . '=""'
endfor
endfunc
func CheckHomeIsMissingFromSubprocessEnvironment()
silent! let out = system('set')
let env = filter(split(out, "\n"), 'v:val=~"^HOME="')
call assert_equal(0, len(env))
endfunc
func CheckHomeIsInSubprocessEnvironment(exp)
silent! let out = system('set')
let env = filter(split(out, "\n"), 'v:val=~"^HOME="')
let home = len(env) == 0 ? "" : substitute(env[0], '[^=]\+=', '', '')
call assert_equal(a:exp, home)
endfunc
func CheckHome(exp, ...)
"call assert_equal(a:exp, $HOME)
"call assert_equal(a:exp, expand('~', ':p'))
if !a:0
call CheckHomeIsMissingFromSubprocessEnvironment()
else
call CheckHomeIsInSubprocessEnvironment(a:exp)
endif
endfunc
func TestWindowsHome()
command! -nargs=* SaveEnv call <SID>save_env(<f-args>)
command! -nargs=* RestoreEnv call <SID>restore_env()
command! -nargs=* UnletEnv call <SID>unlet_env(<f-args>)
SaveEnv $HOME $USERPROFILE $HOMEDRIVE $HOMEPATH
try
RestoreEnv
UnletEnv $HOME $USERPROFILE $HOMEPATH
let $HOMEDRIVE = 'C:'
call CheckHome('C:\')
RestoreEnv
UnletEnv $HOME $USERPROFILE
let $HOMEDRIVE = 'C:'
let $HOMEPATH = '\foobar'
call CheckHome('C:\foobar')
RestoreEnv
UnletEnv $HOME $HOMEDRIVE $HOMEPATH
let $USERPROFILE = 'C:\foo'
call CheckHome('C:\foo')
RestoreEnv
UnletEnv $HOME
let $USERPROFILE = 'C:\foo'
let $HOMEDRIVE = 'C:'
let $HOMEPATH = '\baz'
call CheckHome('C:\foo')
RestoreEnv
let $HOME = 'C:\bar'
let $USERPROFILE = 'C:\foo'
let $HOMEDRIVE = 'C:'
let $HOMEPATH = '\baz'
call CheckHome('C:\bar', 1)
RestoreEnv
let $HOME = '%USERPROFILE%\bar'
let $USERPROFILE = 'C:\foo'
let $HOMEDRIVE = 'C:'
let $HOMEPATH = '\baz'
call CheckHome('%USERPROFILE%\bar', 1)
RestoreEnv
let $HOME = '%USERPROFILE'
let $USERPROFILE = 'C:\foo'
let $HOMEDRIVE = 'C:'
let $HOMEPATH = '\baz'
call CheckHome('%USERPROFILE', 1)
RestoreEnv
let $HOME = 'C:\%USERPROFILE%'
let $USERPROFILE = 'C:\foo'
let $HOMEDRIVE = 'C:'
let $HOMEPATH = '\baz'
call CheckHome('C:\%USERPROFILE%', 1)
if has('channel')
RestoreEnv
UnletEnv $HOME
let env = ''
let job = job_start('cmd /c set', {'out_cb': {ch,x->[env,execute('let env=x')]}})
sleep 1
let env = filter(split(env, "\n"), 'v:val=="HOME"')
let home = len(env) == 0 ? "" : env[0]
call assert_equal('', home)
endif
finally
RestoreEnv
delcommand SaveEnv
delcommand RestoreEnv
delcommand UnletEnv
endtry
endfunc
View
@@ -769,6 +769,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1012,
/**/
1011,
/**/

0 comments on commit 48340b6

Please sign in to comment.