Line data Source code
1 : /* t-zb32.c - Module tests for zb32.c
2 : * Copyright (C) 2014 Werner Koch
3 : *
4 : * This file is part of GnuPG.
5 : *
6 : * This file is free software; you can redistribute it and/or modify
7 : * it 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 : * This file is distributed in the hope that it will be useful,
22 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 : * GNU General Public License for more details.
25 : *
26 : * You should have received a copy of the GNU General Public License
27 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
28 : */
29 :
30 : #include <config.h>
31 : #include <stdio.h>
32 : #include <stdlib.h>
33 : #include <string.h>
34 : #include <sys/stat.h>
35 : #include <unistd.h>
36 : #include <errno.h>
37 : #ifdef HAVE_DOSISH_SYSTEM
38 : # include <fcntl.h>
39 : #endif
40 :
41 : #include "zb32.h"
42 : #include "t-support.h"
43 :
44 : #define PGM "t-zb32"
45 :
46 : static int verbose;
47 : static int debug;
48 : static int errcount;
49 :
50 :
51 : static void
52 1 : test_zb32enc (void)
53 : {
54 : static struct {
55 : size_t datalen;
56 : char *data;
57 : const char *expected;
58 : } tests[] = {
59 : /* From the DESIGN document. */
60 : { 1, "\x00", "y" },
61 : { 1, "\x80", "o" },
62 : { 2, "\x40", "e" },
63 : { 2, "\xc0", "a" },
64 : { 10, "\x00\x00", "yy" },
65 : { 10, "\x80\x80", "on" },
66 : { 20, "\x8b\x88\x80", "tqre" },
67 : { 24, "\xf0\xbf\xc7", "6n9hq" },
68 : { 24, "\xd4\x7a\x04", "4t7ye" },
69 : /* The next vector is strange: The DESIGN document from 2007 gives
70 : "8ik66o" as result, the revision from 2009 gives "6im5sd". I
71 : look at it for quite some time and came to the conclusion that
72 : "6im54d" is the right encoding. */
73 : { 30, "\xf5\x57\xbd\x0c", "6im54d" },
74 : /* From ccrtp's Java code. */
75 : { 40, "\x01\x01\x01\x01\x01", "yryonyeb" },
76 : { 15, "\x01\x01", "yry" },
77 : { 80, "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01", "yryonyebyryonyeb" },
78 : { 15, "\x81\x81", "ogy" },
79 : { 16, "\x81\x81", "ogyo" },
80 : { 20, "\x81\x81\x81", "ogya" },
81 : { 64, "\x81\x81\x81\x81\x81\x81\x81\x81", "ogyadycbogyan" },
82 : /* More tests. */
83 : { 160, "\x80\x61\x58\x70\xF5\xBA\xD6\x90\x33\x36"
84 : /* */"\x86\xD0\xF2\xAD\x85\xAC\x1E\x42\xB3\x67",
85 : /* */"oboioh8izmmjyc3so5exfmcfioxrfc58" },
86 : { 0, "", "" }
87 : };
88 : int tidx;
89 : char *output;
90 :
91 20 : for (tidx = 0; tidx < DIM(tests); tidx++)
92 : {
93 19 : output = zb32_encode (tests[tidx].data, tests[tidx].datalen);
94 19 : if (!output)
95 : {
96 0 : fprintf (stderr, PGM": error encoding test %d: %s\n",
97 0 : tidx, strerror (errno));
98 0 : exit (1);
99 : }
100 : /* puts (output); */
101 19 : if (strcmp (output, tests[tidx].expected))
102 0 : fail (tidx);
103 19 : xfree (output);
104 : }
105 1 : }
106 :
107 :
108 : /* Read the file FNAME or stdin if FNAME is NULL and return a malloced
109 : buffer with the content. R_LENGTH received the length of the file.
110 : Print a diagnostic and returns NULL on error. */
111 : static char *
112 0 : read_file (const char *fname, size_t *r_length)
113 : {
114 : FILE *fp;
115 : char *buf;
116 : size_t buflen;
117 :
118 0 : if (!fname)
119 : {
120 0 : size_t nread, bufsize = 0;
121 :
122 0 : fp = stdin;
123 : #ifdef HAVE_DOSISH_SYSTEM
124 : setmode (fileno(fp) , O_BINARY );
125 : #endif
126 0 : buf = NULL;
127 0 : buflen = 0;
128 : #define NCHUNK 8192
129 : do
130 : {
131 0 : bufsize += NCHUNK;
132 0 : if (!buf)
133 0 : buf = xmalloc (bufsize);
134 : else
135 0 : buf = xrealloc (buf, bufsize);
136 :
137 0 : nread = fread (buf+buflen, 1, NCHUNK, fp);
138 0 : if (nread < NCHUNK && ferror (fp))
139 : {
140 0 : fprintf (stderr, PGM": error reading '[stdin]': %s\n",
141 0 : strerror (errno));
142 0 : xfree (buf);
143 0 : return NULL;
144 : }
145 0 : buflen += nread;
146 : }
147 0 : while (nread == NCHUNK);
148 : #undef NCHUNK
149 :
150 : }
151 : else
152 : {
153 : struct stat st;
154 :
155 0 : fp = fopen (fname, "rb");
156 0 : if (!fp)
157 : {
158 0 : fprintf (stderr, PGM": can't open '%s': %s\n",
159 0 : fname, strerror (errno));
160 0 : return NULL;
161 : }
162 :
163 0 : if (fstat (fileno(fp), &st))
164 : {
165 0 : fprintf (stderr, PGM": can't stat '%s': %s\n",
166 0 : fname, strerror (errno));
167 0 : fclose (fp);
168 0 : return NULL;
169 : }
170 :
171 0 : buflen = st.st_size;
172 0 : buf = xmalloc (buflen+1);
173 0 : if (fread (buf, buflen, 1, fp) != 1)
174 : {
175 0 : fprintf (stderr, PGM": error reading '%s': %s\n",
176 0 : fname, strerror (errno));
177 0 : fclose (fp);
178 0 : xfree (buf);
179 0 : return NULL;
180 : }
181 0 : fclose (fp);
182 : }
183 :
184 0 : *r_length = buflen;
185 0 : return buf;
186 : }
187 :
188 :
189 : /* Debug helper to encode or decode to/from zb32. */
190 : static void
191 0 : endecode_file (const char *fname, int decode)
192 : {
193 : char *buffer;
194 : size_t buflen;
195 : char *result;
196 :
197 0 : if (decode)
198 : {
199 0 : fprintf (stderr, PGM": decode mode has not yet been implemented\n");
200 0 : errcount++;
201 0 : return;
202 : }
203 :
204 : #ifdef HAVE_DOSISH_SYSTEM
205 : if (decode)
206 : setmode (fileno (stdout), O_BINARY);
207 : #endif
208 :
209 :
210 0 : buffer = read_file (fname, &buflen);
211 0 : if (!buffer)
212 : {
213 0 : errcount++;
214 0 : return;
215 : }
216 :
217 0 : result = zb32_encode (buffer, 8 * buflen);
218 0 : if (!result)
219 : {
220 0 : fprintf (stderr, PGM": error encoding data: %s\n", strerror (errno));
221 0 : errcount++;
222 0 : xfree (buffer);
223 0 : return;
224 : }
225 :
226 0 : fputs (result, stdout);
227 0 : putchar ('\n');
228 :
229 0 : xfree (result);
230 0 : xfree (buffer);
231 : }
232 :
233 :
234 : int
235 1 : main (int argc, char **argv)
236 : {
237 1 : int last_argc = -1;
238 1 : int opt_endecode = 0;
239 :
240 1 : no_exit_on_fail = 1;
241 :
242 1 : if (argc)
243 1 : { argc--; argv++; }
244 2 : while (argc && last_argc != argc )
245 : {
246 0 : last_argc = argc;
247 0 : if (!strcmp (*argv, "--"))
248 : {
249 0 : argc--; argv++;
250 0 : break;
251 : }
252 0 : else if (!strcmp (*argv, "--help"))
253 : {
254 0 : fputs ("usage: " PGM " [FILE]\n"
255 : "Options:\n"
256 : " --verbose Print timings etc.\n"
257 : " --debug Flyswatter\n"
258 : " --encode Encode FILE or stdin\n"
259 : " --decode Decode FILE or stdin\n"
260 : , stdout);
261 0 : exit (0);
262 : }
263 0 : else if (!strcmp (*argv, "--verbose"))
264 : {
265 0 : verbose++;
266 0 : argc--; argv++;
267 : }
268 0 : else if (!strcmp (*argv, "--debug"))
269 : {
270 0 : verbose += 2;
271 0 : debug++;
272 0 : argc--; argv++;
273 : }
274 0 : else if (!strcmp (*argv, "--encode"))
275 : {
276 0 : opt_endecode = 1;
277 0 : argc--; argv++;
278 : }
279 0 : else if (!strcmp (*argv, "--decode"))
280 : {
281 0 : opt_endecode = -1;
282 0 : argc--; argv++;
283 : }
284 0 : else if (!strncmp (*argv, "--", 2))
285 : {
286 0 : fprintf (stderr, PGM ": unknown option '%s'\n", *argv);
287 0 : exit (1);
288 : }
289 : }
290 :
291 1 : if (argc > 1)
292 : {
293 0 : fprintf (stderr, PGM ": to many arguments given\n");
294 0 : exit (1);
295 : }
296 :
297 1 : if (opt_endecode)
298 : {
299 0 : endecode_file (argc? *argv : NULL, (opt_endecode < 0));
300 : }
301 : else
302 1 : test_zb32enc ();
303 :
304 1 : return !!errcount;
305 : }
|