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