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)
diff --git a/src/Makefile b/src/Makefile
index 551bb6f..3d13b85 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2096,6 +2096,7 @@
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 357511d..2ded997 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -4637,13 +4637,23 @@
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 @@
if (*p > 0)
{
(*p)--;
- file_path[len++] = '*';
+ if (len + 1 < MAXPATHL)
+ file_path[len++] = '*';
+ else
+ goto fail;
}
if (*p == 0)
@@ -4688,7 +4701,10 @@
*/
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 @@
/* 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 @@
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 @@
}
#endif
+fail:
vim_free(file_path);
return NULL;
}
diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim
index 33fba67..314a5b7 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 0000000..e573419
--- /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 75afd62..72516f0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 493,
+/**/
492,
/**/
491,