1272343Sngie/* $NetBSD: t_strcpy.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */
2272343Sngie
3272343Sngie/*
4272343Sngie * Written by J.T. Conklin <jtc@acorntoolworks.com>
5272343Sngie * Public domain.
6272343Sngie */
7272343Sngie
8272343Sngie#include <atf-c.h>
9272343Sngie#include <string.h>
10272343Sngie#include <unistd.h>
11272343Sngie#include <stdio.h>
12272343Sngie#include <stdlib.h>
13272343Sngie
14272343SngieATF_TC(strcpy_basic);
15272343SngieATF_TC_HEAD(strcpy_basic, tc)
16272343Sngie{
17272343Sngie        atf_tc_set_md_var(tc, "descr", "Test strcpy(3) results");
18272343Sngie}
19272343Sngie
20272343SngieATF_TC_BODY(strcpy_basic, tc)
21272343Sngie{
22272343Sngie	/* try to trick the compiler */
23272343Sngie	char * (*f)(char *, const char *s) = strcpy;
24272343Sngie
25272343Sngie	unsigned int a0, a1, t;
26272343Sngie	char buf0[64];
27272343Sngie	char buf1[64];
28272343Sngie	char *ret;
29272343Sngie
30272343Sngie	struct tab {
31272343Sngie		const char*	val;
32272343Sngie		size_t		len;
33272343Sngie	};
34272343Sngie
35272343Sngie	const struct tab tab[] = {
36272343Sngie		/*
37272343Sngie		 * patterns that check for all combinations of leading and
38272343Sngie		 * trailing unaligned characters (on a 64 bit processor)
39272343Sngie		 */
40272343Sngie
41272343Sngie		{ "",				0 },
42272343Sngie		{ "a",				1 },
43272343Sngie		{ "ab",				2 },
44272343Sngie		{ "abc",			3 },
45272343Sngie		{ "abcd",			4 },
46272343Sngie		{ "abcde",			5 },
47272343Sngie		{ "abcdef",			6 },
48272343Sngie		{ "abcdefg",			7 },
49272343Sngie		{ "abcdefgh",			8 },
50272343Sngie		{ "abcdefghi",			9 },
51272343Sngie		{ "abcdefghij",			10 },
52272343Sngie		{ "abcdefghijk",		11 },
53272343Sngie		{ "abcdefghijkl",		12 },
54272343Sngie		{ "abcdefghijklm",		13 },
55272343Sngie		{ "abcdefghijklmn",		14 },
56272343Sngie		{ "abcdefghijklmno",		15 },
57272343Sngie		{ "abcdefghijklmnop",		16 },
58272343Sngie		{ "abcdefghijklmnopq",		17 },
59272343Sngie		{ "abcdefghijklmnopqr",		18 },
60272343Sngie		{ "abcdefghijklmnopqrs",	19 },
61272343Sngie		{ "abcdefghijklmnopqrst",	20 },
62272343Sngie		{ "abcdefghijklmnopqrstu",	21 },
63272343Sngie		{ "abcdefghijklmnopqrstuv",	22 },
64272343Sngie		{ "abcdefghijklmnopqrstuvw",	23 },
65272343Sngie
66272343Sngie		/*
67272343Sngie		 * patterns that check for the cases where the expression:
68272343Sngie		 *
69272343Sngie		 *	((word - 0x7f7f..7f) & 0x8080..80)
70272343Sngie		 *
71272343Sngie		 * returns non-zero even though there are no zero bytes in
72272343Sngie		 * the word.
73272343Sngie		 */
74272343Sngie
75272343Sngie		{ "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh",	16 },
76272343Sngie		{ "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh",	16 },
77272343Sngie		{ "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh",	16 },
78272343Sngie		{ "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh",	16 },
79272343Sngie		{ "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh",	16 },
80272343Sngie		{ "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh",	16 },
81272343Sngie		{ "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh",	16 },
82272343Sngie		{ "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h",	16 },
83272343Sngie		{ "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "",	16 },
84272343Sngie	};
85272343Sngie
86272343Sngie	for (a0 = 0; a0 < sizeof(long); ++a0) {
87272343Sngie		for (a1 = 0; a1 < sizeof(long); ++a1) {
88272343Sngie			for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
89272343Sngie
90272343Sngie				memcpy(&buf1[a1], tab[t].val, tab[t].len + 1);
91272343Sngie				ret = f(&buf0[a0], &buf1[a1]);
92272343Sngie
93272343Sngie				/*
94272343Sngie				 * verify strcpy returns address of
95272343Sngie				 * first parameter
96272343Sngie				 */
97272343Sngie			    	if (&buf0[a0] != ret) {
98272343Sngie					fprintf(stderr, "a0 %d, a1 %d, t %d\n",
99272343Sngie					    a0, a1, t);
100272343Sngie					atf_tc_fail("strcpy did not return "
101272343Sngie					    "its first arg");
102272343Sngie				}
103272343Sngie
104272343Sngie				/*
105272343Sngie				 * verify string was copied correctly
106272343Sngie				 */
107272343Sngie				if (memcmp(&buf0[a0], &buf1[a1],
108272343Sngie					   tab[t].len + 1) != 0) {
109272343Sngie					fprintf(stderr, "a0 %d, a1 %d, t %d\n",
110272343Sngie					    a0, a1, t);
111272343Sngie					atf_tc_fail("not correctly copied");
112272343Sngie				}
113272343Sngie			}
114272343Sngie		}
115272343Sngie	}
116272343Sngie}
117272343Sngie
118272343SngieATF_TP_ADD_TCS(tp)
119272343Sngie{
120272343Sngie
121272343Sngie	ATF_TP_ADD_TC(tp, strcpy_basic);
122272343Sngie
123272343Sngie	return atf_no_error();
124272343Sngie}
125