aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Edmund Lazo <janedmundlazo@hotmail.com>2018-07-22 16:18:51 -0400
committerJan Edmund Lazo <janedmundlazo@hotmail.com>2018-07-22 19:34:58 -0400
commit563957e3cb778305230a2b1f9d5d64a682b60b7a (patch)
tree92012f0585eabb35b6a838bd492118c122e04a37
parent13d29cb9ed0d6fba734dc5a96ed543326ee14b3f (diff)
downloadrneovim-563957e3cb778305230a2b1f9d5d64a682b60b7a.tar.gz
rneovim-563957e3cb778305230a2b1f9d5d64a682b60b7a.tar.bz2
rneovim-563957e3cb778305230a2b1f9d5d64a682b60b7a.zip
vim-patch:8.0.0493: crash with cd command with very long argument
Problem: Crash with cd command with very long argument. Solution: Check for running out of space. (Dominique Pellé, closes vim/vim#1576) https://github.com/vim/vim/commit/15618fa643867cf0d9c31f327022a22dff78a0cf
-rw-r--r--src/nvim/file_search.c52
-rw-r--r--src/nvim/testdir/test_alot.vim1
-rw-r--r--src/nvim/testdir/test_cd.vim13
3 files changed, 54 insertions, 12 deletions
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index 5b17b58781..ebe6dce5b1 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -683,28 +683,40 @@ char_u *vim_findfile(void *search_ctx_arg)
dirptrs[0] = file_path;
dirptrs[1] = NULL;
- /* if we have a start dir copy it in */
+ // if we have a start dir copy it in
if (!vim_isAbsName(stackp->ffs_fix_path)
&& search_ctx->ffsc_start_dir) {
+ if (STRLEN(search_ctx->ffsc_start_dir) + 1 >= MAXPATHL) {
+ goto fail;
+ }
STRCPY(file_path, search_ctx->ffsc_start_dir);
- add_pathsep((char *)file_path);
+ if (!add_pathsep((char *)file_path)) {
+ goto fail;
+ }
}
- /* append the fix part of the search path */
+ // append the fix part of the search path
+ if (STRLEN(file_path) + STRLEN(stackp->ffs_fix_path) + 1 >= MAXPATHL) {
+ goto fail;
+ }
STRCAT(file_path, stackp->ffs_fix_path);
- add_pathsep((char *)file_path);
+ if (!add_pathsep((char *)file_path)) {
+ goto fail;
+ }
rest_of_wildcards = stackp->ffs_wc_path;
if (*rest_of_wildcards != NUL) {
len = STRLEN(file_path);
if (STRNCMP(rest_of_wildcards, "**", 2) == 0) {
- /* pointer to the restrict byte
- * The restrict byte is not a character!
- */
+ // pointer to the restrict byte
+ // The restrict byte is not a character!
p = rest_of_wildcards + 2;
if (*p > 0) {
(*p)--;
+ if (len + 1 >= MAXPATHL) {
+ goto fail;
+ }
file_path[len++] = '*';
}
@@ -729,8 +741,12 @@ char_u *vim_findfile(void *search_ctx_arg)
* on the stack again for further search.
*/
while (*rest_of_wildcards
- && !vim_ispathsep(*rest_of_wildcards))
+ && !vim_ispathsep(*rest_of_wildcards)) {
+ if (len + 1 >= MAXPATHL) {
+ goto fail;
+ }
file_path[len++] = *rest_of_wildcards++;
+ }
file_path[len] = NUL;
if (vim_ispathsep(*rest_of_wildcards))
@@ -773,10 +789,15 @@ char_u *vim_findfile(void *search_ctx_arg)
&& !os_isdir(stackp->ffs_filearray[i]))
continue; /* not a directory */
- /* prepare the filename to be checked for existence
- * below */
+ // prepare the filename to be checked for existence below
+ if (STRLEN(stackp->ffs_filearray[i]) + 1
+ + STRLEN(search_ctx->ffsc_file_to_search) >= MAXPATHL) {
+ goto fail;
+ }
STRCPY(file_path, stackp->ffs_filearray[i]);
- add_pathsep((char *)file_path);
+ if (!add_pathsep((char *)file_path)) {
+ goto fail;
+ }
STRCAT(file_path, search_ctx->ffsc_file_to_search);
/*
@@ -924,8 +945,14 @@ char_u *vim_findfile(void *search_ctx_arg)
if (*search_ctx->ffsc_start_dir == 0)
break;
+ if (STRLEN(search_ctx->ffsc_start_dir) + 1
+ + STRLEN(search_ctx->ffsc_fix_path) >= MAXPATHL) {
+ goto fail;
+ }
STRCPY(file_path, search_ctx->ffsc_start_dir);
- add_pathsep((char *)file_path);
+ if (!add_pathsep((char *)file_path)) {
+ goto fail;
+ }
STRCAT(file_path, search_ctx->ffsc_fix_path);
/* create a new stack entry */
@@ -936,6 +963,7 @@ char_u *vim_findfile(void *search_ctx_arg)
break;
}
+fail:
xfree(file_path);
return NULL;
}
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index 1a70ac152f..d026221dac 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -2,6 +2,7 @@
" This makes testing go faster, since Vim doesn't need to restart.
source test_assign.vim
+source test_cd.vim
source test_changedtick.vim
source test_cursor_func.vim
source test_ex_undo.vim
diff --git a/src/nvim/testdir/test_cd.vim b/src/nvim/testdir/test_cd.vim
new file mode 100644
index 0000000000..e573419bd0
--- /dev/null
+++ b/src/nvim/testdir/test_cd.vim
@@ -0,0 +1,13 @@
+" Test for :cd
+
+func Test_cd_large_path()
+ " This used to crash with a heap write overflow.
+ call assert_fails('cd ' . repeat('x', 5000), 'E472:')
+endfunc
+
+func Test_cd_up_and_down()
+ let path = getcwd()
+ cd ..
+ exe 'cd ' . path
+ call assert_equal(path, getcwd())
+endfunc