diff -d -urpN busybox.2/include/unicode.h busybox.3/include/unicode.h
--- busybox.2/include/unicode.h	2010-05-06 19:36:24.000000000 +0200
+++ busybox.3/include/unicode.h	2010-05-11 13:18:06.143703556 +0200
@@ -92,6 +92,7 @@ size_t wcrtomb(char *s, wchar_t wc, mbst
 int iswspace(wint_t wc) FAST_FUNC;
 int iswalnum(wint_t wc) FAST_FUNC;
 int iswpunct(wint_t wc) FAST_FUNC;
+int wcwidth(unsigned ucs) FAST_FUNC;
 #  if ENABLE_UNICODE_BIDI_SUPPORT
 #   undef unicode_bidi_isrtl
 int unicode_bidi_isrtl(wint_t wc) FAST_FUNC;
diff -d -urpN busybox.2/libbb/lineedit.c busybox.3/libbb/lineedit.c
--- busybox.2/libbb/lineedit.c	2010-05-11 14:40:39.738704839 +0200
+++ busybox.3/libbb/lineedit.c	2010-05-11 14:41:02.025703295 +0200
@@ -269,14 +269,28 @@ static void BB_PUTCHAR(wchar_t c)
 	mbstate_t mbst = { 0 };
 	ssize_t len;
 
-	if (unicode_is_inv_wchar(c))
-		c = CONFIG_SUBST_WCHAR;
 	len = wcrtomb(buf, c, &mbst);
 	if (len > 0) {
 		buf[len] = '\0';
 		fputs(buf, stdout);
 	}
 }
+static wchar_t validate_wc(wchar_t wc)
+{
+	int w;
+
+	if (unicode_status == UNICODE_ON &&
+	    (unicode_is_inv_wchar(wc)
+	     || (CONFIG_LAST_SUPPORTED_WCHAR && wc > CONFIG_LAST_SUPPORTED_WCHAR)))
+		wc = CONFIG_SUBST_WCHAR;
+	w = wcwidth(wc);
+	if ((ENABLE_UNICODE_COMBINING_WCHARS && w < 0)
+	    || (!ENABLE_UNICODE_COMBINING_WCHARS && w <= 0)
+	    || (!ENABLE_UNICODE_WIDE_WCHARS && w > 1))
+		wc = CONFIG_SUBST_WCHAR;
+
+	return wc;
+}
 #else
 static size_t load_string(const char *src, int maxsize)
 {
@@ -309,7 +323,14 @@ static void put_cur_glyph_and_inc_cursor
 		cursor++;
 		cmdedit_x++;
 	}
-
+#if ENABLE_UNICODE_SUPPORT
+	c = validate_wc(c);
+#endif
+#if ENABLE_UNICODE_COMBINING_WCHARS || ENABLE_UNICODE_WIDE_WCHARS
+	cmdedit_x += wcwidth(c);
+#else
+	cmdedit_x++;
+#endif
 #if ENABLE_FEATURE_NONPRINTABLE_INVERSE_PUT
 	/* Display non-printable characters in reverse */
 	if (!BB_isprint(c)) {
@@ -392,7 +413,17 @@ static void input_backward(unsigned num)
 	if (!num)
 		return;
 	cursor -= num;
+#if ENABLE_UNICODE_COMBINING_WCHARS || ENABLE_UNICODE_WIDE_WCHARS
+	{
+		int n = num;
 
+		num = 0;
+		while (n--)
+			num += wcwidth(validate_wc(command_ps[cursor + n]));
+		if (!num)
+			return;
+	}
+#endif
 	if (cmdedit_x >= num) {
 		cmdedit_x -= num;
 		if (num <= 4) {
diff -d -urpN busybox.2/libbb/unicode.c busybox.3/libbb/unicode.c
--- busybox.2/libbb/unicode.c	2010-05-11 13:55:52.228712961 +0200
+++ busybox.3/libbb/unicode.c	2010-05-11 13:18:06.150704518 +0200
@@ -418,7 +418,7 @@ static int in_uint16_table(unsigned ucs,
  * This implementation assumes that wchar_t characters are encoded
  * in ISO 10646.
  */
-static int wcwidth(unsigned ucs)
+int FAST_FUNC wcwidth(unsigned ucs)
 {
 # if LAST_SUPPORTED_WCHAR >= 0x300
 	/* sorted list of non-overlapping intervals of non-spacing characters */
