From c8aba5a172da641b47dedb2ed708c574027b873f Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Fri, 12 Jan 2024 12:31:12 -0500 Subject: [PATCH] [CRT_APITEST] Add tests for _mbsncmp and _mbsstr. CORE-16933 --- modules/rostests/apitests/crt/_mbsncmp.c | 70 +++++++++++++++ modules/rostests/apitests/crt/_mbsstr.c | 87 +++++++++++++++++++ .../apitests/crt/crtdll_crt_apitest.cmake | 4 +- .../apitests/crt/msvcrt_crt_apitest.cmake | 4 +- modules/rostests/apitests/crt/testlist.c | 4 + 5 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 modules/rostests/apitests/crt/_mbsncmp.c create mode 100644 modules/rostests/apitests/crt/_mbsstr.c diff --git a/modules/rostests/apitests/crt/_mbsncmp.c b/modules/rostests/apitests/crt/_mbsncmp.c new file mode 100644 index 00000000000..7aa099cde3c --- /dev/null +++ b/modules/rostests/apitests/crt/_mbsncmp.c @@ -0,0 +1,70 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Tests for _mbsncmp + * COPYRIGHT: Copyright 2024 Thomas Faber (thomas.faber@reactos.org) + */ + +#include +#include +#define WIN32_NO_STATUS +#include +#include + +/* + * cmp functions can either return 1/-1 or the actual difference between the + * first two differing characters. + * On Win2003, both crtdll and msvcrt always return 1/-1. + * On Win10, msvcrt returns the diff, crtdll returns 1/-1. + */ +#ifdef TEST_CRTDLL +#define RETURN_DIFF 0 +#else +#define RETURN_DIFF (GetVersion() >= 0x0600) +#endif + +#define DIFF_RETURN(sign, absolute) (sign (RETURN_DIFF ? absolute : 1)) + +START_TEST(_mbsncmp) +{ + int ret; + + /* Zero length always returns true */ + ret = _mbsncmp(NULL, NULL, 0); + ok(ret == 0, "ret = %d\n", ret); + + ret = _mbsncmp("a", "c", 0); + ok(ret == 0, "ret = %d\n", ret); + + /* No null checks - length 1 crashes */ + StartSeh() + (void)_mbsncmp("a", NULL, 1); + EndSeh(STATUS_ACCESS_VIOLATION); + + StartSeh() + (void)_mbsncmp(NULL, "c", 1); + EndSeh(STATUS_ACCESS_VIOLATION); + + /* Strings longer than or equal to length */ + ret = _mbsncmp("a", "c", 1); + ok(ret == DIFF_RETURN(-, 2), "ret = %d\n", ret); + + ret = _mbsncmp("a", "a", 1); + ok(ret == 0, "ret = %d\n", ret); + + ret = _mbsncmp("ab", "aB", 1); + ok(ret == 0, "ret = %d\n", ret); + + ret = _mbsncmp("aa", "ac", 2); + ok(ret == DIFF_RETURN(-, 2), "ret = %d\n", ret); + + /* Length longer than one of the strings */ + ret = _mbsncmp("a", "ac", 2); + ok(ret == DIFF_RETURN(-, 'c'), "ret = %d\n", ret); + + ret = _mbsncmp("aa", "a", 2); + ok(ret == DIFF_RETURN(+, 'a'), "ret = %d\n", ret); + + ret = _mbsncmp("ab", "ab", 100); + ok(ret == 0, "ret = %d\n", ret); +} diff --git a/modules/rostests/apitests/crt/_mbsstr.c b/modules/rostests/apitests/crt/_mbsstr.c new file mode 100644 index 00000000000..fc926c1cee8 --- /dev/null +++ b/modules/rostests/apitests/crt/_mbsstr.c @@ -0,0 +1,87 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Tests for _mbsstr + * COPYRIGHT: Copyright 2024 Thomas Faber (thomas.faber@reactos.org) + */ + +#include +#include +#define WIN32_NO_STATUS +#include +#include + +START_TEST(_mbsstr) +{ + unsigned char *haystack; + unsigned char *ret; + + /* NULL pointers are not handled */ + StartSeh() + (void)_mbsstr(NULL, NULL); + EndSeh(STATUS_ACCESS_VIOLATION); + + StartSeh() + haystack = "hello"; + (void)_mbsstr(haystack, NULL); + EndSeh(STATUS_ACCESS_VIOLATION); + + StartSeh() + haystack = ""; + (void)_mbsstr(haystack, NULL); + EndSeh(STATUS_ACCESS_VIOLATION); + + /* Empty needle returns haystack, empty haystack returns NULL... */ + haystack = "hello"; + ret = _mbsstr(haystack, ""); + ok(ret == haystack, "ret = %p, haystack = %p\n", ret, haystack); + + haystack = ""; + ret = _mbsstr(haystack, "a"); + ok(ret == NULL, "ret = %p, haystack = %p\n", ret, haystack); + + /* ... but if both are empty, behavior differs */ + haystack = ""; + ret = _mbsstr(haystack, ""); +#ifdef TEST_CRTDLL + ok(ret == NULL, "ret = %p, haystack = %p\n", ret, haystack); +#else + ok(ret == haystack, "ret = %p, haystack = %p\n", ret, haystack); +#endif + + /* Simple "found" cases */ + haystack = "abcdefg"; + ret = _mbsstr(haystack, "abc"); + ok(ret == haystack, "ret = %p, haystack = %p\n", ret, haystack); + + haystack = "abcdefg"; + ret = _mbsstr(haystack, "g"); + ok(ret == haystack + 6, "ret = %p, haystack = %p\n", ret, haystack); + + haystack = "abcdefg"; + ret = _mbsstr(haystack, "abcdefg"); + ok(ret == haystack, "ret = %p, haystack = %p\n", ret, haystack); + + /* Simple "not found" cases */ + haystack = "abcdefg"; + ret = _mbsstr(haystack, "h"); + ok(ret == NULL, "ret = %p, haystack = %p\n", ret, haystack); + + haystack = "abcdefg"; + ret = _mbsstr(haystack, "gh"); + ok(ret == NULL, "ret = %p, haystack = %p\n", ret, haystack); + + haystack = "abcdefg"; + ret = _mbsstr(haystack, "abcD"); + ok(ret == NULL, "ret = %p, haystack = %p\n", ret, haystack); + + /* Needle longer than haystack */ + haystack = "abcdefg"; + ret = _mbsstr(haystack, "abcdefgh"); + ok(ret == NULL, "ret = %p, haystack = %p\n", ret, haystack); + + haystack = "abcdefg"; + ret = _mbsstr(haystack, "xxxxxxxx"); + ok(ret == NULL, "ret = %p, haystack = %p\n", ret, haystack); +} + diff --git a/modules/rostests/apitests/crt/crtdll_crt_apitest.cmake b/modules/rostests/apitests/crt/crtdll_crt_apitest.cmake index c6f60ea1d56..cc9a32d004b 100644 --- a/modules/rostests/apitests/crt/crtdll_crt_apitest.cmake +++ b/modules/rostests/apitests/crt/crtdll_crt_apitest.cmake @@ -212,7 +212,7 @@ list(APPEND SOURCE_CRTDLL # _mbsnbset.c # _mbsncat.c # _mbsnccnt.c -# _mbsncmp.c + _mbsncmp.c # _mbsncpy.c # _mbsnextc.c # _mbsnicmp.c @@ -224,7 +224,7 @@ list(APPEND SOURCE_CRTDLL # _mbsset.c # _mbsspn.c # _mbsspnp.c -# _mbsstr.c + _mbsstr.c # _mbstok.c # _mbstrlen.c # _mbsupr.c diff --git a/modules/rostests/apitests/crt/msvcrt_crt_apitest.cmake b/modules/rostests/apitests/crt/msvcrt_crt_apitest.cmake index 919a7b01b64..0d1984b5d17 100644 --- a/modules/rostests/apitests/crt/msvcrt_crt_apitest.cmake +++ b/modules/rostests/apitests/crt/msvcrt_crt_apitest.cmake @@ -549,7 +549,7 @@ list(APPEND SOURCE_MSVCRT # _mbsncat_s_l # _mbsnccnt.c # _mbsnccnt_l -# _mbsncmp.c + _mbsncmp.c # _mbsncmp_l # _mbsncoll.c # _mbsncoll_l @@ -585,7 +585,7 @@ list(APPEND SOURCE_MSVCRT # _mbsspn_l # _mbsspnp.c # _mbsspnp_l -# _mbsstr.c + _mbsstr.c # _mbsstr_l # _mbstok.c # _mbstok_l diff --git a/modules/rostests/apitests/crt/testlist.c b/modules/rostests/apitests/crt/testlist.c index 14f0bb97ad3..e1592928611 100644 --- a/modules/rostests/apitests/crt/testlist.c +++ b/modules/rostests/apitests/crt/testlist.c @@ -3,6 +3,8 @@ #define STANDALONE #include +extern void func__mbsncmp(void); +extern void func__mbsstr(void); #if defined(TEST_MSVCRT) extern void func__vscprintf(void); extern void func__vscwprintf(void); @@ -60,6 +62,8 @@ const struct test winetest_testlist[] = { "strlen", func_strlen }, { "strtoul", func_strtoul }, #if defined(TEST_CRTDLL) || defined(TEST_MSVCRT) + { "_mbsncmp", func__mbsncmp }, + { "_mbsstr", func__mbsstr }, { "system", func_system }, #endif #if defined(TEST_MSVCRT)