diff options
-rw-r--r-- | src/nvim/file_search.c | 52 | ||||
-rw-r--r-- | src/nvim/testdir/test_alot.vim | 1 | ||||
-rw-r--r-- | src/nvim/testdir/test_cd.vim | 13 |
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 |