1168515Sgshapiro/*
2261363Sgshapiro * Copyright (c) 2006 Proofpoint, Inc. and its suppliers.
3168515Sgshapiro *	All rights reserved.
4168515Sgshapiro *
5168515Sgshapiro * By using this file, you agree to the terms and conditions set
6168515Sgshapiro * forth in the LICENSE file which can be found at the top level of
7168515Sgshapiro * the sendmail distribution.
8168515Sgshapiro */
9168515Sgshapiro
10168515Sgshapiro#include <sm/gen.h>
11266692SgshapiroSM_IDSTR(id, "@(#)$Id: t-qic.c,v 1.10 2013-11-22 20:51:43 ca Exp $")
12168515Sgshapiro
13168515Sgshapiro#include <stdio.h>
14168515Sgshapiro#include <sm/sendmail.h>
15168515Sgshapiro#include <sm/assert.h>
16168515Sgshapiro#include <sm/heap.h>
17168515Sgshapiro#include <sm/string.h>
18168515Sgshapiro#include <sm/test.h>
19168515Sgshapiro
20168515Sgshapiroextern bool SmTestVerbose;
21168515Sgshapiro
22168515Sgshapiro
23168515Sgshapirovoid
24168515Sgshapiroshow_diff(s1, s2)
25168515Sgshapiro	const char *s1;
26168515Sgshapiro	const char *s2;
27168515Sgshapiro{
28168515Sgshapiro	int i;
29168515Sgshapiro
30168515Sgshapiro	for (i = 0; s1[i] != '\0' && s2[i] != '\0'; i++)
31168515Sgshapiro	{
32168515Sgshapiro		if (s1[i] != s2[i])
33168515Sgshapiro		{
34168515Sgshapiro			fprintf(stderr, "i=%d, s1[]=%u, s2[]=%u\n",
35168515Sgshapiro				i, (unsigned char) s1[i],
36168515Sgshapiro				(unsigned char) s2[i]);
37168515Sgshapiro			return;
38168515Sgshapiro		}
39168515Sgshapiro	}
40168515Sgshapiro	if (s1[i] != s2[i])
41168515Sgshapiro	{
42168515Sgshapiro		fprintf(stderr, "i=%d, s1[]=%u, s2[]=%u\n",
43168515Sgshapiro			i, (unsigned char) s1[i], (unsigned char) s2[i]);
44168515Sgshapiro	}
45168515Sgshapiro}
46168515Sgshapiro
47168515Sgshapirochar *quote_unquote __P((char *, char *, int, int));
48168515Sgshapiro
49168515Sgshapirochar *
50168515Sgshapiroquote_unquote(in, out, outlen, exp)
51168515Sgshapiro	char *in;
52168515Sgshapiro	char *out;
53168515Sgshapiro	int outlen;
54168515Sgshapiro	int exp;
55168515Sgshapiro{
56168515Sgshapiro	char *obp, *bp;
57168515Sgshapiro	char line_back[1024];
58168515Sgshapiro	char line_in[1024];
59168515Sgshapiro	int cmp;
60168515Sgshapiro
61168515Sgshapiro	sm_strlcpy(line_in, in, sizeof(line_in));
62168515Sgshapiro	obp = quote_internal_chars(in, out, &outlen);
63168515Sgshapiro	bp = str2prt(line_in);
64168515Sgshapiro	dequote_internal_chars(obp, line_back, sizeof(line_back));
65168515Sgshapiro	cmp = strcmp(line_in, line_back);
66168515Sgshapiro	SM_TEST(exp == cmp);
67168515Sgshapiro	if (cmp != exp && !SmTestVerbose)
68168515Sgshapiro	{
69168515Sgshapiro		fprintf(stderr, "in: %s\n", bp);
70168515Sgshapiro		bp = str2prt(line_back);
71168515Sgshapiro		fprintf(stderr, "out:%s\n", bp);
72168515Sgshapiro		fprintf(stderr, "cmp=%d\n", cmp);
73168515Sgshapiro		show_diff(in, line_back);
74168515Sgshapiro	}
75168515Sgshapiro	if (SmTestVerbose)
76168515Sgshapiro	{
77168515Sgshapiro		fprintf(stderr, "%s -> ", bp);
78168515Sgshapiro		bp = str2prt(obp);
79168515Sgshapiro		fprintf(stderr, "%s\n", bp);
80168515Sgshapiro		fprintf(stderr, "cmp=%d\n", cmp);
81168515Sgshapiro	}
82168515Sgshapiro	return obp;
83168515Sgshapiro}
84168515Sgshapiro
85168515Sgshapirostruct sm_qic_S
86168515Sgshapiro{
87168515Sgshapiro	char		*qic_in;
88168515Sgshapiro	char		*qic_out;
89168515Sgshapiro	int		 qic_exp;
90168515Sgshapiro};
91168515Sgshapiro
92168515Sgshapirotypedef struct sm_qic_S sm_qic_T;
93168515Sgshapiro
94168515Sgshapiro
95168515Sgshapiroint
96168515Sgshapiromain(argc, argv)
97168515Sgshapiro	int argc;
98168515Sgshapiro	char *argv[];
99168515Sgshapiro{
100168515Sgshapiro	char line_in[1024], line[256], line_out[32], *obp;
101168515Sgshapiro	int i, los, cmp;
102168515Sgshapiro	sm_qic_T inout[] = {
103168515Sgshapiro		  { "", "",	0 }
104168515Sgshapiro		, { "abcdef", "abcdef",	0 }
105168515Sgshapiro		, { "01234567890123456789", "01234567890123456789",	0 }
106168515Sgshapiro		, { "01234567890123456789\001", "01234567890123456789\001",
107168515Sgshapiro			0 }
108168515Sgshapiro		, { "012345\2067890123456789", "012345\377\2067890123456789",
109168515Sgshapiro			0 }
110168515Sgshapiro		, { "\377", "\377\377",	0 }
111168515Sgshapiro		, { "\240", "\240",	0 }
112168515Sgshapiro		, { "\220", "\377\220",	0 }
113168515Sgshapiro		, { "\240\220", "\240\377\220",	0 }
114168515Sgshapiro		, { "\377\377", "\377\377\377\377",	0 }
115168515Sgshapiro		, { "\377a\377b", "\377\377a\377\377b",	0 }
116168515Sgshapiro		, { "\376a\377b", "\376a\377\377b",	0 }
117168515Sgshapiro		, { "\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",
118168515Sgshapiro		    "\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",
119168515Sgshapiro			0 }
120168515Sgshapiro		, { NULL, NULL,	0 }
121168515Sgshapiro	};
122168515Sgshapiro
123168515Sgshapiro	sm_test_begin(argc, argv, "test meta quoting");
124168515Sgshapiro	for (i = 0; i < sizeof(line_out); i++)
125168515Sgshapiro		line_out[i] = '\0';
126168515Sgshapiro	for (i = 0; i < sizeof(line_in); i++)
127168515Sgshapiro		line_in[i] = '\0';
128168515Sgshapiro	for (i = 0; i < sizeof(line_in) / 2; i++)
129168515Sgshapiro	{
130168515Sgshapiro		char ch;
131168515Sgshapiro
132168515Sgshapiro		ch = 0200 + i;
133168515Sgshapiro		if ('\0' == ch)
134168515Sgshapiro			ch = '0';
135168515Sgshapiro		line_in[i] = ch;
136168515Sgshapiro	}
137168515Sgshapiro	los = sizeof(line_out) / 2;
138168515Sgshapiro	obp = quote_unquote(line_in, line_out, los, 0);
139168515Sgshapiro	if (obp != line_out)
140168515Sgshapiro		SM_FREE(obp);
141168515Sgshapiro
142168515Sgshapiro	for (i = 0; i < sizeof(line_in); i++)
143168515Sgshapiro		line_in[i] = '\0';
144168515Sgshapiro	for (i = 0; i < sizeof(line_in) / 2; i++)
145168515Sgshapiro	{
146168515Sgshapiro		char ch;
147168515Sgshapiro
148168515Sgshapiro		ch = 0200 + i;
149168515Sgshapiro		if ('\0' == ch)
150168515Sgshapiro			ch = '0';
151168515Sgshapiro		line_in[i] = ch;
152168515Sgshapiro	}
153168515Sgshapiro	los = sizeof(line_in);
154168515Sgshapiro	obp = quote_unquote(line_in, line_in, los, 0);
155168515Sgshapiro	if (obp != line_in)
156168515Sgshapiro		SM_FREE(obp);
157168515Sgshapiro
158168515Sgshapiro	for (i = 0; inout[i].qic_in != NULL; i++)
159168515Sgshapiro	{
160168515Sgshapiro		los = sizeof(line_out) / 2;
161168515Sgshapiro		obp = quote_unquote(inout[i].qic_in, line_out, los,
162168515Sgshapiro				inout[i].qic_exp);
163168515Sgshapiro		cmp = strcmp(inout[i].qic_out, obp);
164168515Sgshapiro		SM_TEST(inout[i].qic_exp == cmp);
165168515Sgshapiro		if (inout[i].qic_exp != cmp && !SmTestVerbose)
166168515Sgshapiro		{
167168515Sgshapiro			char *bp;
168168515Sgshapiro
169168515Sgshapiro			bp = str2prt(obp);
170168515Sgshapiro			fprintf(stderr, "got: %s\n", bp);
171168515Sgshapiro			bp = str2prt(inout[i].qic_out);
172168515Sgshapiro			fprintf(stderr, "exp:%s\n", bp);
173168515Sgshapiro			fprintf(stderr, "cmp=%d\n", cmp);
174168515Sgshapiro			show_diff(inout[i].qic_in, inout[i].qic_out);
175168515Sgshapiro		}
176168515Sgshapiro		if (obp != line_out)
177168515Sgshapiro			SM_FREE(obp);
178168515Sgshapiro	}
179168515Sgshapiro
180168515Sgshapiro	/* use same buffer for in and out */
181168515Sgshapiro	for (i = 0; inout[i].qic_in != NULL; i++)
182168515Sgshapiro	{
183168515Sgshapiro		bool same;
184168515Sgshapiro
185168515Sgshapiro		same = strcmp(inout[i].qic_in, inout[i].qic_out) == 0;
186168515Sgshapiro		los = sm_strlcpy(line, inout[i].qic_in, sizeof(line));
187168515Sgshapiro		SM_TEST(los + 1 < sizeof(line));
188168515Sgshapiro		++los;
189168515Sgshapiro		obp = quote_unquote(line, line, los, inout[i].qic_exp);
190168515Sgshapiro		cmp = strcmp(inout[i].qic_out, obp);
191168515Sgshapiro		SM_TEST(inout[i].qic_exp == cmp);
192168515Sgshapiro		if (inout[i].qic_exp != cmp && !SmTestVerbose)
193168515Sgshapiro		{
194168515Sgshapiro			char *bp;
195168515Sgshapiro
196168515Sgshapiro			bp = str2prt(obp);
197168515Sgshapiro			fprintf(stderr, "got: %s\n", bp);
198168515Sgshapiro			bp = str2prt(inout[i].qic_out);
199168515Sgshapiro			fprintf(stderr, "exp:%s\n", bp);
200168515Sgshapiro			fprintf(stderr, "cmp=%d\n", cmp);
201168515Sgshapiro			show_diff(inout[i].qic_in, inout[i].qic_out);
202168515Sgshapiro		}
203168515Sgshapiro		if (obp != line)
204168515Sgshapiro		{
205168515Sgshapiro			SM_TEST(!same);
206168515Sgshapiro			if (same)
207168515Sgshapiro				show_diff(obp, inout[i].qic_out);
208168515Sgshapiro			SM_FREE(obp);
209168515Sgshapiro		}
210168515Sgshapiro	}
211168515Sgshapiro
212168515Sgshapiro	/* use NULL buffer for out */
213168515Sgshapiro	for (i = 0; inout[i].qic_in != NULL; i++)
214168515Sgshapiro	{
215168515Sgshapiro		los = 0;
216168515Sgshapiro		obp = quote_unquote(inout[i].qic_in, NULL, los,
217168515Sgshapiro				inout[i].qic_exp);
218168515Sgshapiro		SM_TEST(obp != NULL);
219168515Sgshapiro		cmp = strcmp(inout[i].qic_out, obp);
220168515Sgshapiro		SM_TEST(inout[i].qic_exp == cmp);
221168515Sgshapiro		if (inout[i].qic_exp != cmp && !SmTestVerbose)
222168515Sgshapiro		{
223168515Sgshapiro			char *bp;
224168515Sgshapiro
225168515Sgshapiro			bp = str2prt(obp);
226168515Sgshapiro			fprintf(stderr, "got: %s\n", bp);
227168515Sgshapiro			bp = str2prt(inout[i].qic_out);
228168515Sgshapiro			fprintf(stderr, "exp:%s\n", bp);
229168515Sgshapiro			fprintf(stderr, "cmp=%d\n", cmp);
230168515Sgshapiro			show_diff(inout[i].qic_in, inout[i].qic_out);
231168515Sgshapiro		}
232168515Sgshapiro	}
233168515Sgshapiro
234168515Sgshapiro	return sm_test_end();
235168515Sgshapiro}
236