diff options
| -rw-r--r-- | runtime/autoload/man.vim | 5 | ||||
| -rw-r--r-- | runtime/autoload/provider/pythonx.vim | 3 | ||||
| -rw-r--r-- | src/nvim/ex_docmd.c | 2 | ||||
| -rw-r--r-- | src/nvim/os/time.c | 39 | ||||
| -rw-r--r-- | src/nvim/path.c | 47 | ||||
| -rw-r--r-- | src/nvim/testdir/test_usercommands.vim | 30 | ||||
| -rw-r--r-- | src/nvim/version.c | 2 | ||||
| -rw-r--r-- | test/unit/path_spec.lua | 11 | 
8 files changed, 101 insertions, 38 deletions
| diff --git a/runtime/autoload/man.vim b/runtime/autoload/man.vim index 6fed4a54e3..251e6eee41 100644 --- a/runtime/autoload/man.vim +++ b/runtime/autoload/man.vim @@ -113,10 +113,11 @@ function! s:system(cmd, ...) abort  endfunction  function! s:get_page(path) abort +  " Respect $MANWIDTH or default to window width. +  let manwidth = empty($MANWIDTH) ? winwidth(0) : $MANWIDTH    " Force MANPAGER=cat to ensure Vim is not recursively invoked (by man-db).    " http://comments.gmane.org/gmane.editors.vim.devel/29085 -  " Respect $MANWIDTH, or default to window width. -  return s:system(['env', 'MANPAGER=cat', (empty($MANWIDTH) ? 'MANWIDTH='.winwidth(0) : ''), 'man', a:path]) +  return s:system(['env', 'MANPAGER=cat', 'MANWIDTH='.manwidth, 'man', a:path])  endfunction  function! s:put_page(page) abort diff --git a/runtime/autoload/provider/pythonx.vim b/runtime/autoload/provider/pythonx.vim index f46c260fa3..08a0f39b01 100644 --- a/runtime/autoload/provider/pythonx.vim +++ b/runtime/autoload/provider/pythonx.vim @@ -57,7 +57,8 @@ function! provider#pythonx#Detect(major_ver) abort      if exists('g:python3_host_prog')        return [g:python3_host_prog, '']      else -      let progs = ['python3', 'python3.5', 'python3.4', 'python3.3', 'python'] +      let progs = ['python3', 'python3.7', 'python3.6', 'python3.5', +            \ 'python3.4', 'python3.3', 'python']      endif    endif diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 79a0b5849f..2c60cd0189 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1711,7 +1711,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,      xfree(p);      // If the autocommands did something and didn't cause an error, try      // finding the command again. -    p = (ret && !aborting()) ? find_command(&ea, NULL) : NULL; +    p = (ret && !aborting()) ? find_command(&ea, NULL) : ea.cmd;    }    if (p == NULL) { diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 2205ad0958..8ce2ecf4f4 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -7,6 +7,7 @@  #include <uv.h>  #include "nvim/os/time.h" +#include "nvim/os/input.h"  #include "nvim/event/loop.h"  #include "nvim/vim.h"  #include "nvim/main.h" @@ -34,10 +35,10 @@ uint64_t os_hrtime(void)    return uv_hrtime();  } -/// Sleeps for a certain amount of milliseconds +/// Sleeps for a certain amount of milliseconds.  ///  /// @param milliseconds Number of milliseconds to sleep -/// @param ignoreinput If true, allow a SIGINT to interrupt us +/// @param ignoreinput If true, only SIGINT (CTRL-C) can interrupt.  void os_delay(uint64_t milliseconds, bool ignoreinput)  {    if (ignoreinput) { @@ -46,26 +47,42 @@ void os_delay(uint64_t milliseconds, bool ignoreinput)      }      LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, (int)milliseconds, got_int);    } else { -    os_microdelay(milliseconds * 1000); +    os_microdelay(milliseconds * 1000u, ignoreinput);    }  } -/// Sleeps for a certain amount of microseconds +/// Sleeps for a certain amount of microseconds.  /// -/// @param microseconds Number of microseconds to sleep -void os_microdelay(uint64_t microseconds) +/// @param ms          Number of microseconds to sleep. +/// @param ignoreinput If true, ignore all input (including SIGINT/CTRL-C). +///                    If false, waiting is aborted on any input. +void os_microdelay(uint64_t ms, bool ignoreinput)  { -  uint64_t elapsed = 0; -  uint64_t ns = microseconds * 1000;  // convert to nanoseconds +  uint64_t elapsed = 0u;    uint64_t base = uv_hrtime(); +  // Convert microseconds to nanoseconds, or UINT64_MAX on overflow. +  const uint64_t ns = (ms < UINT64_MAX / 1000u) ? ms * 1000u : UINT64_MAX;    uv_mutex_lock(&delay_mutex);    while (elapsed < ns) { -    if (uv_cond_timedwait(&delay_cond, &delay_mutex, ns - elapsed) -        == UV_ETIMEDOUT) +    // If ignoring input, we simply wait the full delay. +    // Else we check for input in ~100ms intervals. +    const uint64_t ns_delta = ignoreinput +                              ? ns - elapsed +                              : MIN(ns - elapsed, 100000000u);  // 100ms + +    const int rv = uv_cond_timedwait(&delay_cond, &delay_mutex, ns_delta); +    if (0 != rv && UV_ETIMEDOUT != rv) { +      assert(false); +      break; +    }  // Else: Timeout proceeded normally. + +    if (!ignoreinput && os_char_avail()) {        break; -    uint64_t now = uv_hrtime(); +    } + +    const uint64_t now = uv_hrtime();      elapsed += now - base;      base = now;    } diff --git a/src/nvim/path.c b/src/nvim/path.c index 6149e1ab99..3d1def8dd4 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -417,15 +417,11 @@ char *FullName_save(char *fname, bool force)    }    char *buf = xmalloc(MAXPATHL); -  char *new_fname = NULL; -  if (vim_FullName(fname, buf, MAXPATHL, force) != FAIL) { -    new_fname = xstrdup(buf); -  } else { -    new_fname = xstrdup(fname); +  if (vim_FullName(fname, buf, MAXPATHL, force) == FAIL) { +    xfree(buf); +    return xstrdup(fname);    } -  xfree(buf); - -  return new_fname; +  return buf;  }  /// Saves the absolute path. @@ -1649,30 +1645,37 @@ bool vim_isAbsName(char_u *name)  /// Save absolute file name to "buf[len]".  /// -/// @param      fname is the filename to evaluate -/// @param[out] buf   is the buffer for returning the absolute path for `fname` -/// @param      len   is the length of `buf` -/// @param      force is a flag to force expanding even if the path is absolute +/// @param      fname filename to evaluate +/// @param[out] buf   contains `fname` absolute path, or: +///                   - truncated `fname` if longer than `len` +///                   - 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  int vim_FullName(const char *fname, char *buf, size_t len, bool force)    FUNC_ATTR_NONNULL_ARG(2)  { -  int retval = OK; -  int url; -    *buf = NUL; -  if (fname == NULL) +  if (fname == NULL) {      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) */ +  if (strlen(fname) > (len - 1)) { +    xstrlcpy(buf, fname, len);  // truncate +    return FAIL; +  } + +  if (path_with_url(fname)) {      xstrlcpy(buf, fname, len); +    return OK;    } -  return retval; + +  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` diff --git a/src/nvim/testdir/test_usercommands.vim b/src/nvim/testdir/test_usercommands.vim index f593d16dbf..facd675f88 100644 --- a/src/nvim/testdir/test_usercommands.vim +++ b/src/nvim/testdir/test_usercommands.vim @@ -46,3 +46,33 @@ function Test_cmdmods()    delcommand MyQCmd    unlet g:mods  endfunction + +func Test_Ambiguous() +  command Doit let g:didit = 'yes' +  command Dothat let g:didthat = 'also' +  call assert_fails('Do', 'E464:') +  Doit +  call assert_equal('yes', g:didit) +  Dothat +  call assert_equal('also', g:didthat) +  unlet g:didit +  unlet g:didthat + +  delcommand Doit +  Do +  call assert_equal('also', g:didthat) +  delcommand Dothat +endfunc + +func Test_CmdUndefined() +  call assert_fails('Doit', 'E492:') +  au CmdUndefined Doit :command Doit let g:didit = 'yes' +  Doit +  call assert_equal('yes', g:didit) +  delcommand Doit + +  call assert_fails('Dothat', 'E492:') +  au CmdUndefined * let g:didnot = 'yes' +  call assert_fails('Dothat', 'E492:') +  call assert_equal('yes', g:didnot) +endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index 8d2c89c950..6ddc0cd77e 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -330,7 +330,7 @@ static int included_patches[] = {    // 2113,    2112,    // 2111, -  // 2110, +  2110,    2109,    // 2108 NA    // 2107, diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua index 9b76834383..ccaf0228ab 100644 --- a/test/unit/path_spec.lua +++ b/test/unit/path_spec.lua @@ -336,6 +336,17 @@ describe('more path function', function()        eq(FAIL, result)      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()        local force_expansion = 1        local filename = 'http://www.neovim.org' | 
