https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c8aba5a172da641b47ded…
commit c8aba5a172da641b47dedb2ed708c574027b873f
Author: Thomas Faber <thomas.faber(a)reactos.org>
AuthorDate: Fri Jan 12 12:31:12 2024 -0500
Commit: Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Fri Jan 12 12:36:43 2024 -0500
[CRT_APITEST] Add tests for _mbsncmp and _mbsstr. CORE-16933
---
modules/rostests/apitests/crt/_mbsncmp.c | 70 +++++++++++++++++
modules/rostests/apitests/crt/_mbsstr.c | 87 ++++++++++++++++++++++
.../rostests/apitests/crt/crtdll_crt_apitest.cmake | 4 +-
.../rostests/apitests/crt/msvcrt_crt_apitest.cmake | 4 +-
modules/rostests/apitests/crt/testlist.c | 4 +
5 files changed, 165 insertions(+), 4 deletions(-)
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(a)reactos.org)
+ */
+
+#include <apitest.h>
+#include <mbstring.h>
+#define WIN32_NO_STATUS
+#include <pseh/pseh2.h>
+#include <ndk/mmfuncs.h>
+
+/*
+ * 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(a)reactos.org)
+ */
+
+#include <apitest.h>
+#include <mbstring.h>
+#define WIN32_NO_STATUS
+#include <pseh/pseh2.h>
+#include <ndk/mmfuncs.h>
+
+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 <apitest.h>
+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)