xref: /freebsd-src/lib/libc/tests/string/strncmp_test.c (revision 459ddefcc9dcc010f6f7445285e61e2b6780379c)
1*459ddefcSRobert Clausecker /*-
2*459ddefcSRobert Clausecker  * Copyright (c) 2023 The FreeBSD Foundation
3*459ddefcSRobert Clausecker  *
4*459ddefcSRobert Clausecker  * This software was developed by Robert Clausecker <fuz@FreeBSD.org>
5*459ddefcSRobert Clausecker  * under sponsorship from the FreeBSD Foundation.
6*459ddefcSRobert Clausecker  *
7*459ddefcSRobert Clausecker  * Redistribution and use in source and binary forms, with or without
8*459ddefcSRobert Clausecker  * modification, are permitted provided that the following conditions
9*459ddefcSRobert Clausecker  * are met:
10*459ddefcSRobert Clausecker  * 1. Redistributions of source code must retain the above copyright
11*459ddefcSRobert Clausecker  *    notice, this list of conditions and the following disclaimer.
12*459ddefcSRobert Clausecker  * 2. Redistributions in binary form must reproduce the above copyright
13*459ddefcSRobert Clausecker  *    notice, this list of conditions and the following disclaimer in the
14*459ddefcSRobert Clausecker  *    documentation and/or other materials provided with the distribution.
15*459ddefcSRobert Clausecker  *
16*459ddefcSRobert Clausecker  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ''AS IS'' AND
17*459ddefcSRobert Clausecker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*459ddefcSRobert Clausecker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*459ddefcSRobert Clausecker  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*459ddefcSRobert Clausecker  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*459ddefcSRobert Clausecker  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*459ddefcSRobert Clausecker  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*459ddefcSRobert Clausecker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*459ddefcSRobert Clausecker  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*459ddefcSRobert Clausecker  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*459ddefcSRobert Clausecker  * SUCH DAMAGE
27*459ddefcSRobert Clausecker  */
28*459ddefcSRobert Clausecker 
29*459ddefcSRobert Clausecker #include <sys/cdefs.h>
30*459ddefcSRobert Clausecker 
31*459ddefcSRobert Clausecker #include <atf-c.h>
32*459ddefcSRobert Clausecker #include <dlfcn.h>
33*459ddefcSRobert Clausecker #include <string.h>
34*459ddefcSRobert Clausecker 
35*459ddefcSRobert Clausecker int (*volatile strncmp_fn)(const char *, const char *, size_t);
36*459ddefcSRobert Clausecker 
37*459ddefcSRobert Clausecker static void
alignment_testcase(char * a,char * b,int want,size_t len)38*459ddefcSRobert Clausecker alignment_testcase(char *a, char *b, int want, size_t len)
39*459ddefcSRobert Clausecker {
40*459ddefcSRobert Clausecker 	int res;
41*459ddefcSRobert Clausecker 
42*459ddefcSRobert Clausecker 	res = strncmp_fn(a, b, len);
43*459ddefcSRobert Clausecker 	ATF_CHECK_MSG(want == (res > 0) - (res < 0),
44*459ddefcSRobert Clausecker 	    "strcmp(%p \"%s\", %p \"%s\", %zu) = %d != %d",
45*459ddefcSRobert Clausecker 	    (void *)a, a, (void *)b, b, len, res, want);
46*459ddefcSRobert Clausecker }
47*459ddefcSRobert Clausecker 
48*459ddefcSRobert Clausecker static void
check_strncmp_alignments(char a[],char b[],size_t a_off,size_t b_off,size_t len,size_t pos)49*459ddefcSRobert Clausecker check_strncmp_alignments(char a[], char b[],
50*459ddefcSRobert Clausecker     size_t a_off, size_t b_off, size_t len, size_t pos)
51*459ddefcSRobert Clausecker {
52*459ddefcSRobert Clausecker 	char *a_str, *b_str, a_orig, b_orig;
53*459ddefcSRobert Clausecker 
54*459ddefcSRobert Clausecker 	a[a_off] = '\0';
55*459ddefcSRobert Clausecker 	b[b_off] = '\0';
56*459ddefcSRobert Clausecker 
57*459ddefcSRobert Clausecker 	a_str = a + a_off + 1;
58*459ddefcSRobert Clausecker 	b_str = b + b_off + 1;
59*459ddefcSRobert Clausecker 
60*459ddefcSRobert Clausecker 	a_str[len] = '\0';
61*459ddefcSRobert Clausecker 	b_str[len] = '\0';
62*459ddefcSRobert Clausecker 	a_str[len+1] = 'A';
63*459ddefcSRobert Clausecker 	b_str[len+1] = 'B';
64*459ddefcSRobert Clausecker 
65*459ddefcSRobert Clausecker 	a_orig = a_str[pos];
66*459ddefcSRobert Clausecker 	b_orig = b_str[pos];
67*459ddefcSRobert Clausecker 
68*459ddefcSRobert Clausecker 	alignment_testcase(a_str, b_str, 0, len + 16);
69*459ddefcSRobert Clausecker 	alignment_testcase(a_str, b_str, 0, len + 1);
70*459ddefcSRobert Clausecker 	alignment_testcase(a_str, b_str, 0, len);
71*459ddefcSRobert Clausecker 
72*459ddefcSRobert Clausecker 	if (pos < len) {
73*459ddefcSRobert Clausecker 		a_str[pos] = '\0';
74*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, -1, len + 16);
75*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, -1, len + 1);
76*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, -1, len);
77*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, -1, pos + 1);
78*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, 0, pos);
79*459ddefcSRobert Clausecker 		a_str[pos] = a_orig;
80*459ddefcSRobert Clausecker 
81*459ddefcSRobert Clausecker 		b_str[pos] = '\0';
82*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, 1, len + 16);
83*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, 1, len + 1);
84*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, 1, len);
85*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, 1, pos + 1);
86*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, 0, pos);
87*459ddefcSRobert Clausecker 		b_str[pos] = b_orig;
88*459ddefcSRobert Clausecker 	}
89*459ddefcSRobert Clausecker 
90*459ddefcSRobert Clausecker 	a_str[pos] = 'X';
91*459ddefcSRobert Clausecker 	alignment_testcase(a_str, b_str, 1, len + 16);
92*459ddefcSRobert Clausecker 	alignment_testcase(a_str, b_str, 0, pos);
93*459ddefcSRobert Clausecker 	alignment_testcase(a_str, b_str, 1, pos + 1);
94*459ddefcSRobert Clausecker 	if (pos < len) {
95*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, 1, len);
96*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, 1, len + 1);
97*459ddefcSRobert Clausecker 	}
98*459ddefcSRobert Clausecker 	a_str[pos] = a_orig;
99*459ddefcSRobert Clausecker 
100*459ddefcSRobert Clausecker 	b_str[pos] = 'X';
101*459ddefcSRobert Clausecker 	alignment_testcase(a_str, b_str, -1, len + 16);
102*459ddefcSRobert Clausecker 	alignment_testcase(a_str, b_str, 0, pos);
103*459ddefcSRobert Clausecker 	alignment_testcase(a_str, b_str, -1, pos + 1);
104*459ddefcSRobert Clausecker 	if (pos < len) {
105*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, -1, len);
106*459ddefcSRobert Clausecker 		alignment_testcase(a_str, b_str, -1, len + 1);
107*459ddefcSRobert Clausecker 	}
108*459ddefcSRobert Clausecker 	b_str[pos] = b_orig;
109*459ddefcSRobert Clausecker 
110*459ddefcSRobert Clausecker 	a[a_off] = '-';
111*459ddefcSRobert Clausecker 	b[b_off] = '-';
112*459ddefcSRobert Clausecker 	a_str[len] = '-';
113*459ddefcSRobert Clausecker 	b_str[len] = '-';
114*459ddefcSRobert Clausecker 	a_str[len+1] = '-';
115*459ddefcSRobert Clausecker 	b_str[len+1] = '-';
116*459ddefcSRobert Clausecker }
117*459ddefcSRobert Clausecker 
118*459ddefcSRobert Clausecker ATF_TC(strncmp_alignments);
ATF_TC_HEAD(strncmp_alignments,tc)119*459ddefcSRobert Clausecker ATF_TC_HEAD(strncmp_alignments, tc)
120*459ddefcSRobert Clausecker {
121*459ddefcSRobert Clausecker 	atf_tc_set_md_var(tc, "descr", "Test strncmp(3) with various alignments");
122*459ddefcSRobert Clausecker }
123*459ddefcSRobert Clausecker 
ATF_TC_BODY(strncmp_alignments,tc)124*459ddefcSRobert Clausecker ATF_TC_BODY(strncmp_alignments, tc)
125*459ddefcSRobert Clausecker {
126*459ddefcSRobert Clausecker 	size_t a_off, b_off, len, pos;
127*459ddefcSRobert Clausecker 	char a[64+16+16+3], b[64+16+16+3];
128*459ddefcSRobert Clausecker 
129*459ddefcSRobert Clausecker 	memset(a, '-', sizeof(a));
130*459ddefcSRobert Clausecker 	memset(b, '-', sizeof(b));
131*459ddefcSRobert Clausecker 	a[sizeof(a) - 1] = '\0';
132*459ddefcSRobert Clausecker 	b[sizeof(b) - 1] = '\0';
133*459ddefcSRobert Clausecker 
134*459ddefcSRobert Clausecker 	for (a_off = 0; a_off < 16; a_off++)
135*459ddefcSRobert Clausecker 		for (b_off = 0; b_off < 16; b_off++)
136*459ddefcSRobert Clausecker 			for (len = 1; len <= 64; len++)
137*459ddefcSRobert Clausecker 				for (pos = 0; pos <= len; pos++)
138*459ddefcSRobert Clausecker 					check_strncmp_alignments(a, b, a_off, b_off, len, pos);
139*459ddefcSRobert Clausecker }
140*459ddefcSRobert Clausecker 
141*459ddefcSRobert Clausecker ATF_TC(strncmp_null);
ATF_TC_HEAD(strncmp_null,tc)142*459ddefcSRobert Clausecker ATF_TC_HEAD(strncmp_null, tc)
143*459ddefcSRobert Clausecker {
144*459ddefcSRobert Clausecker 	atf_tc_set_md_var(tc, "descr", "Test strncmp(3) with null pointers");
145*459ddefcSRobert Clausecker }
146*459ddefcSRobert Clausecker 
ATF_TC_BODY(strncmp_null,tc)147*459ddefcSRobert Clausecker ATF_TC_BODY(strncmp_null, tc)
148*459ddefcSRobert Clausecker {
149*459ddefcSRobert Clausecker 	alignment_testcase(NULL, NULL, 0, 0);
150*459ddefcSRobert Clausecker }
151*459ddefcSRobert Clausecker 
ATF_TP_ADD_TCS(tp)152*459ddefcSRobert Clausecker ATF_TP_ADD_TCS(tp)
153*459ddefcSRobert Clausecker {
154*459ddefcSRobert Clausecker 	void *dl_handle;
155*459ddefcSRobert Clausecker 
156*459ddefcSRobert Clausecker 	dl_handle = dlopen(NULL, RTLD_LAZY);
157*459ddefcSRobert Clausecker 	strncmp_fn = dlsym(dl_handle, "test_strncmp");
158*459ddefcSRobert Clausecker 	if (strncmp_fn == NULL)
159*459ddefcSRobert Clausecker 		strncmp_fn = strncmp;
160*459ddefcSRobert Clausecker 
161*459ddefcSRobert Clausecker 	ATF_TP_ADD_TC(tp, strncmp_alignments);
162*459ddefcSRobert Clausecker 	ATF_TP_ADD_TC(tp, strncmp_null);
163*459ddefcSRobert Clausecker 
164*459ddefcSRobert Clausecker 	return atf_no_error();
165*459ddefcSRobert Clausecker }
166