From 15618fa643867cf0d9c31f327022a22dff78a0cf Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 19 Mar 2017 21:37:13 +0100 Subject: 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 pending, closes #1576) --- src/Makefile | 1 + src/misc2.c | 53 ++++++++++++++++++++++++++++++++++++----------- src/testdir/test_alot.vim | 1 + src/testdir/test_cd.vim | 13 ++++++++++++ src/version.c | 2 ++ 5 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 src/testdir/test_cd.vim (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 551bb6fdd..3d13b85e5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2096,6 +2096,7 @@ test_arglist \ test_backspace_opt \ test_breakindent \ test_bufwintabinfo \ + test_cd \ test_cdo \ test_changedtick \ test_channel \ diff --git a/src/misc2.c b/src/misc2.c index 357511d0a..2ded997de 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -4637,13 +4637,23 @@ vim_findfile(void *search_ctx_arg) if (!vim_isAbsName(stackp->ffs_fix_path) && search_ctx->ffsc_start_dir) { - STRCPY(file_path, search_ctx->ffsc_start_dir); - add_pathsep(file_path); + if (STRLEN(search_ctx->ffsc_start_dir) + 1 < MAXPATHL) + { + STRCPY(file_path, search_ctx->ffsc_start_dir); + add_pathsep(file_path); + } + else + goto fail; } /* append the fix part of the search path */ - STRCAT(file_path, stackp->ffs_fix_path); - add_pathsep(file_path); + if (STRLEN(file_path) + STRLEN(stackp->ffs_fix_path) + 1 < MAXPATHL) + { + STRCAT(file_path, stackp->ffs_fix_path); + add_pathsep(file_path); + } + else + goto fail; #ifdef FEAT_PATH_EXTRA rest_of_wildcards = stackp->ffs_wc_path; @@ -4660,7 +4670,10 @@ vim_findfile(void *search_ctx_arg) if (*p > 0) { (*p)--; - file_path[len++] = '*'; + if (len + 1 < MAXPATHL) + file_path[len++] = '*'; + else + goto fail; } if (*p == 0) @@ -4688,7 +4701,10 @@ vim_findfile(void *search_ctx_arg) */ while (*rest_of_wildcards && !vim_ispathsep(*rest_of_wildcards)) - file_path[len++] = *rest_of_wildcards++; + if (len + 1 < MAXPATHL) + file_path[len++] = *rest_of_wildcards++; + else + goto fail; file_path[len] = NUL; if (vim_ispathsep(*rest_of_wildcards)) @@ -4749,9 +4765,15 @@ vim_findfile(void *search_ctx_arg) /* prepare the filename to be checked for existence * below */ - STRCPY(file_path, stackp->ffs_filearray[i]); - add_pathsep(file_path); - STRCAT(file_path, search_ctx->ffsc_file_to_search); + if (STRLEN(stackp->ffs_filearray[i]) + 1 + + STRLEN(search_ctx->ffsc_file_to_search) < MAXPATHL) + { + STRCPY(file_path, stackp->ffs_filearray[i]); + add_pathsep(file_path); + STRCAT(file_path, search_ctx->ffsc_file_to_search); + } + else + goto fail; /* * Try without extra suffix and then with suffixes @@ -4924,9 +4946,15 @@ vim_findfile(void *search_ctx_arg) if (*search_ctx->ffsc_start_dir == 0) break; - STRCPY(file_path, search_ctx->ffsc_start_dir); - add_pathsep(file_path); - STRCAT(file_path, search_ctx->ffsc_fix_path); + if (STRLEN(search_ctx->ffsc_start_dir) + 1 + + STRLEN(search_ctx->ffsc_fix_path) < MAXPATHL) + { + STRCPY(file_path, search_ctx->ffsc_start_dir); + add_pathsep(file_path); + STRCAT(file_path, search_ctx->ffsc_fix_path); + } + else + goto fail; /* create a new stack entry */ sptr = ff_create_stack_element(file_path, @@ -4940,6 +4968,7 @@ vim_findfile(void *search_ctx_arg) } #endif +fail: vim_free(file_path); return NULL; } diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim index 33fba67c2..314a5b7f5 100644 --- a/src/testdir/test_alot.vim +++ b/src/testdir/test_alot.vim @@ -3,6 +3,7 @@ set belloff=all source test_assign.vim +source test_cd.vim source test_changedtick.vim source test_cursor_func.vim source test_delete.vim diff --git a/src/testdir/test_cd.vim b/src/testdir/test_cd.vim new file mode 100644 index 000000000..e573419bd --- /dev/null +++ b/src/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 diff --git a/src/version.c b/src/version.c index 75afd62d4..72516f05c 100644 --- a/src/version.c +++ b/src/version.c @@ -764,6 +764,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 493, /**/ 492, /**/ -- cgit v1.2.3