Hello!

In cvs head.

A 'readdir' function cannot listing filename that using multi-byte
charctor. (corrupt filename)

Because, newlib's wcstombs do not support 'true' multi-byte charactor 
conversion.

I made a patch for cvs head.

That using W32API's WideCharToMultiByte instead of newlib's wcstombs.

Index: winsup/cygwin/fhandler_disk_file.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_disk_file.cc,v
retrieving revision 1.168
diff -u -r1.168 fhandler_disk_file.cc
--- winsup/cygwin/fhandler_disk_file.cc 5 Feb 2006 18:18:02 -0000       1.168
+++ winsup/cygwin/fhandler_disk_file.cc 7 Feb 2006 13:33:20 -0000
@@ -1608,7 +1608,8 @@
   NTSTATUS status = STATUS_SUCCESS;
   PFILE_ID_BOTH_DIR_INFORMATION buf = NULL;
   wchar_t *FileName;
-  char fname[CYG_MAX_PATH];
+  int      FileNameLength, mblen ;
+  char fname[CYG_MAX_PATH+1];
   IO_STATUS_BLOCK io;
 
   if (!wincap.is_winnt ())
@@ -1650,26 +1651,30 @@
       if ((dir->__flags & dirent_get_d_ino))
        {
          FileName = buf->FileName;
+          FileNameLength = buf->FileNameLength ;
          if ((dir->__flags & dirent_set_d_ino))
            de->d_ino = buf->FileId.QuadPart;
         }
-      else
+      else {
         FileName = ((PFILE_BOTH_DIR_INFORMATION) buf)->FileName;
+        FileNameLength = ((PFILE_BOTH_DIR_INFORMATION) buf)->FileNameLength ;
+      }
+      
 
       if (de->d_ino == 0 && (dir->__flags & dirent_set_d_ino))
        {
          OBJECT_ATTRIBUTES attr;
 
-         if (dir->__d_position == 0 && buf->FileNameLength == 2
+         if (dir->__d_position == 0 && FileNameLength == 2
              && FileName[0] == '.')
            de->d_ino = readdir_get_ino_by_handle (dir->__handle);
-         else if (dir->__d_position == 1 && buf->FileNameLength == 4
+         else if (dir->__d_position == 1 && FileNameLength == 4
                   && FileName[0] == '.' && FileName[1] == '.')
            de->d_ino = readdir_get_ino (dir, pc.normalized_path, true);
          else
            {
              HANDLE hdl;
-             UNICODE_STRING upath = {buf->FileNameLength, CYG_MAX_PATH * 2,
+             UNICODE_STRING upath = {FileNameLength, CYG_MAX_PATH * 2,
                                      FileName};
              InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE,
                                          dir->__handle , NULL);
@@ -1681,8 +1686,16 @@
                }
            }
        }
-      wcstombs (fname, FileName, buf->FileNameLength / 2);
-      fname[buf->FileNameLength / 2] = '\0';
+      mblen = sys_wcstombs2 (fname, CYG_MAX_PATH,
+                             FileName, FileNameLength/(sizeof(WCHAR)));
+      if ( mblen >= CYG_MAX_PATH ) {
+        debug_printf ("path max over FileNameLength = %d, mblen = %d", 
FileNameLength, mblen) ;
+        mblen = CYG_MAX_PATH ;
+      }
+      if ( fname[mblen-1] != '\0' ) {
+        debug_printf ("add null terminator FileNameLength = %d, mblen = %d", 
FileNameLength, mblen) ;
+        fname[mblen] = '\0' ;
+      }
     }
 
   if (!(res = readdir_helper (dir, de, RtlNtStatusToDosError (status),
Index: winsup/cygwin/miscfuncs.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/miscfuncs.cc,v
retrieving revision 1.39
diff -u -r1.39 miscfuncs.cc
--- winsup/cygwin/miscfuncs.cc  20 Dec 2005 20:34:28 -0000      1.39
+++ winsup/cygwin/miscfuncs.cc  7 Feb 2006 13:33:20 -0000
@@ -217,6 +217,12 @@
 }
 
 int __stdcall
+sys_wcstombs2 (char *tgt, int tgtlen, const WCHAR *src, int srclen)
+{
+  return WideCharToMultiByte (get_cp (), 0, src, srclen, tgt, tgtlen, NULL, 
NULL);
+}
+
+int __stdcall
 sys_mbstowcs (WCHAR *tgt, const char *src, int len)
 {
   int res = MultiByteToWideChar (get_cp (), 0, src, -1, tgt, len);
Index: winsup/cygwin/winsup.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/winsup.h,v
retrieving revision 1.182
diff -u -r1.182 winsup.h
--- winsup/cygwin/winsup.h      5 Feb 2006 18:18:02 -0000       1.182
+++ winsup/cygwin/winsup.h      7 Feb 2006 13:33:20 -0000
@@ -122,6 +122,9 @@
 int __stdcall sys_wcstombs(char *, const WCHAR *, int)
   __attribute__ ((regparm(3)));
 
+int __stdcall sys_wcstombs2(char *, int, const WCHAR *, int)
+  __attribute__ ((regparm(4)));
+
 int __stdcall sys_mbstowcs(WCHAR *, const char *, int)
   __attribute__ ((regparm(3)));
 

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Reply via email to