]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/sendmail/libsm/t-qic.c
Merge commit '850ef5ae11d69ea3381bd310f564f025fc8caea3'
[FreeBSD/FreeBSD.git] / contrib / sendmail / libsm / t-qic.c
1 /*
2  * Copyright (c) 2006, 2023 Proofpoint, 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 #include <sm/gen.h>
11 SM_IDSTR(id, "@(#)$Id: t-qic.c,v 1.10 2013-11-22 20:51:43 ca Exp $")
12
13 #include <stdio.h>
14 #include <sm/sendmail.h>
15 #include <sm/assert.h>
16 #include <sm/heap.h>
17 #include <sm/string.h>
18 #include <sm/test.h>
19
20 extern bool SmTestVerbose;
21
22 void
23 show_diff(s1, s2)
24         const char *s1;
25         const char *s2;
26 {
27         int i;
28
29         for (i = 0; s1[i] != '\0' && s2[i] != '\0'; i++)
30         {
31                 if (s1[i] != s2[i])
32                 {
33                         fprintf(stderr, "i=%d, s1[]=%u, s2[]=%u\n",
34                                 i, (unsigned char) s1[i],
35                                 (unsigned char) s2[i]);
36                         return;
37                 }
38         }
39         if (s1[i] != s2[i])
40         {
41                 fprintf(stderr, "i=%d, s1[]=%u, s2[]=%u\n",
42                         i, (unsigned char) s1[i], (unsigned char) s2[i]);
43         }
44 }
45
46 char *quote_unquote __P((char *, char *, int, int, int));
47
48 char *
49 quote_unquote(in, out, outlen, exp, mode)
50         char *in;
51         char *out;
52         int outlen;
53         int exp;
54         int mode;
55 {
56         char *obp, *bp;
57         char line_back[1024];
58         char line_in[1024];
59         int cmp;
60
61         sm_strlcpy(line_in, in, sizeof(line_in));
62         obp = quote_internal_chars(in, out, &outlen, NULL);
63         bp = str2prt(line_in);
64         if (0 == mode)
65                 dequote_internal_chars(obp, line_back, sizeof(line_back));
66         else if (1 == mode)
67                 dequote_internal_chars(obp, line_back, strlen(obp));
68         else if (2 == mode)
69                 dequote_internal_chars(obp, line_back, strlen(obp) + 1);
70         cmp = strcmp(line_in, line_back);
71         SM_TEST(exp == cmp);
72         if (cmp != exp && !SmTestVerbose)
73         {
74                 fprintf(stderr, "in: %s\n", bp);
75                 bp = str2prt(line_back);
76                 fprintf(stderr, "out:%s\n", bp);
77                 fprintf(stderr, "cmp=%d\n", cmp);
78                 show_diff(in, line_back);
79         }
80         if (SmTestVerbose)
81         {
82                 fprintf(stderr, "%s -> ", bp);
83                 bp = str2prt(obp);
84                 fprintf(stderr, "%s\n", bp);
85                 fprintf(stderr, "cmp=%d\n", cmp);
86         }
87         return obp;
88 }
89
90 struct sm_qic_S
91 {
92         char            *qic_in;
93         char            *qic_out;
94         int              qic_exp;
95 };
96
97 typedef struct sm_qic_S sm_qic_T;
98
99
100 int
101 main(argc, argv)
102         int argc;
103         char *argv[];
104 {
105         char line_in[1024], line[256], line_out[32], *obp;
106         int i, los, cmp, mode;
107         sm_qic_T inout[] = {
108                   { "", "",     0 }
109                 , { "\t", "\t", 0 }
110                 , { "\tuser", "\tuser", 0 }
111                 , { "abcdef", "abcdef", 0 }
112                 , { "01234567890123456789", "01234567890123456789",     0 }
113                 , { "\\", "\\", 0 }
114                 , { "\\A", "\\A",       0 }
115                 , { "01234567890123456789\001", "01234567890123456789\001",
116                         0 }
117                 , { "012345\2067890123456789", "012345\377\2067890123456789",
118                         0 }
119                 , { "\377", "\377\377", 0 }
120                 , { "\240", "\240",     0 }
121                 , { "\220", "\377\220", 0 }
122                 , { "\240\220", "\240\377\220", 0 }
123                 , { "\377\377", "\377\377\377\377",     0 }
124                 , { "\377a\377b", "\377\377a\377\377b", 0 }
125                 , { "\376a\377b", "\376a\377\377b",     0 }
126                 , { "\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",
127                     "\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",
128                         0 }
129                 , { NULL, NULL, 0 }
130         };
131
132         sm_test_begin(argc, argv, "test meta quoting");
133         mode = 0;
134         if (argc > 1)
135                 mode = atoi(argv[1]);
136         for (i = 0; i < sizeof(line_out); i++)
137                 line_out[i] = '\0';
138         for (i = 0; i < sizeof(line_in); i++)
139                 line_in[i] = '\0';
140         for (i = 0; i < sizeof(line_in) / 2; i++)
141         {
142                 char ch;
143
144                 ch = 0200 + i;
145                 if ('\0' == ch)
146                         ch = '0';
147                 line_in[i] = ch;
148         }
149         los = sizeof(line_out) / 2;
150         obp = quote_unquote(line_in, line_out, los, 0, mode);
151         if (obp != line_out)
152                 SM_FREE(obp);
153
154         for (i = 0; i < sizeof(line_in); i++)
155                 line_in[i] = '\0';
156         for (i = 0; i < sizeof(line_in) / 2; i++)
157         {
158                 char ch;
159
160                 ch = 0200 + i;
161                 if ('\0' == ch)
162                         ch = '0';
163                 line_in[i] = ch;
164         }
165         los = sizeof(line_in);
166         obp = quote_unquote(line_in, line_in, los, 0, mode);
167         if (obp != line_in)
168                 SM_FREE(obp);
169
170         for (i = 0; inout[i].qic_in != NULL; i++)
171         {
172                 los = sizeof(line_out) / 2;
173                 obp = quote_unquote(inout[i].qic_in, line_out, los,
174                                 inout[i].qic_exp, mode);
175                 cmp = strcmp(inout[i].qic_out, obp);
176                 SM_TEST(inout[i].qic_exp == cmp);
177                 if (inout[i].qic_exp != cmp && !SmTestVerbose)
178                 {
179                         char *bp;
180
181                         bp = str2prt(obp);
182                         fprintf(stderr, "got: %s\n", bp);
183                         bp = str2prt(inout[i].qic_out);
184                         fprintf(stderr, "exp:%s\n", bp);
185                         fprintf(stderr, "cmp=%d\n", cmp);
186                         show_diff(inout[i].qic_in, inout[i].qic_out);
187                 }
188                 if (obp != line_out)
189                         SM_FREE(obp);
190         }
191
192         /* use same buffer for in and out */
193         for (i = 0; inout[i].qic_in != NULL; i++)
194         {
195                 bool same;
196
197                 same = strcmp(inout[i].qic_in, inout[i].qic_out) == 0;
198                 los = sm_strlcpy(line, inout[i].qic_in, sizeof(line));
199                 SM_TEST(los + 1 < sizeof(line));
200                 ++los;
201                 obp = quote_unquote(line, line, los, inout[i].qic_exp, mode);
202                 cmp = strcmp(inout[i].qic_out, obp);
203                 SM_TEST(inout[i].qic_exp == cmp);
204                 if (inout[i].qic_exp != cmp && !SmTestVerbose)
205                 {
206                         char *bp;
207
208                         bp = str2prt(obp);
209                         fprintf(stderr, "got: %s\n", bp);
210                         bp = str2prt(inout[i].qic_out);
211                         fprintf(stderr, "exp:%s\n", bp);
212                         fprintf(stderr, "cmp=%d\n", cmp);
213                         show_diff(inout[i].qic_in, inout[i].qic_out);
214                 }
215                 if (obp != line)
216                 {
217                         SM_TEST(!same);
218                         if (same)
219                                 show_diff(obp, inout[i].qic_out);
220                         SM_FREE(obp);
221                 }
222         }
223
224         /* use NULL buffer for out */
225         for (i = 0; inout[i].qic_in != NULL; i++)
226         {
227                 los = 0;
228                 obp = quote_unquote(inout[i].qic_in, NULL, los,
229                                 inout[i].qic_exp, mode);
230                 SM_TEST(obp != NULL);
231                 cmp = strcmp(inout[i].qic_out, obp);
232                 SM_TEST(inout[i].qic_exp == cmp);
233                 if (inout[i].qic_exp != cmp && !SmTestVerbose)
234                 {
235                         char *bp;
236
237                         bp = str2prt(obp);
238                         fprintf(stderr, "got: %s\n", bp);
239                         bp = str2prt(inout[i].qic_out);
240                         fprintf(stderr, "exp:%s\n", bp);
241                         fprintf(stderr, "cmp=%d\n", cmp);
242                         show_diff(inout[i].qic_in, inout[i].qic_out);
243                 }
244         }
245
246         los = -1;
247         obp = quote_internal_chars(NULL, NULL, &los, NULL);
248         SM_TEST(NULL == obp);
249         SM_TEST(-1 == los);
250
251         sm_strlcpy(line_in, "nothing", sizeof(line_in));
252         los = -123;
253         obp = quote_internal_chars(line_in, NULL, &los, NULL);
254         SM_TEST(NULL != obp);
255         SM_TEST(los > 0);
256
257         return sm_test_end();
258 }