changeset 11213:290f5f6a2bac v8.0.0493

patch 8.0.0493: crash with cd command with very long argument commit https://github.com/vim/vim/commit/15618fa643867cf0d9c31f327022a22dff78a0cf Author: Bram Moolenaar <Bram@vim.org> 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)
author Christian Brabandt <cb@256bit.org>
date Sun, 19 Mar 2017 21:45:05 +0100
parents 22a64df8374b
children 6a6e9495cff4
files src/Makefile src/misc2.c src/testdir/test_alot.vim src/testdir/test_cd.vim src/version.c
diffstat 5 files changed, 58 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- 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 \
--- 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;
 }
--- 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
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
--- 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,