1 /*
2  * PROJECT:         ReactOS API tests
3  * LICENSE:         LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4  * PURPOSE:         Tests for _mbsncmp
5  * COPYRIGHT:       Copyright 2024 Thomas Faber (thomas.faber@reactos.org)
6  */
7 
8 #include <apitest.h>
9 #include <mbstring.h>
10 #define WIN32_NO_STATUS
11 #include <pseh/pseh2.h>
12 #include <ndk/mmfuncs.h>
13 
14 ULONG g_WinVersion;
15 
16 /*
17  * cmp functions can either return 1/-1 or the actual difference between the
18  * first two differing characters.
19  * On Win2003, both crtdll and msvcrt always return 1/-1.
20  * On Win10, msvcrt returns the diff, crtdll returns 1/-1.
21  */
22 #ifdef TEST_CRTDLL
23 #define RETURN_DIFF 0
24 #else
25 #define RETURN_DIFF (g_WinVersion >= _WIN32_WINNT_VISTA)
26 #endif
27 
28 #define DIFF_RETURN(sign, absolute) (sign (RETURN_DIFF ? absolute : 1))
29 
START_TEST(_mbsncmp)30 START_TEST(_mbsncmp)
31 {
32     int ret;
33 
34     ULONG Version = GetVersion();
35     g_WinVersion = (Version & 0xFF) << 8 | (Version & 0xFF00) >> 8;
36 
37     /* Zero length always returns true */
38     ret = _mbsncmp(NULL, NULL, 0);
39     ok(ret == 0, "ret = %d\n", ret);
40 
41     ret = _mbsncmp((const unsigned char *)"a", (const unsigned char *)"c", 0);
42     ok(ret == 0, "ret = %d\n", ret);
43 
44     /* No null checks - length 1 crashes */
45     StartSeh()
46         (void)_mbsncmp((const unsigned char *)"a", NULL, 1);
47     EndSeh(STATUS_ACCESS_VIOLATION);
48 
49     StartSeh()
50         (void)_mbsncmp(NULL, (const unsigned char *)"c", 1);
51     EndSeh(STATUS_ACCESS_VIOLATION);
52 
53     /* Strings longer than or equal to length */
54     ret = _mbsncmp((const unsigned char *)"a", (const unsigned char *)"c", 1);
55     ok(ret == DIFF_RETURN(-, 2), "ret = %d\n", ret);
56 
57     ret = _mbsncmp((const unsigned char *)"a", (const unsigned char *)"a", 1);
58     ok(ret == 0, "ret = %d\n", ret);
59 
60     ret = _mbsncmp((const unsigned char *)"ab", (const unsigned char *)"aB", 1);
61     ok(ret == 0, "ret = %d\n", ret);
62 
63     ret = _mbsncmp((const unsigned char *)"aa", (const unsigned char *)"ac", 2);
64     ok(ret == DIFF_RETURN(-, 2), "ret = %d\n", ret);
65 
66     /* Length longer than one of the strings */
67     ret = _mbsncmp((const unsigned char *)"a", (const unsigned char *)"ac", 2);
68     ok(ret == DIFF_RETURN(-, 'c'), "ret = %d\n", ret);
69 
70     ret = _mbsncmp((const unsigned char *)"aa", (const unsigned char *)"a", 2);
71     ok(ret == DIFF_RETURN(+, 'a'), "ret = %d\n", ret);
72 
73     ret = _mbsncmp((const unsigned char *)"ab", (const unsigned char *)"ab", 100);
74     ok(ret == 0, "ret = %d\n", ret);
75 }
76