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