Jacek Caban : ntdll: Implement _snprintf_s and _vsnprintf_s.

Alexandre Julliard julliard at winehq.org
Wed Jul 3 17:11:54 CDT 2019


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Jul  3 21:06:21 2019 +0200

ntdll: Implement _snprintf_s and _vsnprintf_s.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/ntdll.spec     |  2 ++
 dlls/ntdll/printf.c       | 45 ++++++++++++++++++++++++++++++++++++++++
 dlls/ntdll/tests/string.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 100 insertions(+)

diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 94bc52c..299bfac 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1406,6 +1406,7 @@
 @ cdecl _memccpy(ptr ptr long long)
 @ cdecl _memicmp(str str long)
 @ varargs _snprintf(ptr long str) NTDLL__snprintf
+@ varargs _snprintf_s(ptr long long str) _snprintf_s
 @ varargs _snwprintf(ptr long wstr) NTDLL__snwprintf
 @ cdecl _splitpath(str ptr ptr ptr ptr)
 @ cdecl _strcmpi(str str) _stricmp
@@ -1420,6 +1421,7 @@
 @ cdecl _ultoa(long ptr long)
 @ cdecl _ultow(long ptr long)
 @ cdecl -norelay _vsnprintf(ptr long str ptr) NTDLL__vsnprintf
+@ cdecl _vsnprintf_s(ptr long str ptr) _vsnprintf_s
 @ cdecl _vsnwprintf(ptr long wstr ptr) NTDLL__vsnwprintf
 @ cdecl _wcsicmp(wstr wstr) NTDLL__wcsicmp
 @ cdecl _wcslwr(wstr) NTDLL__wcslwr
diff --git a/dlls/ntdll/printf.c b/dlls/ntdll/printf.c
index 6b7293b..018f774 100644
--- a/dlls/ntdll/printf.c
+++ b/dlls/ntdll/printf.c
@@ -765,6 +765,51 @@ int WINAPIV NTDLL__snwprintf( WCHAR *str, SIZE_T len, const WCHAR *format, ... )
 
 
 /*********************************************************************
+ *                  _vsnprintf_s   (NTDLL.@)
+ */
+int CDECL _vsnprintf_s( char *str, SIZE_T size, SIZE_T len, const char *format, __ms_va_list args )
+{
+    DWORD sz;
+    LPWSTR formatW = NULL;
+    pf_output out;
+    int r;
+
+    out.unicode = FALSE;
+    out.buf.A = str;
+    out.used = 0;
+    out.len = min( size, len );
+
+    if (format)
+    {
+        RtlMultiByteToUnicodeSize( &sz, format, strlen(format) + 1 );
+        if (!(formatW = RtlAllocateHeap( GetProcessHeap(), 0, sz ))) return -1;
+        RtlMultiByteToUnicodeN( formatW, sz, NULL, format, strlen(format) + 1 );
+    }
+    r = pf_vsnprintf( &out, formatW, args );
+    RtlFreeHeap( GetProcessHeap(), 0, formatW );
+    if (out.used < size) str[out.used] = 0;
+    else str[0] = 0;
+    if (r == size) r = -1;
+    return r;
+}
+
+
+/*********************************************************************
+ *                  _snprintf_s   (NTDLL.@)
+ */
+int WINAPIV _snprintf_s( char *str, SIZE_T size, SIZE_T len, const char *format, ... )
+{
+    int ret;
+    __ms_va_list valist;
+
+    __ms_va_start( valist, format );
+    ret = _vsnprintf_s( str, size, len, format, valist );
+    __ms_va_end( valist );
+    return ret;
+}
+
+
+/*********************************************************************
  *                  vsprintf   (NTDLL.@)
  */
 int CDECL NTDLL_vsprintf( char *str, const char *format, __ms_va_list args )
