mirror of
https://github.com/reactos/reactos.git
synced 2026-06-01 08:50:24 +08:00
[CRT_APITEST] Add _mbsn(b)cat tests based on Wine 10.0 (#8460)
These tests examine msvcrt, crtdll, and our static CRT. - msvcrt/crtdll verified passing on Windows 2003, 7 and 10. References: -9250ecc5a6/dlls/msvcrt/tests/string.c (L2773)-7f1075986f/modules/rostests/winetests/msvcrt/string.c (L2789)CORE-19308
This commit is contained in:
committed by
GitHub
parent
7f1075986f
commit
a3147ab6d9
22
modules/rostests/apitests/crt/_mbsnbcat.c
Normal file
22
modules/rostests/apitests/crt/_mbsnbcat.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* PROJECT: ReactOS API tests
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Tests for _mbsnbcat
|
||||
* COPYRIGHT: Copyright 2025 Stanislav Motylkov <x86corez@gmail.com>
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
#include <mbstring.h>
|
||||
#define WIN32_NO_STATUS
|
||||
|
||||
typedef unsigned char *(__cdecl *PFN__mbsncat)(unsigned char*, const unsigned char*, size_t);
|
||||
|
||||
extern VOID mbsncat_PerformTests(_In_ LPSTR fname, _In_opt_ PFN__mbsncat func);
|
||||
|
||||
START_TEST(_mbsnbcat)
|
||||
{
|
||||
#ifndef TEST_STATIC_CRT
|
||||
#define _mbsnbcat NULL
|
||||
#endif
|
||||
mbsncat_PerformTests("_mbsnbcat", _mbsnbcat);
|
||||
}
|
||||
156
modules/rostests/apitests/crt/_mbsncat.c
Normal file
156
modules/rostests/apitests/crt/_mbsncat.c
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* PROJECT: ReactOS API tests
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Tests for _mbsncat
|
||||
* COPYRIGHT: Copyright 2025 Doug Lyons <douglyons@douglyons.com>
|
||||
* Copyright 2025 Stanislav Motylkov <x86corez@gmail.com>
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
#include <mbstring.h>
|
||||
#define WIN32_NO_STATUS
|
||||
#include <pseh/pseh2.h>
|
||||
#include <ndk/mmfuncs.h>
|
||||
|
||||
typedef unsigned char *(__cdecl *PFN__mbsncat)(unsigned char*, const unsigned char*, size_t);
|
||||
|
||||
#ifndef TEST_STATIC_CRT
|
||||
static PFN__mbsncat Init(_In_ LPSTR fname)
|
||||
{
|
||||
static PFN__mbsncat p__mbsncat;
|
||||
HMODULE hdll = LoadLibraryA(TEST_DLL_NAME);
|
||||
|
||||
p__mbsncat = (PFN__mbsncat)GetProcAddress(hdll, fname);
|
||||
ok(p__mbsncat != NULL, "Failed to load %s from %s\n", fname, TEST_DLL_NAME);
|
||||
return p__mbsncat;
|
||||
}
|
||||
#endif
|
||||
|
||||
static USHORT GetWinVersion(VOID)
|
||||
{
|
||||
return ((GetVersion() & 0xFF) << 8) |
|
||||
((GetVersion() >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
VOID mbsncat_PerformTests(_In_ LPSTR fname, _In_opt_ PFN__mbsncat func)
|
||||
{
|
||||
unsigned char dest[16];
|
||||
const unsigned char first[] = "dinosaur";
|
||||
const unsigned char second[] = "duck";
|
||||
unsigned char *s;
|
||||
BOOL MsVcrt = FALSE, CrtDll = FALSE;
|
||||
|
||||
#ifdef TEST_MSVCRT
|
||||
MsVcrt = TRUE;
|
||||
#endif
|
||||
#ifdef TEST_CRTDLL
|
||||
CrtDll = TRUE;
|
||||
#endif
|
||||
|
||||
#ifndef TEST_STATIC_CRT
|
||||
if (!func)
|
||||
func = Init(fname);
|
||||
#endif
|
||||
if (!func)
|
||||
{
|
||||
skip("Skipping tests, because %s is not available\n", fname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Test invalid arguments */
|
||||
StartSeh()
|
||||
s = func(NULL, NULL, 0);
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
ok(s == NULL, "Expected %s to return NULL, got %p\n", fname, s);
|
||||
|
||||
StartSeh()
|
||||
s = func(NULL, NULL, 10);
|
||||
EndSeh((CrtDll || (MsVcrt && GetWinVersion() <= 0x502)) ? STATUS_ACCESS_VIOLATION : STATUS_SUCCESS);
|
||||
ok(s == NULL, "Expected %s to return NULL, got %p\n", fname, s);
|
||||
|
||||
memset(dest, 'X', sizeof(dest));
|
||||
StartSeh()
|
||||
s = func(dest, NULL, 0);
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
ok(s == dest, "Expected %s to return dest pointer, got %p\n", fname, s);
|
||||
ok(dest[0] == 'X', "Expected the output buffer to be untouched\n");
|
||||
|
||||
memset(dest, 'X', sizeof(dest));
|
||||
StartSeh()
|
||||
s = func(dest, second, 0);
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
ok(s == dest, "Expected %s to return dest pointer, got %p\n", fname, s);
|
||||
ok(dest[0] == 'X', "Expected the output buffer to be untouched\n");
|
||||
|
||||
memset(dest, 'X', sizeof(dest));
|
||||
s = NULL;
|
||||
StartSeh()
|
||||
s = func(dest, NULL, 10);
|
||||
EndSeh((CrtDll || (MsVcrt && GetWinVersion() <= 0x502)) ? STATUS_ACCESS_VIOLATION : STATUS_SUCCESS);
|
||||
ok(s == NULL, "Expected %s to return NULL, got %p\n", fname, s);
|
||||
ok(dest[0] == 'X', "Expected the output buffer to be untouched\n");
|
||||
|
||||
memset(dest, 'X', sizeof(dest));
|
||||
dest[0] = '\0';
|
||||
StartSeh()
|
||||
s = func(dest, second, sizeof(second));
|
||||
EndSeh(STATUS_SUCCESS);
|
||||
ok(s == dest, "Expected %s to return dest pointer, got %p\n", fname, s);
|
||||
ok(!memcmp(dest, second, sizeof(second)),
|
||||
"Expected the output buffer string to be \"duck\", got '%s'\n", dest);
|
||||
|
||||
/* Test source truncation behavior */
|
||||
memset(dest, 'X', sizeof(dest));
|
||||
memcpy(dest, first, sizeof(first));
|
||||
s = func(dest, second, 0);
|
||||
ok(s == dest, "Expected %s to return dest pointer, got %p\n", fname, s);
|
||||
ok(!memcmp(dest, first, sizeof(first)),
|
||||
"Expected the output buffer string to be \"dinosaur\", got '%s'\n", dest);
|
||||
|
||||
memset(dest, 'X', sizeof(dest));
|
||||
memcpy(dest, first, sizeof(first));
|
||||
s = func(dest, second, sizeof(second));
|
||||
ok(s == dest, "Expected %s to return dest pointer, got %p\n", fname, s);
|
||||
ok(!memcmp(dest, "dinosaurduck", sizeof("dinosaurduck")),
|
||||
"Expected the output buffer string to be \"dinosaurduck\", got '%s'\n", dest);
|
||||
|
||||
memset(dest, 'X', sizeof(dest));
|
||||
memcpy(dest, first, sizeof(first));
|
||||
s = func(dest, second, sizeof(second) + 1);
|
||||
ok(s == dest, "Expected %s to return dest pointer, got %p\n", fname, s);
|
||||
ok(!memcmp(dest, "dinosaurduck", sizeof("dinosaurduck")),
|
||||
"Expected the output buffer string to be \"dinosaurduck\", got '%s'\n", dest);
|
||||
|
||||
memset(dest, 'X', sizeof(dest));
|
||||
memcpy(dest, first, sizeof(first));
|
||||
s = func(dest, second, sizeof(second) - 1);
|
||||
ok(s == dest, "Expected %s to return dest pointer, got %p\n", fname, s);
|
||||
ok(!memcmp(dest, "dinosaurduck", sizeof("dinosaurduck")),
|
||||
"Expected the output buffer string to be \"dinosaurduck\", got '%s'\n", dest);
|
||||
|
||||
memset(dest, 'X', sizeof(dest));
|
||||
memcpy(dest, first, sizeof(first));
|
||||
s = func(dest, second, sizeof(second) - 2);
|
||||
ok(s == dest, "Expected %s to return dest pointer, got %p\n", fname, s);
|
||||
ok(!memcmp(dest, "dinosaurduc", sizeof("dinosaurduc")),
|
||||
"Expected the output buffer string to be \"dinosaurduc\", got '%s'\n", dest);
|
||||
|
||||
/* Test typical scenario */
|
||||
memset(dest, 'X', sizeof(dest));
|
||||
memcpy(dest, first, sizeof(first));
|
||||
s = func(dest, second, sizeof(second) - 1);
|
||||
ok(s == dest, "Expected %s to return dest pointer, got %p\n", fname, s);
|
||||
ok(!memcmp(dest, "dinosaurduck", sizeof("dinosaurduck")),
|
||||
"Expected the output buffer string to be \"dinosaurduck\", got '%s'\n", dest);
|
||||
|
||||
/* TODO: Add some distinguishing tests (_mbsncat vs. _mbsnbcat) for concatenating chars vs. bytes,
|
||||
* should probably be done with actual multibyte-character strings. */
|
||||
}
|
||||
|
||||
START_TEST(_mbsncat)
|
||||
{
|
||||
#ifndef TEST_STATIC_CRT
|
||||
#define _mbsncat NULL
|
||||
#endif
|
||||
mbsncat_PerformTests("_mbsncat", _mbsncat);
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
list(APPEND SOURCE_STATIC
|
||||
_mbsnbcat.c
|
||||
_mbsncat.c
|
||||
_snprintf.c
|
||||
_snwprintf.c
|
||||
_vscprintf.c
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#define STANDALONE
|
||||
#include <apitest.h>
|
||||
|
||||
extern void func__mbsnbcat(void);
|
||||
extern void func__mbsncat(void);
|
||||
extern void func__mbsncmp(void);
|
||||
extern void func__mbsstr(void);
|
||||
#if defined(_M_ARM)
|
||||
@@ -44,6 +46,8 @@ const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "_vsnprintf", func__vsnprintf },
|
||||
{ "_vsnwprintf", func__vsnwprintf },
|
||||
{ "_mbsnbcat", func__mbsnbcat },
|
||||
{ "_mbsncat", func__mbsncat },
|
||||
{ "mbstowcs", func_mbstowcs },
|
||||
{ "mbtowc", func_mbtowc },
|
||||
{ "setjmp", func_setjmp },
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
list(APPEND SOURCE_CRTDLL
|
||||
../crt/_mbsnbcat.c
|
||||
../crt/_mbsncat.c
|
||||
../crt/_mbsncmp.c
|
||||
../crt/_mbsstr.c
|
||||
../crt/setjmp.c
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#define STANDALONE
|
||||
#include <apitest.h>
|
||||
|
||||
extern void func__mbsnbcat(void);
|
||||
extern void func__mbsncat(void);
|
||||
extern void func__mbsncmp(void);
|
||||
extern void func__mbsstr(void);
|
||||
extern void func__snprintf(void);
|
||||
@@ -22,6 +24,8 @@ extern void func_wctomb(void);
|
||||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "_mbsnbcat", func__mbsnbcat },
|
||||
{ "_mbsncat", func__mbsncat },
|
||||
{ "_mbsncmp", func__mbsncmp },
|
||||
{ "_mbsstr", func__mbsstr },
|
||||
{ "_snprintf", func__snprintf },
|
||||
|
||||
@@ -10,6 +10,8 @@ list(APPEND SOURCE_CRT_TESTS
|
||||
../crt/fpcontrol.c
|
||||
../crt/_finite.c
|
||||
../crt/_isnan.c
|
||||
../crt/_mbsnbcat.c
|
||||
../crt/_mbsncat.c
|
||||
../crt/_mbsncmp.c
|
||||
../crt/_mbsstr.c
|
||||
../crt/_snprintf.c
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
extern void func__finite(void);
|
||||
extern void func__isnan(void);
|
||||
extern void func__mbsnbcat(void);
|
||||
extern void func__mbsncat(void);
|
||||
extern void func__mbsncmp(void);
|
||||
extern void func__mbsstr(void);
|
||||
extern void func__snprintf(void);
|
||||
@@ -60,6 +62,8 @@ const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "_finite", func__finite },
|
||||
{ "_isnan", func__isnan },
|
||||
{ "_mbsnbcat", func__mbsnbcat },
|
||||
{ "_mbsncat", func__mbsncat },
|
||||
{ "_mbsncmp", func__mbsncmp },
|
||||
{ "_mbsstr", func__mbsstr },
|
||||
{ "_snprintf", func__snprintf },
|
||||
|
||||
Reference in New Issue
Block a user