diff --git a/ChangeLog b/ChangeLog
index d97334057bbd0acd8460f79eb05f35f63e40e9b6..63e3f35f557ce9670c8defc7012551874c11ba4b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -182,10 +182,11 @@ CVS code -
 	  break_line(), do_para_search() (renamed find_paragraph()), and
 	  do_justify(); removal of breakable(). (DLR)
 	- Still more steps toward full wide/multibyte character support.
-	  Make whitespace display mode work with multibyte characters,
+	  Make sure all rcfile arguments are valid multibyte strings,
+	  make whitespace display mode work with multibyte characters,
 	  and add a few related documentation updates.  New function
-	  make_mbstring(); changes to do_help(), main(), parse_rcfile(),
-	  and display_string(). (DLR)
+	  make_mbstring(); changes to make_mbchar(), make_mbstring(),
+	  do_help(), main(), parse_rcfile(), and display_string(). (DLR)
 - cut.c:
   do_cut_text()
 	- If keep_cutbuffer is FALSE, only blow away the text in the
diff --git a/src/chars.c b/src/chars.c
index e2da3ad9bf6b55eefc72529d0290fef7dd28696c..4321281b02e204fa2453ef0b202c1aa1cb03e6b3 100644
--- a/src/chars.c
+++ b/src/chars.c
@@ -272,14 +272,17 @@ int mb_cur_max(void)
 }
 
 /* Convert the value in chr to a multibyte character with the same
- * wide character value as chr.  Return the multibyte character and its
- * length. */
-char *make_mbchar(int chr, char *chr_mb, int *chr_mb_len)
+ * wide character value as chr.  Return the (dynamically allocated)
+ * multibyte character and its length. */
+char *make_mbchar(int chr, int *chr_mb_len)
 {
     assert(chr_mb != NULL && chr_mb_len != NULL);
 
+    char *chr_mb;
+
 #ifdef NANO_WIDE
     if (!ISSET(NO_UTF8)) {
+	chr_mb = charalloc(MB_CUR_MAX);
 	*chr_mb_len = wctomb(chr_mb, chr);
 
 	if (*chr_mb_len <= 0) {
@@ -289,6 +292,7 @@ char *make_mbchar(int chr, char *chr_mb, int *chr_mb_len)
     } else {
 #endif
 	*chr_mb_len = 1;
+	chr_mb = charalloc(1);	
 	chr_mb[0] = (char)chr;
 #ifdef NANO_WIDE
     }
@@ -299,18 +303,20 @@ char *make_mbchar(int chr, char *chr_mb, int *chr_mb_len)
 
 #if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
 /* Convert the string str to a valid multibyte string with the same wide
- * character values as str.  Return the multibyte string. */
-char *make_mbstring(char *str, char *str_mb)
+ * character values as str.  Return the (dynamically allocated)
+ * multibyte string. */
+char *make_mbstring(char *str)
 {
-    assert(str != NULL && str_mb != NULL);
+    assert(str != NULL);
+
+    char *str_mb;
 
 #ifdef NANO_WIDE
     if (!ISSET(NO_UTF8)) {
 	char *chr_mb = charalloc(MB_CUR_MAX);
 	int chr_mb_len;
-	size_t str_mb_len = 0;
-
 	str_mb = charalloc((MB_CUR_MAX * strlen(str)) + 1);
+	size_t str_mb_len = 0;
 
 	while (*str != '\0') {
 	    bool bad_char;
@@ -319,11 +325,11 @@ char *make_mbstring(char *str, char *str_mb)
 	    chr_mb_len = parse_mbchar(str, chr_mb, &bad_char, NULL);
 
 	    if (bad_char) {
-		char *bad_chr_mb = charalloc(MB_CUR_MAX);
+		char *bad_chr_mb;
 		int bad_chr_mb_len;
 
 		bad_chr_mb = make_mbchar((unsigned char)chr_mb[0],
-		    bad_chr_mb, &bad_chr_mb_len);
+		    &bad_chr_mb_len);
 
 		for (i = 0; i < bad_chr_mb_len; i++)
 		    str_mb[str_mb_len + i] = bad_chr_mb[i];
diff --git a/src/proto.h b/src/proto.h
index ac64923156ece1c2f99ffffab52d668b8bf42076..b0996d40a6f42ad8490bad696ae352abab5c9e37 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -174,9 +174,9 @@ wchar_t control_wrep(wchar_t c);
 #endif
 int mbwidth(const char *c);
 int mb_cur_max(void);
-char *make_mbchar(int chr, char *chr_mb, int *chr_mb_len);
+char *make_mbchar(int chr, int *chr_mb_len);
 #if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
-char *make_mbstring(char *str, char *str_mb);
+char *make_mbstring(char *str);
 #endif
 int parse_mbchar(const char *buf, char *chr, bool *bad_chr, size_t
 	*col);
diff --git a/src/rcfile.c b/src/rcfile.c
index 6ca952bfbe2d93526ae96c67024d3e942fcfd5df..377fb2260ccdff93dd599c4ba9d3a90cba8d9145 100644
--- a/src/rcfile.c
+++ b/src/rcfile.c
@@ -561,12 +561,13 @@ void parse_rcfile(FILE *rcstream)
 			if (*option == '"')
 			    option++;
 			ptr = parse_argument(ptr);
+			option = make_mbstring(option);
 #ifdef DEBUG
 			fprintf(stderr, "option = \"%s\"\n", option);
 #endif
 #ifndef DISABLE_OPERATINGDIR
 			if (strcasecmp(rcopts[i].name, "operatingdir") == 0)
-			    operating_dir = mallocstrcpy(NULL, option);
+			    operating_dir = option;
 			else
 #endif
 #ifndef DISABLE_WRAPJUSTIFY
@@ -576,12 +577,13 @@ void parse_rcfile(FILE *rcstream)
 					N_("Requested fill size %s invalid"),
 					option);
 				wrap_at = -CHARS_FROM_EOL;
-			    }
+			    } else
+				free(option);
 			} else
 #endif
 #ifndef NANO_SMALL
 			if (strcasecmp(rcopts[i].name, "whitespace") == 0) {
-			    whitespace = make_mbstring(option, whitespace);
+			    whitespace = option;
 			    if (mbstrlen(whitespace) != 2 || strlenpt(whitespace) != 2) {
 				rcfile_error(
 					N_("Two single-column characters required"));
@@ -600,7 +602,7 @@ void parse_rcfile(FILE *rcstream)
 #endif
 #ifndef DISABLE_JUSTIFY
 			if (strcasecmp(rcopts[i].name, "punct") == 0) {
-			    punct = mallocstrcpy(NULL, option);
+			    punct = option;
 			    if (strchr(punct, '\t') != NULL ||
 				strchr(punct, ' ') != NULL) {
 				rcfile_error(
@@ -610,7 +612,7 @@ void parse_rcfile(FILE *rcstream)
 			    }
 			} else if (strcasecmp(rcopts[i].name,
 				"brackets") == 0) {
-			    brackets = mallocstrcpy(NULL, option);
+			    brackets = option;
 			    if (strchr(brackets, '\t') != NULL ||
 				strchr(brackets, ' ') != NULL) {
 				rcfile_error(
@@ -620,18 +622,18 @@ void parse_rcfile(FILE *rcstream)
 			    }
 			} else if (strcasecmp(rcopts[i].name,
 				"quotestr") == 0)
-			    quotestr = mallocstrcpy(NULL, option);
+			    quotestr = option;
 			else
 #endif
 #ifndef NANO_SMALL
 			if (strcasecmp(rcopts[i].name,
 				"backupdir") == 0)
-			    backup_dir = mallocstrcpy(NULL, option);
+			    backup_dir = option;
 			else
 #endif
 #ifndef DISABLE_SPELLER
 			if (strcasecmp(rcopts[i].name, "speller") == 0)
-			    alt_speller = mallocstrcpy(NULL, option);
+			    alt_speller = option;
 			else
 #endif
 			if (strcasecmp(rcopts[i].name,
@@ -642,7 +644,8 @@ void parse_rcfile(FILE *rcstream)
 					N_("Requested tab size %s invalid"),
 					option);
 				tabsize = -1;
-			    }
+			    } else
+				free(option);
 			} else
 			    assert(FALSE);
 		    }
diff --git a/src/winio.c b/src/winio.c
index bc0b92019eb16830bd5567c1542a04c6c207fd68..80aef2ec16fdb03cde83648d3bf3d5f64c02bb6e 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -546,7 +546,7 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key
 				);
 
 			if (byte != ERR) {
-			    char *byte_mb = charalloc(mb_cur_max());
+			    char *byte_mb;
 			    int byte_mb_len, *seq, i;
 
 			    /* If we've read in a complete byte
@@ -558,8 +558,7 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key
 
 			    /* Put back the multibyte equivalent of the
 			     * byte value. */
-			    byte_mb = make_mbchar(byte, byte_mb,
-				&byte_mb_len);
+			    byte_mb = make_mbchar(byte, &byte_mb_len);
 
 			    seq = (int *)nmalloc(byte_mb_len *
 				sizeof(int));
@@ -1424,7 +1423,7 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *kbinput_len)
     /* Otherwise, read in keystrokes until we have a complete word
      * sequence, and put back the corresponding word value. */
     else {
-	char *word_mb = charalloc(mb_cur_max());
+	char *word_mb;
 	int word_mb_len, *seq, i;
 
 	while (word == ERR) {
@@ -1438,7 +1437,7 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *kbinput_len)
 	}
 
 	/* Put back the multibyte equivalent of the word value. */
-	word_mb = make_mbchar(word, word_mb, &word_mb_len);
+	word_mb = make_mbchar(word, &word_mb_len);
 
 	seq = (int *)nmalloc(word_mb_len * sizeof(int));
 
@@ -2331,11 +2330,11 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
 	     * character, interpret that character as though it's a
 	     * normal non-control character. */
 	    if (!ISSET(NO_UTF8) && bad_char) {
-		char *bad_buf_mb = charalloc(mb_cur_max());
+		char *bad_buf_mb;
 		int bad_buf_mb_len;
 
 		bad_buf_mb = make_mbchar((unsigned char)*buf_mb,
-			bad_buf_mb, &bad_buf_mb_len);
+			&bad_buf_mb_len);
 
 		for (i = 0; i < bad_buf_mb_len; i++)
 		    converted[index++] = bad_buf_mb[i];