agent: Cleanups to prepare implementation of Ed25519.
[gnupg.git] / common / t-stringhelp.c
1 /* t-stringhelp.c - Regression tests for stringhelp.c
2  * Copyright (C) 2007 Free Software Foundation, Inc.
3  *
4  * This file is part of JNLIB, which is a subsystem of GnuPG.
5  *
6  * JNLIB is free software; you can redistribute it and/or modify it
7  * under the terms of either
8  *
9  *   - the GNU Lesser General Public License as published by the Free
10  *     Software Foundation; either version 3 of the License, or (at
11  *     your option) any later version.
12  *
13  * or
14  *
15  *   - the GNU General Public License as published by the Free
16  *     Software Foundation; either version 2 of the License, or (at
17  *     your option) any later version.
18  *
19  * or both in parallel, as here.
20  *
21  * JNLIB is distributed in the hope that it will be useful, but
22  * WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * General Public License for more details.
25  *
26  * You should have received a copies of the GNU General Public License
27  * and the GNU Lesser General Public License along with this program;
28  * if not, see <http://www.gnu.org/licenses/>.
29  */
30
31 #include <config.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <errno.h>
36 #ifdef HAVE_PWD_H
37 # include <pwd.h>
38 #endif
39 #include <unistd.h>
40 #include <sys/types.h>
41
42 #include "stringhelp.h"
43
44 #include "t-support.h"
45
46
47 static char *home_buffer;
48
49
50 const char *
51 gethome (void)
52 {
53   if (!home_buffer)
54     {
55       char *home = getenv("HOME");
56
57       if(home)
58         home_buffer = xstrdup (home);
59 #if defined(HAVE_GETPWUID) && defined(HAVE_PWD_H)
60       else
61         {
62           struct passwd *pwd;
63
64           pwd = getpwuid (getuid());
65           if (pwd)
66             home_buffer = xstrdup (pwd->pw_dir);
67         }
68 #endif
69     }
70   return home_buffer;
71 }
72
73
74 static void
75 test_percent_escape (void)
76 {
77   char *result;
78   static struct {
79     const char *extra;
80     const char *value;
81     const char *expected;
82   } tests[] =
83     {
84       { NULL, "", "" },
85       { NULL, "%", "%25" },
86       { NULL, "%%", "%25%25" },
87       { NULL, " %", " %25" },
88       { NULL, ":", "%3a" },
89       { NULL, " :", " %3a" },
90       { NULL, ": ", "%3a " },
91       { NULL, " : ", " %3a " },
92       { NULL, "::", "%3a%3a" },
93       { NULL, ": :", "%3a %3a" },
94       { NULL, "%:", "%25%3a" },
95       { NULL, ":%", "%3a%25" },
96       { "\\\n:", ":%", "%3a%25" },
97       { "\\\n:", "\\:%", "%5c%3a%25" },
98       { "\\\n:", "\n:%", "%0a%3a%25" },
99       { "\\\n:", "\xff:%", "\xff%3a%25" },
100       { "\\\n:", "\xfe:%", "\xfe%3a%25" },
101       { "\\\n:", "\x01:%", "\x01%3a%25" },
102       { "\x01",  "\x01:%", "%01%3a%25" },
103       { "\xfe",  "\xfe:%", "%fe%3a%25" },
104       { "\xfe",  "\xff:%", "\xff%3a%25" },
105
106       { NULL, NULL, NULL }
107     };
108   int testno;
109
110   result = percent_escape (NULL, NULL);
111   if (result)
112     fail (0);
113   for (testno=0; tests[testno].value; testno++)
114     {
115       result = percent_escape (tests[testno].value, tests[testno].extra);
116       if (!result)
117         fail (testno);
118       if (strcmp (result, tests[testno].expected))
119         fail (testno);
120       xfree (result);
121     }
122
123 }
124
125
126 static void
127 test_compare_filenames (void)
128 {
129   struct {
130     const char *a;
131     const char *b;
132     int result;
133   } tests[] = {
134     { "", "", 0 },
135     { "", "a", -1 },
136     { "a", "", 1 },
137     { "a", "a", 0 },
138     { "a", "aa", -1 },
139     { "aa", "a", 1 },
140     { "a",  "b", -1  },
141
142 #ifdef HAVE_W32_SYSTEM
143     { "a", "A", 0 },
144     { "A", "a", 0 },
145     { "foo/bar", "foo\\bar", 0 },
146     { "foo\\bar", "foo/bar", 0 },
147     { "foo\\", "foo/", 0 },
148     { "foo/", "foo\\", 0 },
149 #endif /*HAVE_W32_SYSTEM*/
150     { NULL, NULL, 0}
151   };
152   int testno, result;
153
154   for (testno=0; tests[testno].a; testno++)
155     {
156       result = compare_filenames (tests[testno].a, tests[testno].b);
157       result = result < 0? -1 : result > 0? 1 : 0;
158       if (result != tests[testno].result)
159         fail (testno);
160     }
161 }
162
163
164 static void
165 test_strconcat (void)
166 {
167   char *out;
168
169   out = strconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
170                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
171                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
172                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
173                    "1", "2", "3", "4", "5", "6", "7", NULL);
174   if (!out)
175     fail (0);
176   else
177     xfree (out);
178   out = strconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
179                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
180                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
181                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
182                    "1", "2", "3", "4", "5", "6", "7", "8", NULL);
183   if (out)
184     fail (0);
185   else if (errno != EINVAL)
186     fail (0);
187
188   out = strconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
189                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
190                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
191                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
192                    "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL);
193   if (out)
194     fail (0);
195   else if (errno != EINVAL)
196     fail (0);
197
198 #if __GNUC__ < 4 /* gcc 4.0 has a sentinel attribute.  */
199   out = strconcat (NULL);
200   if (!out || *out)
201     fail (1);
202 #endif
203   out = strconcat (NULL, NULL);
204   if (!out || *out)
205     fail (1);
206   out = strconcat ("", NULL);
207   if (!out || *out)
208     fail (1);
209   xfree (out);
210
211   out = strconcat ("", "", NULL);
212   if (!out || *out)
213     fail (2);
214   xfree (out);
215
216   out = strconcat ("a", "b", NULL);
217   if (!out || strcmp (out, "ab"))
218     fail (3);
219   xfree (out);
220   out = strconcat ("a", "b", "c", NULL);
221   if (!out || strcmp (out, "abc"))
222     fail (3);
223   xfree (out);
224
225   out = strconcat ("a", "b", "cc", NULL);
226   if (!out || strcmp (out, "abcc"))
227     fail (4);
228   xfree (out);
229   out = strconcat ("a1", "b1", "c1", NULL);
230   if (!out || strcmp (out, "a1b1c1"))
231     fail (4);
232   xfree (out);
233
234   out = strconcat ("", " long b ", "", "--even-longer--", NULL);
235   if (!out || strcmp (out, " long b --even-longer--"))
236     fail (5);
237   xfree (out);
238
239   out = strconcat ("", " long b ", "", "--even-longer--", NULL);
240   if (!out || strcmp (out, " long b --even-longer--"))
241     fail (5);
242   xfree (out);
243 }
244
245 static void
246 test_xstrconcat (void)
247 {
248   char *out;
249
250   out = xstrconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
251                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
252                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
253                    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
254                    "1", "2", "3", "4", "5", "6", "7", NULL);
255   if (!out)
256     fail (0);
257
258 #if __GNUC__ < 4 /* gcc 4.0 has a sentinel attribute.  */
259   out = xstrconcat (NULL);
260   if (!out)
261     fail (1);
262 #endif
263   out = xstrconcat (NULL, NULL);
264   if (!out)
265     fail (1);
266   out = xstrconcat ("", NULL);
267   if (!out || *out)
268     fail (1);
269   xfree (out);
270
271   out = xstrconcat ("", "", NULL);
272   if (!out || *out)
273     fail (2);
274   xfree (out);
275
276   out = xstrconcat ("a", "b", NULL);
277   if (!out || strcmp (out, "ab"))
278     fail (3);
279   xfree (out);
280   out = xstrconcat ("a", "b", "c", NULL);
281   if (!out || strcmp (out, "abc"))
282     fail (3);
283   xfree (out);
284
285   out = xstrconcat ("a", "b", "cc", NULL);
286   if (!out || strcmp (out, "abcc"))
287     fail (4);
288   xfree (out);
289   out = xstrconcat ("a1", "b1", "c1", NULL);
290   if (!out || strcmp (out, "a1b1c1"))
291     fail (4);
292   xfree (out);
293
294   out = xstrconcat ("", " long b ", "", "--even-longer--", NULL);
295   if (!out || strcmp (out, " long b --even-longer--"))
296     fail (5);
297   xfree (out);
298
299   out = xstrconcat ("", " long b ", "", "--even-longer--", NULL);
300   if (!out || strcmp (out, " long b --even-longer--"))
301     fail (5);
302   xfree (out);
303 }
304
305
306 static void
307 test_make_filename_try (void)
308 {
309   char *out;
310   const char *home = gethome ();
311   size_t homelen = home? strlen (home):0;
312
313   out = make_filename_try ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
314                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
315                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
316                            "1", "2", "3", NULL);
317   if (out)
318     fail (0);
319   else if (errno != EINVAL)
320     fail (0);
321   xfree (out);
322   out = make_filename_try ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
323                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
324                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
325                            "1", "2", "3", "4", NULL);
326   if (out)
327     fail (0);
328   else if (errno != EINVAL)
329     fail (0);
330   xfree (out);
331
332   out = make_filename_try ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
333                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
334                            "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
335                            "1", "2", NULL);
336   if (!out || strcmp (out,
337                       "1/2/3/4/5/6/7/8/9/10/"
338                       "1/2/3/4/5/6/7/8/9/10/"
339                       "1/2/3/4/5/6/7/8/9/10/"
340                       "1/2"))
341     fail (0);
342   xfree (out);
343
344   out = make_filename_try ("foo", "~/bar", "baz/cde", NULL);
345   if (!out || strcmp (out, "foo/~/bar/baz/cde"))
346     fail (1);
347   xfree (out);
348
349   out = make_filename_try ("foo", "~/bar", "baz/cde/", NULL);
350   if (!out || strcmp (out, "foo/~/bar/baz/cde/"))
351     fail (1);
352   xfree (out);
353
354   out = make_filename_try ("/foo", "~/bar", "baz/cde/", NULL);
355   if (!out || strcmp (out, "/foo/~/bar/baz/cde/"))
356     fail (1);
357   xfree (out);
358
359   out = make_filename_try ("//foo", "~/bar", "baz/cde/", NULL);
360   if (!out || strcmp (out, "//foo/~/bar/baz/cde/"))
361     fail (1);
362   xfree (out);
363
364   out = make_filename_try ("", "~/bar", "baz/cde", NULL);
365   if (!out || strcmp (out, "/~/bar/baz/cde"))
366     fail (1);
367   xfree (out);
368
369
370   out = make_filename_try ("~/foo", "bar", NULL);
371   if (!out)
372     fail (2);
373   if (home)
374     {
375       if (strlen (out) < homelen + 7)
376         fail (2);
377       if (strncmp (out, home, homelen))
378         fail (2);
379       if (strcmp (out+homelen, "/foo/bar"))
380         fail (2);
381     }
382   else
383     {
384       if (strcmp (out, "~/foo/bar"))
385         fail (2);
386     }
387   xfree (out);
388
389   out = make_filename_try ("~", "bar", NULL);
390   if (!out)
391     fail (2);
392   if (home)
393     {
394       if (strlen (out) < homelen + 3)
395         fail (2);
396       if (strncmp (out, home, homelen))
397         fail (2);
398       if (strcmp (out+homelen, "/bar"))
399         fail (2);
400     }
401   else
402     {
403       if (strcmp (out, "~/bar"))
404         fail (2);
405     }
406   xfree (out);
407 }
408
409
410 int
411 main (int argc, char **argv)
412 {
413   (void)argc;
414   (void)argv;
415
416   test_percent_escape ();
417   test_compare_filenames ();
418   test_strconcat ();
419   test_xstrconcat ();
420   test_make_filename_try ();
421
422   xfree (home_buffer);
423   return 0;
424 }