diff --git a/ChangeLog b/ChangeLog
index 5b6201249e046a4fe239e9aebbdee218afa44aff..8ea1d695fbb4a7a96d748ed52324dcf00142272f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -260,6 +260,9 @@ CVS code -
 	  the number of lines and characters in the file or selection,
 	  as wc does. (DLR)
 - winio.c:
+  get_word_kbinput()
+	- Limit the input word to hexadecimal FFFD instead of FFFF, as
+	  FFFE and FFFF are invalid Unicode characters. (DLR)
   display_string()
 	- Instead of using parse_mbchar()'s bad_chr parameter, use
 	  mbrep() to get the representation of a bad character. (DLR)
diff --git a/src/winio.c b/src/winio.c
index e77a9f4fe9a3d65401ee95135a7e84e08bf9008e..c7a17e1016bf4ff3d10072d24e186a085c2549f0 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -1232,7 +1232,7 @@ int get_byte_kbinput(int kbinput
 }
 
 /* Translate a word sequence: turn a four-digit hexadecimal number from
- * 0000 to ffff (case-insensitive) into its corresponding word value. */
+ * 0000 to fffd (case-insensitive) into its corresponding word value. */
 int get_word_kbinput(int kbinput
 #ifndef NANO_SMALL
 	, bool reset
@@ -1303,7 +1303,7 @@ int get_word_kbinput(int kbinput
 		word += (kbinput - '0');
 		retval = word;
 	    } else if ('a' <= tolower(kbinput) &&
-		tolower(kbinput) <= 'f') {
+		tolower(kbinput) <= 'd') {
 		word += (tolower(kbinput) + 10 - 'a');
 		retval = word;
 	    } else