Piotr Caban : ucrtbase: Don't fail if path ends with '\' character in stat functions family.

Alexandre Julliard julliard at winehq.org
Fri Jul 13 15:01:47 CDT 2018


Module: wine
Branch: master
Commit: c5cb5e24a30d98aa329e87c3c9e709b16cf43233
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c5cb5e24a30d98aa329e87c3c9e709b16cf43233

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Fri Jul 13 16:49:34 2018 +0200

ucrtbase: Don't fail if path ends with '\' character in stat functions family.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45292
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/file.c         | 22 ++++++++++++++++++----
 dlls/ucrtbase/tests/misc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index 6b295cf..1c7b5a4 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -2980,13 +2980,20 @@ int CDECL MSVCRT_stat64(const char* path, struct MSVCRT__stat64 * buf)
   while (plen && path[plen-1]==' ')
     plen--;
 
-  if (plen && (plen<2 || path[plen-2]!=':') &&
-          (path[plen-1]==':' || path[plen-1]=='\\' || path[plen-1]=='/'))
+  if (plen==2 && path[1]==':')
   {
     *MSVCRT__errno() = MSVCRT_ENOENT;
     return -1;
   }
 
+#if _MSVCR_VER<140
+  if (plen>=2 && path[plen-2]!=':' && (path[plen-1]=='\\' || path[plen-1]=='/'))
+  {
+    *MSVCRT__errno() = MSVCRT_ENOENT;
+    return -1;
+  }
+#endif
+
   if (!GetFileAttributesExA(path, GetFileExInfoStandard, &hfi))
   {
       TRACE("failed (%d)\n",GetLastError());
@@ -3128,13 +3135,20 @@ int CDECL MSVCRT__wstat64(const MSVCRT_wchar_t* path, struct MSVCRT__stat64 * bu
   while (plen && path[plen-1]==' ')
     plen--;
 
-  if(plen && (plen<2 || path[plen-2]!=':') &&
-          (path[plen-1]==':' || path[plen-1]=='\\' || path[plen-1]=='/'))
+  if (plen==2 && path[1]==':')
   {
     *MSVCRT__errno() = MSVCRT_ENOENT;
     return -1;
   }
 
+#if _MSVCR_VER<140
+  if (plen>=2 && path[plen-2]!=':' && (path[plen-1]=='\\' || path[plen-1]=='/'))
+  {
+    *MSVCRT__errno() = MSVCRT_ENOENT;
+    return -1;
+  }
+#endif
+
   if (!GetFileAttributesExW(path, GetFileExInfoStandard, &hfi))
   {
       TRACE("failed (%d)\n",GetLastError());
diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c
index 555dc2d..2a9648a 100644
--- a/dlls/ucrtbase/tests/misc.c
+++ b/dlls/ucrtbase/tests/misc.c
@@ -27,6 +27,7 @@
 #include <share.h>
 #include <fcntl.h>
 #include <time.h>
+#include <direct.h>
 
 #include <windef.h>
 #include <winbase.h>
@@ -129,6 +130,7 @@ static void (CDECL *p_exit)(int);
 static int (CDECL *p__crt_atexit)(void (CDECL*)(void));
 static int (__cdecl *p_crt_at_quick_exit)(void (__cdecl *func)(void));
 static void (__cdecl *p_quick_exit)(int exitcode);
+static int (__cdecl *p__stat32)(const char*, struct _stat32 *buf);
 
 static void test__initialize_onexit_table(void)
 {
@@ -437,6 +439,7 @@ static BOOL init(void)
     p_exit = (void*)GetProcAddress(module, "exit");
     p_crt_at_quick_exit = (void*)GetProcAddress(module, "_crt_at_quick_exit");
     p_quick_exit = (void*)GetProcAddress(module, "quick_exit");
+    p__stat32 = (void*)GetProcAddress(module, "_stat32");
 
     return TRUE;
 }
@@ -931,6 +934,48 @@ static void test_quick_exit(const char *argv0)
     CloseHandle(quick_exit_event);
 }
 
+static void test__stat32(void)
+{
+    static const char test_file[] = "\\stat_file.tst";
+    static const char test_dir[] = "\\stat_dir.tst";
+
+    char path[2*MAX_PATH];
+    struct _stat32 buf;
+    int fd, ret;
+    DWORD len;
+
+    len = GetTempPathA(MAX_PATH, path);
+    ok(len, "GetTempPathA failed\n");
+
+    ret = p__stat32("c:", &buf);
+    ok(ret == -1, "_stat32('c:') returned %d\n", ret);
+    ret = p__stat32("c:\\", &buf);
+    ok(!ret, "_stat32('c:\\') returned %d\n", ret);
+
+    memcpy(path+len, test_file, sizeof(test_file));
+    if((fd = open(path, O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE)) >= 0)
+    {
+        ret = p__stat32(path, &buf);
+        ok(!ret, "_stat32('%s') returned %d\n", path, ret);
+        strcat(path, "\\");
+        ret = p__stat32(path, &buf);
+        todo_wine ok(ret, "_stat32('%s') returned %d\n", path, ret);
+        close(fd);
+        remove(path);
+    }
+
+    memcpy(path+len, test_dir, sizeof(test_dir));
+    if(!mkdir(path))
+    {
+        ret = p__stat32(path, &buf);
+        ok(!ret, "_stat32('%s') returned %d\n", path, ret);
+        strcat(path, "\\");
+        ret = p__stat32(path, &buf);
+        ok(!ret, "_stat32('%s') returned %d\n", path, ret);
+        rmdir(path);
+    }
+}
+
 START_TEST(misc)
 {
     int arg_c;
@@ -964,4 +1009,5 @@ START_TEST(misc)
     test_asctime();
     test_exit(arg_v[0]);
     test_quick_exit(arg_v[0]);
+    test__stat32();
 }




More information about the wine-cvs mailing list