# HG changeset patch # User Christian Brabandt # Date 1489956305 -3600 # Node ID 290f5f6a2bac713d64632b2af27c019340b0f17a # Parent 22a64df8374b0fc41a4de9b659dfb6f59644d8c1 patch 8.0.0493: crash with cd command with very long argument commit https://github.com/vim/vim/commit/15618fa643867cf0d9c31f327022a22dff78a0cf Author: Bram Moolenaar Date: Sun Mar 19 21:37:13 2017 +0100 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 https://github.com/vim/vim/issues/1576) diff --git a/src/Makefile b/src/Makefile --- 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 --- 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 --- 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 --- /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 --- a/src/version.c +++ b/src/version.c @@ -765,6 +765,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 493, +/**/ 492, /**/ 491,