From 6a7f187ce60c2d359b7e276787a01c290d7828e0 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Thu, 10 Dec 2020 09:58:43 +0900 Subject: Patch-ID: readline52-014 Bug-Reported-by: Len Lattanzi Bug-Reference-ID: <52B1297F-6675-45CC-B63E-24745337D006@apple.com> Bug-Reference-URL: Bug-Description: On systems where mbrtowc() returns -2 when passed a length argument with value 0, when using a multibyte locale, Readline's emacs-mode forward-char at the end of a line will leave the point beyond the end of the line. Change-Id: I73b50c94b0a0012803fb07f0f35bdc9c2ebaa7dd Signed-off-by: DongHun Kwak --- mbutil.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/mbutil.c b/mbutil.c index 17dde53..5f40e84 100644 --- a/mbutil.c +++ b/mbutil.c @@ -77,7 +77,7 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) char *string; int seed, count, find_non_zero; { - size_t tmp; + size_t tmp, len; mbstate_t ps; int point; wchar_t wc; @@ -96,9 +96,12 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) if (seed < point) count--; - while (count > 0) + while (count > 0) { - tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps); + len = strlen (string + point); + if (len == 0) + break; + tmp = mbrtowc (&wc, string+point, len, &ps); if (MB_INVALIDCH ((size_t)tmp)) { /* invalid bytes. asume a byte represents a character */ @@ -152,7 +155,7 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) memset(&ps, 0, sizeof(mbstate_t)); length = strlen(string); - + if (seed < 0) return 0; else if (length < seed) @@ -186,7 +189,7 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) prev = point; } else - prev = point; + prev = point; } point += tmp; @@ -196,9 +199,9 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) } /* return the number of bytes parsed from the multibyte sequence starting - at src, if a non-L'\0' wide character was recognized. It returns 0, - if a L'\0' wide character was recognized. It returns (size_t)(-1), - if an invalid multibyte sequence was encountered. It returns (size_t)(-2) + at src, if a non-L'\0' wide character was recognized. It returns 0, + if a L'\0' wide character was recognized. It returns (size_t)(-1), + if an invalid multibyte sequence was encountered. It returns (size_t)(-2) if it couldn't parse a complete multibyte character. */ int _rl_get_char_len (src, ps) @@ -242,7 +245,7 @@ _rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2) { int i, w1, w2; - if ((w1 = _rl_get_char_len (&buf1[pos1], ps1)) <= 0 || + if ((w1 = _rl_get_char_len (&buf1[pos1], ps1)) <= 0 || (w2 = _rl_get_char_len (&buf2[pos2], ps2)) <= 0 || (w1 != w2) || (buf1[pos1] != buf2[pos2])) @@ -275,7 +278,7 @@ _rl_adjust_point(string, point, ps) return -1; if (length < point) return -1; - + while (pos < point) { tmp = mbrlen (string + pos, length - pos, ps); @@ -334,7 +337,7 @@ _rl_char_value (buf, ind) return ((wchar_t) buf[ind]); memset (&ps, 0, sizeof (mbstate_t)); tmp = mbrtowc (&wc, buf + ind, l - ind, &ps); - if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp)) + if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp)) return ((wchar_t) buf[ind]); return wc; } -- cgit v1.2.3