diff --git a/dlls/ntdll/tests/string.c b/dlls/ntdll/tests/string.c
index 7954508..5a2d845 100644
--- a/dlls/ntdll/tests/string.c
+++ b/dlls/ntdll/tests/string.c
@@ -61,6 +61,7 @@ static LPWSTR   (WINAPIV *p_wcsrchr)(LPCWSTR, WCHAR);
 static void     (__cdecl *p_qsort)(void *,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
 static void*    (__cdecl *p_bsearch)(void *,void*,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
 static int      (WINAPIV *p__snprintf)(char *, size_t, const char *, ...);
+static int      (WINAPIV *p__snprintf_s)(char *, size_t, size_t, const char *, ...);
 
 static int      (__cdecl *p_tolower)(int);
 static int      (__cdecl *p_toupper)(int);
@@ -103,6 +104,7 @@ static void InitFunctionPtrs(void)
 	p_bsearch= (void *)GetProcAddress(hntdll, "bsearch");
 
         p__snprintf = (void *)GetProcAddress(hntdll, "_snprintf");
+        p__snprintf_s = (void *)GetProcAddress(hntdll, "_snprintf_s");
 
         p_tolower = (void *)GetProcAddress(hntdll, "tolower");
         p_toupper = (void *)GetProcAddress(hntdll, "toupper");
@@ -1333,6 +1335,53 @@ static void test__snprintf(void)
     res = p__snprintf(buffer, strlen(teststring) + 1, teststring);
     ok(res == lstrlenA(teststring), "_snprintf returned %d, expected %d.\n", res, lstrlenA(teststring));
     ok(!strcmp(buffer, teststring), "_snprintf returned buffer '%s', expected '%s'.\n", buffer, teststring);
+
+    memset(buffer, 0x7c, sizeof(buffer));
+    res = p__snprintf(buffer, 4, "test");
+    ok(res == 4, "res = %d\n", res);
+    ok(!memcmp(buffer, "test", 4), "buf = %s\n", buffer);
+    ok(buffer[4] == 0x7c, "buffer[4] = %x\n", buffer[4]);
+
+    memset(buffer, 0x7c, sizeof(buffer));
+    res = p__snprintf(buffer, 3, "test");
+    ok(res == -1, "res = %d\n", res);
+ }
+
+static void test__snprintf_s(void)
+{
+    char buf[32];
+    int res;
+
+    memset(buf, 0xcc, sizeof(buf));
+    res = p__snprintf_s(buf, sizeof(buf), sizeof(buf), "test");
+    ok(res == 4, "res = %d\n", res);
+    ok(!strcmp(buf, "test"), "buf = %s\n", buf);
+
+    memset(buf, 0xcc, sizeof(buf));
+    res = p__snprintf_s(buf, 4, 4, "test");
+    ok(res == -1, "res = %d\n", res);
+    ok(!buf[0], "buf = %s\n", buf);
+
+    memset(buf, 0xcc, sizeof(buf));
+    res = p__snprintf_s(buf, 5, 4, "test");
+    ok(res == 4, "res = %d\n", res);
+    ok(!strcmp(buf, "test"), "buf = %s\n", buf);
+
+    memset(buf, 0xcc, sizeof(buf));
+    res = p__snprintf_s(buf, 5, 3, "test");
+    ok(res == -1, "res = %d\n", res);
+    ok(!strcmp(buf, "tes"), "buf = %s\n", buf);
+
+    memset(buf, 0xcc, sizeof(buf));
+    res = p__snprintf_s(buf, 4, 10, "test");
+    ok(res == -1, "res = %d\n", res);
+    ok(!buf[0], "buf = %s\n", buf);
+
+    memset(buf, 0xcc, sizeof(buf));
+    res = p__snprintf_s(buf, 6, 5, "test%c", 0);
+    ok(res == 5, "res = %d\n", res);
+    ok(!memcmp(buf, "test\0", 6), "buf = %s\n", buf);
+
 }
 
 static void test_tolower(void)
@@ -1442,6 +1491,10 @@ START_TEST(string)
         test_bsearch();
     if (p__snprintf)
         test__snprintf();
+    if (p__snprintf_s)
+        test__snprintf_s();
+    else
+        win_skip("_snprintf_s not available\n");
     test_tolower();
     test_toupper();
     test__strnicmp();




More information about the wine-cvs mailing list