changeset 16277:5ef25fa57f71 v8.1.1143

patch 8.1.1143: may pass weird strings to file name expansion commit https://github.com/vim/vim/commit/8f130eda4747e4a4d68353cdb650f359fd01469b Author: Bram Moolenaar <Bram@vim.org> Date: Wed Apr 10 22:15:19 2019 +0200 patch 8.1.1143: may pass weird strings to file name expansion Problem: May pass weird strings to file name expansion. Solution: Check for matching characters. Disallow control characters.
author Bram Moolenaar <Bram@vim.org>
date Wed, 10 Apr 2019 22:30:06 +0200
parents 8322ad152939
children 957309499096
files src/misc1.c src/option.c src/proto/option.pro src/spell.c src/testdir/test_escaped_glob.vim src/testdir/test_spell.vim src/version.c
diffstat 7 files changed, 58 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -6170,11 +6170,22 @@ has_special_wildchar(char_u *p)
 {
     for ( ; *p; MB_PTR_ADV(p))
     {
-	/* Allow for escaping. */
-	if (*p == '\\' && p[1] != NUL)
+	// Disallow line break characters.
+	if (*p == '\r' || *p == '\n')
+	    break;
+	// Allow for escaping.
+	if (*p == '\\' && p[1] != NUL && p[1] != '\r' && p[1] != '\n')
 	    ++p;
 	else if (vim_strchr((char_u *)SPECIAL_WILDCHAR, *p) != NULL)
+	{
+	    // A { must be followed by a matching }.
+	    if (*p == '{' && vim_strchr(p, '}') == NULL)
+		continue;
+	    // A quote and backtick must be followed by another one.
+	    if ((*p == '`' || *p == '\'') && vim_strchr(p, *p) == NULL)
+		continue;
 	    return TRUE;
+	}
     }
     return FALSE;
 }
--- a/src/option.c
+++ b/src/option.c
@@ -6006,18 +6006,37 @@ set_string_option(
 }
 
 /*
+ * Return TRUE if "val" is a valid name: only consists of alphanumeric ASCII
+ * characters or characters in "allowed".
+ */
+    static int
+valid_name(char_u *val, char *allowed)
+{
+    char_u *s;
+
+    for (s = val; *s != NUL; ++s)
+	if (!ASCII_ISALNUM(*s) && vim_strchr((char_u *)allowed, *s) == NULL)
+	    return FALSE;
+    return TRUE;
+}
+
+/*
  * Return TRUE if "val" is a valid 'filetype' name.
  * Also used for 'syntax' and 'keymap'.
  */
     static int
 valid_filetype(char_u *val)
 {
-    char_u *s;
-
-    for (s = val; *s != NUL; ++s)
-	if (!ASCII_ISALNUM(*s) && vim_strchr((char_u *)".-_", *s) == NULL)
-	    return FALSE;
-    return TRUE;
+    return valid_name(val, ".-_");
+}
+
+/*
+ * Return TRUE if "val" is a valid 'spellang' value.
+ */
+    int
+valid_spellang(char_u *val)
+{
+    return valid_name(val, ".-_,");
 }
 
 /*
@@ -7082,7 +7101,10 @@ did_set_string_option(
     else if (varp == &(curwin->w_s->b_p_spl)
 	    || varp == &(curwin->w_s->b_p_spf))
     {
-	errmsg = did_set_spell_option(varp == &(curwin->w_s->b_p_spf));
+	if (!valid_spellang(*varp))
+	    errmsg = e_invarg;
+	else
+	    errmsg = did_set_spell_option(varp == &(curwin->w_s->b_p_spf));
     }
     /* When 'spellcapcheck' is set compile the regexp program. */
     else if (varp == &(curwin->w_s->b_p_spc))
@@ -7737,7 +7759,8 @@ did_set_string_option(
 		    break;
 	    if (p > q)
 	    {
-		vim_snprintf((char *)fname, 200, "spell/%.*s.vim", (int)(p - q), q);
+		vim_snprintf((char *)fname, 200, "spell/%.*s.vim",
+							      (int)(p - q), q);
 		source_runtime(fname, DIP_ALL);
 	    }
 	}
--- a/src/proto/option.pro
+++ b/src/proto/option.pro
@@ -21,6 +21,7 @@ int get_term_opt_idx(char_u **p);
 int set_term_option_alloced(char_u **p);
 int was_set_insecurely(char_u *opt, int opt_flags);
 void set_string_option_direct(char_u *name, int opt_idx, char_u *val, int opt_flags, int set_sid);
+int valid_spellang(char_u *val);
 char *check_colorcolumn(win_T *wp);
 char *check_stl_option(char_u *s);
 void set_term_option_sctx_idx(char *name, int opt_idx);
--- a/src/spell.c
+++ b/src/spell.c
@@ -2308,11 +2308,14 @@ did_set_spelllang(win_T *wp)
     /* Loop over comma separated language names. */
     for (splp = spl_copy; *splp != NUL; )
     {
-	/* Get one language name. */
+	// Get one language name.
 	copy_option_part(&splp, lang, MAXWLEN, ",");
 	region = NULL;
 	len = (int)STRLEN(lang);
 
+	if (!valid_spellang(lang))
+	    continue;
+
 	if (STRCMP(lang, "cjk") == 0)
 	{
 	    wp->w_s->b_cjk = 1;
--- a/src/testdir/test_escaped_glob.vim
+++ b/src/testdir/test_escaped_glob.vim
@@ -17,7 +17,7 @@ function Test_glob()
   " Setting 'shell' to an invalid name causes a memory leak.
   sandbox call assert_equal("", glob('Xxx\{'))
   sandbox call assert_equal("", glob('Xxx\$'))
-  w! Xxx{
+  w! Xxx\{
   w! Xxx\$
   sandbox call assert_equal("Xxx{", glob('Xxx\{'))
   sandbox call assert_equal("Xxx$", glob('Xxx\$'))
--- a/src/testdir/test_spell.vim
+++ b/src/testdir/test_spell.vim
@@ -149,6 +149,12 @@ func Test_spellinfo()
   set nospell spelllang=en
   call assert_fails('spellinfo', 'E756:')
 
+  call assert_fails('set spelllang=foo/bar', 'E474:')
+  call assert_fails('set spelllang=foo\ bar', 'E474:')
+  call assert_fails("set spelllang=foo\\\nbar", 'E474:')
+  call assert_fails("set spelllang=foo\\\rbar", 'E474:')
+  call assert_fails("set spelllang=foo+bar", 'E474:')
+
   set enc& spell& spelllang&
   bwipe
 endfunc
--- a/src/version.c
+++ b/src/version.c
@@ -772,6 +772,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1143,
+/**/
     1142,
 /**/
     1141,