# HG changeset patch # User Bram Moolenaar # Date 1360770598 -3600 # Node ID d5b1d6177b374bbecfbd5c75fbce28e148eeecea # Parent 9d93d458e536b7dff0187795833669667d9b25df updated for version 7.3.814 Problem: Can't input multibyte characters on Win32 console if 'encoding' is different from current codepage. Solution: Use convert_input_safe() instead of convert_input(). Make string_convert_ext() return an error for incomplete input. (Ken Takata) diff --git a/src/mbyte.c b/src/mbyte.c --- a/src/mbyte.c +++ b/src/mbyte.c @@ -6256,8 +6256,23 @@ string_convert_ext(vcp, ptr, lenp, uncon if (vcp->vc_cpfrom == 0) tmp_len = utf8_to_utf16(ptr, len, NULL, NULL); else - tmp_len = MultiByteToWideChar(vcp->vc_cpfrom, 0, - ptr, len, 0, 0); + { + tmp_len = MultiByteToWideChar(vcp->vc_cpfrom, + unconvlenp ? MB_ERR_INVALID_CHARS : 0, + ptr, len, 0, 0); + if (tmp_len == 0 + && GetLastError() == ERROR_NO_UNICODE_TRANSLATION) + { + if (lenp != NULL) + *lenp = 0; + if (unconvlenp != NULL) + *unconvlenp = len; + retval = alloc(1); + if (retval) + retval[0] = NUL; + return retval; + } + } tmp = (short_u *)alloc(sizeof(short_u) * tmp_len); if (tmp == NULL) break; diff --git a/src/os_win32.c b/src/os_win32.c --- a/src/os_win32.c +++ b/src/os_win32.c @@ -1466,6 +1466,11 @@ mch_inchar( #define TYPEAHEADLEN 20 static char_u typeahead[TYPEAHEADLEN]; /* previously typed bytes. */ static int typeaheadlen = 0; +#ifdef FEAT_MBYTE + static char_u *rest = NULL; /* unconverted rest of previous read */ + static int restlen = 0; + int unconverted; +#endif /* First use any typeahead that was kept because "buf" was too small. */ if (typeaheadlen > 0) @@ -1569,6 +1574,33 @@ mch_inchar( c = tgetch(&modifiers, &ch2); +#ifdef FEAT_MBYTE + /* stolen from fill_input_buf() in ui.c */ + if (rest != NULL) + { + /* Use remainder of previous call, starts with an invalid + * character that may become valid when reading more. */ + if (restlen > TYPEAHEADLEN - typeaheadlen) + unconverted = TYPEAHEADLEN - typeaheadlen; + else + unconverted = restlen; + mch_memmove(typeahead + typeaheadlen, rest, unconverted); + if (unconverted == restlen) + { + vim_free(rest); + rest = NULL; + } + else + { + restlen -= unconverted; + mch_memmove(rest, rest + unconverted, restlen); + } + typeaheadlen += unconverted; + } + else + unconverted = 0; +#endif + if (typebuf_changed(tb_change_cnt)) { /* "buf" may be invalid now if a client put something in the @@ -1604,8 +1636,12 @@ mch_inchar( * when 'tenc' is set. */ if (input_conv.vc_type != CONV_NONE && (ch2 == NUL || c != K_NUL)) - n = convert_input(typeahead + typeaheadlen, n, - TYPEAHEADLEN - typeaheadlen); + { + typeaheadlen -= unconverted; + n = convert_input_safe(typeahead + typeaheadlen, + n + unconverted, TYPEAHEADLEN - typeaheadlen, + rest == NULL ? &rest : NULL, &restlen); + } #endif /* Use the ALT key to set the 8th bit of the character diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -726,6 +726,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 814, +/**/ 813, /**/ 812,