[PATCH] Cygwin: pty: Skip multibyte char boundary check conditionally.
Takashi Yano
takashi.yano@nifty.ne.jp
Fri Sep 11 18:34:41 GMT 2020
- For charset in which MB_ERR_INVALID_CHARS does not work properly,
skip multibyte char boundary check in convert_mb_str().
---
winsup/cygwin/fhandler_tty.cc | 83 ++++++++++++++++++++---------------
1 file changed, 47 insertions(+), 36 deletions(-)
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 8910af1e7..dd514049f 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -122,46 +122,57 @@ convert_mb_str (UINT cp_to, char *ptr_to, size_t *len_to,
UINT cp_from, const char *ptr_from, size_t len_from,
mbstate_t *mbp)
{
+ bool check_boundary = false;
+ if (MultiByteToWideChar (cp_from, MB_ERR_INVALID_CHARS, "A", 1, NULL, 0))
+ check_boundary = true;
tmp_pathbuf tp;
wchar_t *wbuf = tp.w_get ();
int wlen = 0;
- char *tmpbuf = tp.c_get ();
- memcpy (tmpbuf, mbp->__value.__wchb, mbp->__count);
- if (mbp->__count + len_from > NT_MAX_PATH)
- len_from = NT_MAX_PATH - mbp->__count;
- memcpy (tmpbuf + mbp->__count, ptr_from, len_from);
- int total_len = mbp->__count + len_from;
- mbp->__count = 0;
- int mblen = 0;
- for (const char *p = tmpbuf; p < tmpbuf + total_len; p += mblen)
- /* Max bytes in multibyte char supported is 4. */
- for (mblen = 1; mblen <= 4; mblen ++)
- {
- /* Try conversion */
- int l = MultiByteToWideChar (cp_from, MB_ERR_INVALID_CHARS,
- p, mblen,
- wbuf + wlen, NT_MAX_PATH - wlen);
- if (l)
- { /* Conversion Success */
- wlen += l;
- break;
- }
- else if (mblen == 4)
- { /* Conversion Fail */
- l = MultiByteToWideChar (cp_from, 0, p, 1,
- wbuf + wlen, NT_MAX_PATH - wlen);
- wlen += l;
- mblen = 1;
- break;
- }
- else if (p + mblen == tmpbuf + total_len)
- { /* Multibyte char incomplete */
- memcpy (mbp->__value.__wchb, p, mblen);
- mbp->__count = mblen;
- break;
+ if (!check_boundary)
+ /* If MB_ERR_INVALID_CHARS does not work properly,
+ just convert string without checking */
+ wlen = MultiByteToWideChar (cp_from, 0, ptr_from, len_from,
+ wbuf, NT_MAX_PATH);
+ else
+ {
+ char *tmpbuf = tp.c_get ();
+ memcpy (tmpbuf, mbp->__value.__wchb, mbp->__count);
+ if (mbp->__count + len_from > NT_MAX_PATH)
+ len_from = NT_MAX_PATH - mbp->__count;
+ memcpy (tmpbuf + mbp->__count, ptr_from, len_from);
+ int total_len = mbp->__count + len_from;
+ mbp->__count = 0;
+ int mblen = 0;
+ for (const char *p = tmpbuf; p < tmpbuf + total_len; p += mblen)
+ /* Max bytes in multibyte char supported is 4. */
+ for (mblen = 1; mblen <= 4; mblen ++)
+ {
+ /* Try conversion */
+ int l = MultiByteToWideChar (cp_from, MB_ERR_INVALID_CHARS,
+ p, mblen,
+ wbuf + wlen, NT_MAX_PATH - wlen);
+ if (l)
+ { /* Conversion Success */
+ wlen += l;
+ break;
+ }
+ else if (mblen == 4)
+ { /* Conversion Fail */
+ l = MultiByteToWideChar (cp_from, 0, p, 1,
+ wbuf + wlen, NT_MAX_PATH - wlen);
+ wlen += l;
+ mblen = 1;
+ break;
+ }
+ else if (p + mblen == tmpbuf + total_len)
+ { /* Multibyte char incomplete */
+ memcpy (mbp->__value.__wchb, p, mblen);
+ mbp->__count = mblen;
+ break;
+ }
+ /* Retry conversion with extended length */
}
- /* Retry conversion with extended length */
- }
+ }
*len_to = WideCharToMultiByte (cp_to, 0, wbuf, wlen,
ptr_to, *len_to, NULL, NULL);
}
--
2.28.0
More information about the Cygwin-patches
mailing list