msvcrt: Add _wmakepath_s implementation.

Robert Wilhelm robert.wilhelm at gmx.net
Mon Jun 14 17:16:20 CDT 2010


---
 dlls/msvcr90/msvcr90.spec |    2 +-
 dlls/msvcrt/dir.c         |   69 +++++++++++++++++++++++++++++++++++++++++++++
 dlls/msvcrt/msvcrt.spec   |    2 +-
 dlls/msvcrt/tests/dir.c   |   26 +++++++++++++++++
 include/msvcrt/stdlib.h   |    1 +
 include/msvcrt/wchar.h    |    1 +
 6 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index a2bed36..6e380e8 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -1144,7 +1144,7 @@
 @ cdecl _wgetenv(wstr) msvcrt._wgetenv
 @ stub _wgetenv_s
 @ cdecl _wmakepath(wstr wstr wstr wstr wstr) msvcrt._wmakepath
-@ stub _wmakepath_s
+@ cdecl _wmakepath_s(wstr long wstr wstr wstr wstr) msvcrt._wmakepath_s
 @ cdecl _wmkdir(wstr) msvcrt._wmkdir
 @ cdecl _wmktemp(wstr) msvcrt._wmktemp
 @ stub _wmktemp_s
diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c
index a9f9234..5c3aece 100644
--- a/dlls/msvcrt/dir.c
+++ b/dlls/msvcrt/dir.c
@@ -1078,6 +1078,75 @@ VOID CDECL _wmakepath(MSVCRT_wchar_t *path, const MSVCRT_wchar_t *drive, const M
 }
 
 /*********************************************************************
+ *		_wmakepath_s (MSVCRT.@)
+ *
+ * Security enhanced version of _wmakepath.
+ */
+int CDECL _wmakepath_s(MSVCRT_wchar_t *path, MSVCRT_size_t size, const MSVCRT_wchar_t *drive, const MSVCRT_wchar_t *directory,
+                      const MSVCRT_wchar_t *filename, const MSVCRT_wchar_t *extension)
+{
+    MSVCRT_wchar_t *p = path;
+    MSVCRT_size_t count = 0;
+
+    TRACE("%s %s %s %s\n", debugstr_w(drive), debugstr_w(directory),
+          debugstr_w(filename), debugstr_w(extension));
+
+    if ( !path )
+        return MSVCRT_EINVAL;
+
+    if ( !size )
+        return MSVCRT_EINVAL;
+
+    if (drive && drive[0])
+    {
+        count +=2;
+        if (count > size) return MSVCRT_EINVAL;
+        *p++ = drive[0];
+        *p++ = ':';
+    }
+    if (directory && directory[0])
+    {
+        unsigned int len = strlenW(directory);
+        count += len * sizeof(MSVCRT_wchar_t);
+        if (count > size) return MSVCRT_EINVAL;
+        memmove(p, directory, len * sizeof(MSVCRT_wchar_t));
+        p += len;
+        if (p[-1] != '/' && p[-1] != '\\')
+        {
+            count += 1;
+            if (count > size) return MSVCRT_EINVAL;
+            *p++ = '\\';
+        }
+    }
+    if (filename && filename[0])
+    {
+        unsigned int len = strlenW(filename);
+        count += len * sizeof(MSVCRT_wchar_t);
+        if (count > size) return MSVCRT_EINVAL;
+        memmove(p, filename, len * sizeof(MSVCRT_wchar_t));
+        p += len;
+    }
+    if (extension && extension[0])
+    {
+        unsigned int len = strlenW(extension);
+        if (extension[0] != '.')
+        {
+            count += 1;
+            if (count > size) return MSVCRT_EINVAL;
+            *p++ = '.';
+        }
+        count += len * sizeof(MSVCRT_wchar_t);
+        if (count > size) return MSVCRT_EINVAL;
+        strcpyW(p, extension);
+    }
+    else
+        *p = '\0';
+
+    TRACE("returning %s\n", debugstr_w(path));
+    return 0;
+}
+
+/*********************************************************************
  *		_searchenv (MSVCRT.@)
  *
  * Search for a file in a list of paths from an environment variable.
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index bba06d6..616acb5 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -1090,7 +1090,7 @@
 # stub _winput_s
 @ extern _winver MSVCRT__winver
 @ cdecl _wmakepath(wstr wstr wstr wstr wstr)
-# stub _wmakepath_s
+@ cdecl _wmakepath_s(wstr long wstr wstr wstr wstr)
 @ cdecl _wmkdir(wstr)
 @ cdecl _wmktemp(wstr)
 # stub _wmktemp_s
diff --git a/dlls/msvcrt/tests/dir.c b/dlls/msvcrt/tests/dir.c
index 11a9820..6aeed66 100644
--- a/dlls/msvcrt/tests/dir.c
+++ b/dlls/msvcrt/tests/dir.c
@@ -77,6 +77,7 @@ static void test_makepath(void)
     WCHAR extW[MAX_PATH];
     WCHAR bufferW[MAX_PATH];
     char buffer[MAX_PATH];
+    int ret;
 
     unsigned int i, n;
 
@@ -118,7 +119,32 @@ static void test_makepath(void)
         bufferW[MAX_PATH - 1] = '\0';
         WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
         ok(!strcmp(p->expected, buffer), "got '%s' for unicode case %d\n", buffer, i);
+
+        memset(buffer, 0, MAX_PATH);
+        for (n = 0; n < MAX_PATH; ++n)
+            bufferW[n] = 'X';
+        if (p->buffer) MultiByteToWideChar( CP_ACP, 0, p->buffer, -1, bufferW, MAX_PATH);
+
+        ret = _wmakepath_s(bufferW, MAX_PATH, 
+                   p->drive == USE_BUFF ? bufferW : p->drive ? driveW : NULL,
+                   p->dir == USE_BUFF ? bufferW : p->dir ? dirW : NULL,
+                   p->file == USE_BUFF? bufferW : p->file ? fileW : NULL,
+                   p->ext == USE_BUFF ? bufferW : p->ext ? extW : NULL);
+
+        ok(!ret,"return value != 0\n");
+        bufferW[MAX_PATH - 1] = '\0';
+        WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
+        ok(!strcmp(p->expected, buffer), "got '%s' for unicode case %d\n", buffer, i);
+
+        ret = _wmakepath_s(bufferW, 0, 
+                   p->drive == USE_BUFF ? bufferW : p->drive ? driveW : NULL,
+                   p->dir == USE_BUFF ? bufferW : p->dir ? dirW : NULL,
+                   p->file == USE_BUFF? bufferW : p->file ? fileW : NULL,
+                   p->ext == USE_BUFF ? bufferW : p->ext ? extW : NULL);
+
+        ok(ret==EINVAL,"return value != EINVAL %d %d\n",ret,EINVAL);
     }
+   
 }
 
 static void test_fullpath(void)
diff --git a/include/msvcrt/stdlib.h b/include/msvcrt/stdlib.h
index 35a9782..9a5abce 100644
--- a/include/msvcrt/stdlib.h
+++ b/include/msvcrt/stdlib.h
@@ -202,6 +202,7 @@ wchar_t*      __cdecl _ultow(__msvcrt_ulong,wchar_t*,int);
 wchar_t*      __cdecl _wfullpath(wchar_t*,const wchar_t*,size_t);
 wchar_t*      __cdecl _wgetenv(const wchar_t*);
 void          __cdecl _wmakepath(wchar_t*,const wchar_t*,const wchar_t*,const wchar_t*,const wchar_t*);
+int           __cdecl _wmakepath_s(wchar_t*,size_t,const wchar_t*,const wchar_t*,const wchar_t*,const wchar_t*);
 void          __cdecl _wperror(const wchar_t*);
 int           __cdecl _wputenv(const wchar_t*);
 void          __cdecl _wsearchenv(const wchar_t*,const wchar_t*,wchar_t*);
diff --git a/include/msvcrt/wchar.h b/include/msvcrt/wchar.h
index 66d3a81..ff3882a 100644
--- a/include/msvcrt/wchar.h
+++ b/include/msvcrt/wchar.h
@@ -320,6 +320,7 @@ wchar_t* __cdecl _ultow(__msvcrt_ulong,wchar_t*,int);
 wchar_t* __cdecl _wfullpath(wchar_t*,const wchar_t*,size_t);
 wchar_t* __cdecl _wgetenv(const wchar_t*);
 void     __cdecl _wmakepath(wchar_t*,const wchar_t*,const wchar_t*,const wchar_t*,const wchar_t*);
+int      __cdecl _wmakepath_s(wchar_t*,size_t,const wchar_t*,const wchar_t*,const wchar_t*,const wchar_t*);
 void     __cdecl _wperror(const wchar_t*);
 int      __cdecl _wputenv(const wchar_t*);
 void     __cdecl _wsearchenv(const wchar_t*,const wchar_t*,wchar_t*);
-- 
1.6.6.1


--=-C/YEy3YKGrKakvxlk7b7--




More information about the wine-patches mailing list