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.
diff --git a/src/misc1.c b/src/misc1.c
index 54da890..3797094 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -6170,11 +6170,22 @@
 {
     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;
 }
diff --git a/src/option.c b/src/option.c
index 4564395..e4b1d5f 100644
--- a/src/option.c
+++ b/src/option.c
@@ -6006,18 +6006,37 @@
 }
 
 /*
+ * 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;
+    return valid_name(val, ".-_");
+}
 
-    for (s = val; *s != NUL; ++s)
-	if (!ASCII_ISALNUM(*s) && vim_strchr((char_u *)".-_", *s) == NULL)
-	    return FALSE;
-    return TRUE;
+/*
+ * Return TRUE if "val" is a valid 'spellang' value.
+ */
+    int
+valid_spellang(char_u *val)
+{
+    return valid_name(val, ".-_,");
 }
 
 /*
@@ -7082,7 +7101,10 @@
     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 @@
 		    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);
 	    }
 	}
diff --git a/src/proto/option.pro b/src/proto/option.pro
index 1027edf..15aa010 100644
--- a/src/proto/option.pro
+++ b/src/proto/option.pro
@@ -21,6 +21,7 @@
 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);
diff --git a/src/spell.c b/src/spell.c
index ae4db12..947bee5 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -2308,11 +2308,14 @@
     /* 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;
diff --git a/src/testdir/test_escaped_glob.vim b/src/testdir/test_escaped_glob.vim
index 880f32e..a03c180 100644
--- a/src/testdir/test_escaped_glob.vim
+++ b/src/testdir/test_escaped_glob.vim
@@ -17,7 +17,7 @@
   " 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\$'))
diff --git a/src/testdir/test_spell.vim b/src/testdir/test_spell.vim
index 76ad12e..6bf43ac 100644
--- a/src/testdir/test_spell.vim
+++ b/src/testdir/test_spell.vim
@@ -149,6 +149,12 @@
   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
diff --git a/src/version.c b/src/version.c
index a9e4ccf..3e0e95f 100644
--- a/src/version.c
+++ b/src/version.c
@@ -772,6 +772,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1143,
+/**/
     1142,
 /**/
     1141,