- 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

Reply via email to