]> granicus.if.org Git - vim/commitdiff
patch 8.0.1012: MS-Windows: problem with $HOME when is was set internally v8.0.1012
authorBram Moolenaar <Bram@vim.org>
Tue, 29 Aug 2017 20:08:53 +0000 (22:08 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 29 Aug 2017 20:08:53 +0000 (22:08 +0200)
Problem:    MS-Windows: Problem with $HOME when is was set internally.
Solution:   Only use the $HOME default internally. (Yasuhiro Matsumoto, closes
            #2013)

src/Makefile
src/misc1.c
src/testdir/Make_all.mak
src/testdir/test_windows_home.vim [new file with mode: 0644]
src/version.c

index e4da3b4b6b8481c13b5199c4ed7909b1bead540c..ecf14bc49b947701e3934ebc911d837d4e83671a 100644 (file)
@@ -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 \
index bd7dcefbe4a30264d4f616626ba9e642ea9bfb2d..632571dbe17d9f3c794681ea907fcdb55aa0f19d 100644 (file)
@@ -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,9 +3820,7 @@ init_homedir(void)
        }
     }
 # endif
-#endif
 
-#if defined(MSWIN)
     /*
      * Default home dir is C:/
      * Best assumption we can make in such a situation.
@@ -3833,6 +3828,7 @@ init_homedir(void)
     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)
index 678fc80000a6758314c9639feed8d9d869e94311..2a267d653e431d210f9d79c39a1543daea0779db 100644 (file)
@@ -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.
diff --git a/src/testdir/test_windows_home.vim b/src/testdir/test_windows_home.vim
new file mode 100644 (file)
index 0000000..082f217
--- /dev/null
@@ -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
index 0ef208437ae946f13c073317c7c444924d2d0e90..3be91c249ac804a15ef0d686ec050e86054a5ec5 100644 (file)
@@ -769,6 +769,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1012,
 /**/
     1011,
 /**/