xref: /illumos-gate/usr/src/cmd/sendmail/libsm/t-qic.c (revision 058561cb)
1 /*
2  * Copyright (c) 2006 Sendmail, Inc. and its suppliers.
3  *	All rights reserved.
4  *
5  * By using this file, you agree to the terms and conditions set
6  * forth in the LICENSE file which can be found at the top level of
7  * the sendmail distribution.
8  */
9 
10 #pragma ident	"%Z%%M%	%I%	%E% SMI"
11 
12 #include <sm/gen.h>
13 SM_IDSTR(id, "@(#)$Id: t-qic.c,v 1.9 2006/08/24 21:26:13 ca Exp $")
14 
15 #include <stdio.h>
16 #include <sm/sendmail.h>
17 #include <sm/assert.h>
18 #include <sm/heap.h>
19 #include <sm/string.h>
20 #include <sm/test.h>
21 
22 extern bool SmTestVerbose;
23 
24 
25 void
26 show_diff(s1, s2)
27 	const char *s1;
28 	const char *s2;
29 {
30 	int i;
31 
32 	for (i = 0; s1[i] != '\0' && s2[i] != '\0'; i++)
33 	{
34 		if (s1[i] != s2[i])
35 		{
36 			fprintf(stderr, "i=%d, s1[]=%u, s2[]=%u\n",
37 				i, (unsigned char) s1[i],
38 				(unsigned char) s2[i]);
39 			return;
40 		}
41 	}
42 	if (s1[i] != s2[i])
43 	{
44 		fprintf(stderr, "i=%d, s1[]=%u, s2[]=%u\n",
45 			i, (unsigned char) s1[i], (unsigned char) s2[i]);
46 	}
47 }
48 
49 char *quote_unquote __P((char *, char *, int, int));
50 
51 char *
52 quote_unquote(in, out, outlen, exp)
53 	char *in;
54 	char *out;
55 	int outlen;
56 	int exp;
57 {
58 	char *obp, *bp;
59 	char line_back[1024];
60 	char line_in[1024];
61 	int cmp;
62 
63 	sm_strlcpy(line_in, in, sizeof(line_in));
64 	obp = quote_internal_chars(in, out, &outlen);
65 	bp = str2prt(line_in);
66 	dequote_internal_chars(obp, line_back, sizeof(line_back));
67 	cmp = strcmp(line_in, line_back);
68 	SM_TEST(exp == cmp);
69 	if (cmp != exp && !SmTestVerbose)
70 	{
71 		fprintf(stderr, "in: %s\n", bp);
72 		bp = str2prt(line_back);
73 		fprintf(stderr, "out:%s\n", bp);
74 		fprintf(stderr, "cmp=%d\n", cmp);
75 		show_diff(in, line_back);
76 	}
77 	if (SmTestVerbose)
78 	{
79 		fprintf(stderr, "%s -> ", bp);
80 		bp = str2prt(obp);
81 		fprintf(stderr, "%s\n", bp);
82 		fprintf(stderr, "cmp=%d\n", cmp);
83 	}
84 	return obp;
85 }
86 
87 struct sm_qic_S
88 {
89 	char		*qic_in;
90 	char		*qic_out;
91 	int		 qic_exp;
92 };
93 
94 typedef struct sm_qic_S sm_qic_T;
95 
96 
97 int
98 main(argc, argv)
99 	int argc;
100 	char *argv[];
101 {
102 	char line_in[1024], line[256], line_out[32], *obp;
103 	int i, los, cmp;
104 	sm_qic_T inout[] = {
105 		  { "", "",	0 }
106 		, { "abcdef", "abcdef",	0 }
107 		, { "01234567890123456789", "01234567890123456789",	0 }
108 		, { "01234567890123456789\001", "01234567890123456789\001",
109 			0 }
110 		, { "012345\2067890123456789", "012345\377\2067890123456789",
111 			0 }
112 		, { "\377", "\377\377",	0 }
113 		, { "\240", "\240",	0 }
114 		, { "\220", "\377\220",	0 }
115 		, { "\240\220", "\240\377\220",	0 }
116 		, { "\377\377", "\377\377\377\377",	0 }
117 		, { "\377a\377b", "\377\377a\377\377b",	0 }
118 		, { "\376a\377b", "\376a\377\377b",	0 }
119 		, { "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240",
120 		    "\377\200\377\201\377\202\377\203\377\204\377\205\377\206\377\207\377\210\377\211\377\212\377\213\377\214\377\215\377\216\377\217\377\220\377\221\377\222\377\223\377\224\377\225\377\226\377\227\377\230\377\231\377\232\377\233\377\234\377\235\377\236\377\237\240",
121 			0 }
122 		, { NULL, NULL,	0 }
123 	};
124 
125 	sm_test_begin(argc, argv, "test meta quoting");
126 	for (i = 0; i < sizeof(line_out); i++)
127 		line_out[i] = '\0';
128 	for (i = 0; i < sizeof(line_in); i++)
129 		line_in[i] = '\0';
130 	for (i = 0; i < sizeof(line_in) / 2; i++)
131 	{
132 		char ch;
133 
134 		ch = 0200 + i;
135 		if ('\0' == ch)
136 			ch = '0';
137 		line_in[i] = ch;
138 	}
139 	los = sizeof(line_out) / 2;
140 	obp = quote_unquote(line_in, line_out, los, 0);
141 	if (obp != line_out)
142 		SM_FREE(obp);
143 
144 	for (i = 0; i < sizeof(line_in); i++)
145 		line_in[i] = '\0';
146 	for (i = 0; i < sizeof(line_in) / 2; i++)
147 	{
148 		char ch;
149 
150 		ch = 0200 + i;
151 		if ('\0' == ch)
152 			ch = '0';
153 		line_in[i] = ch;
154 	}
155 	los = sizeof(line_in);
156 	obp = quote_unquote(line_in, line_in, los, 0);
157 	if (obp != line_in)
158 		SM_FREE(obp);
159 
160 	for (i = 0; inout[i].qic_in != NULL; i++)
161 	{
162 		los = sizeof(line_out) / 2;
163 		obp = quote_unquote(inout[i].qic_in, line_out, los,
164 				inout[i].qic_exp);
165 		cmp = strcmp(inout[i].qic_out, obp);
166 		SM_TEST(inout[i].qic_exp == cmp);
167 		if (inout[i].qic_exp != cmp && !SmTestVerbose)
168 		{
169 			char *bp;
170 
171 			bp = str2prt(obp);
172 			fprintf(stderr, "got: %s\n", bp);
173 			bp = str2prt(inout[i].qic_out);
174 			fprintf(stderr, "exp:%s\n", bp);
175 			fprintf(stderr, "cmp=%d\n", cmp);
176 			show_diff(inout[i].qic_in, inout[i].qic_out);
177 		}
178 		if (obp != line_out)
179 			SM_FREE(obp);
180 	}
181 
182 	/* use same buffer for in and out */
183 	for (i = 0; inout[i].qic_in != NULL; i++)
184 	{
185 		bool same;
186 
187 		same = strcmp(inout[i].qic_in, inout[i].qic_out) == 0;
188 		los = sm_strlcpy(line, inout[i].qic_in, sizeof(line));
189 		SM_TEST(los + 1 < sizeof(line));
190 		++los;
191 		obp = quote_unquote(line, line, los, inout[i].qic_exp);
192 		cmp = strcmp(inout[i].qic_out, obp);
193 		SM_TEST(inout[i].qic_exp == cmp);
194 		if (inout[i].qic_exp != cmp && !SmTestVerbose)
195 		{
196 			char *bp;
197 
198 			bp = str2prt(obp);
199 			fprintf(stderr, "got: %s\n", bp);
200 			bp = str2prt(inout[i].qic_out);
201 			fprintf(stderr, "exp:%s\n", bp);
202 			fprintf(stderr, "cmp=%d\n", cmp);
203 			show_diff(inout[i].qic_in, inout[i].qic_out);
204 		}
205 		if (obp != line)
206 		{
207 			SM_TEST(!same);
208 			if (same)
209 				show_diff(obp, inout[i].qic_out);
210 			SM_FREE(obp);
211 		}
212 	}
213 
214 	/* use NULL buffer for out */
215 	for (i = 0; inout[i].qic_in != NULL; i++)
216 	{
217 		los = 0;
218 		obp = quote_unquote(inout[i].qic_in, NULL, los,
219 				inout[i].qic_exp);
220 		SM_TEST(obp != NULL);
221 		cmp = strcmp(inout[i].qic_out, obp);
222 		SM_TEST(inout[i].qic_exp == cmp);
223 		if (inout[i].qic_exp != cmp && !SmTestVerbose)
224 		{
225 			char *bp;
226 
227 			bp = str2prt(obp);
228 			fprintf(stderr, "got: %s\n", bp);
229 			bp = str2prt(inout[i].qic_out);
230 			fprintf(stderr, "exp:%s\n", bp);
231 			fprintf(stderr, "cmp=%d\n", cmp);
232 			show_diff(inout[i].qic_in, inout[i].qic_out);
233 		}
234 	}
235 
236 	return sm_test_end();
237 }
238