blob: dd19013feeee2b6fd408a1de948f4146aef53af7 [file] [log] [blame]
Lev Walkin1e609cf2004-09-27 20:50:48 +00001#undef NDEBUG
2#include <stdio.h>
3#include <stdlib.h>
4#include <sys/types.h>
5#include <unistd.h> /* for chdir(2) */
6#include <string.h>
7#include <dirent.h>
8#include <assert.h>
9#include <errno.h>
10
11#include <T.h>
12
13enum expectation {
14 EXP_OK, /* Encoding/decoding must succeed */
15 EXP_BROKEN, /* Decoding must fail */
16 EXP_RECLESS, /* Reconstruction is allowed to yield less data */
Lev Walkinc5364602004-10-05 06:38:38 +000017 EXP_DIFFERENT, /* Reconstruction will yield different encoding */
Lev Walkin1e609cf2004-09-27 20:50:48 +000018};
19
20static unsigned char buf[4096];
21static int buf_offset;
22
23static int
24_buf_writer(const void *buffer, size_t size, void *app_key) {
25 unsigned char *b, *bend;
26 (void)app_key;
27 assert(buf_offset + size < sizeof(buf));
28 memcpy(buf + buf_offset, buffer, size);
29 b = buf + buf_offset;
30 bend = b + size;
31 printf("=> [");
32 for(; b < bend; b++)
33 printf(" %02X", *b);
34 printf("]:%ld\n", (long)size);
35 buf_offset += size;
36 return 0;
37}
38
39static int
40save_object(T_t *st) {
41 asn_enc_rval_t rval; /* Return value */
42
43 buf_offset = 0;
44
Lev Walkinc7400c52004-09-29 13:14:36 +000045 rval = der_encode(&asn_DEF_T, st, _buf_writer, 0);
Lev Walkin1e609cf2004-09-27 20:50:48 +000046 if (rval.encoded == -1) {
47 fprintf(stderr,
48 "Cannot encode %s: %s\n",
49 rval.failed_type->name, strerror(errno));
50 assert(rval.encoded != -1);
51 return -1; /* JIC */
52 }
53
54 fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset);
55
56 return 0;
57}
58
59static T_t *
60load_object(enum expectation expectation, char *fbuf, int size) {
61 ber_dec_rval_t rval;
62 T_t *st = 0;
63 int csize;
64
65 fprintf(stderr, "LOADING OBJECT OF SIZE %d\n", size);
66
67 /* Perform multiple iterations with multiple chunks sizes */
68 for(csize = 1; csize < 20; csize += 1) {
69 int fbuf_offset = 0;
70 int fbuf_left = size;
71 int fbuf_chunk = csize;
72
Lev Walkinc7400c52004-09-29 13:14:36 +000073 if(st) asn_DEF_T.free_struct(&asn_DEF_T, st, 0);
Lev Walkin1e609cf2004-09-27 20:50:48 +000074 st = 0;
75
76 do {
77 fprintf(stderr, "Decoding from %d with %d (left %d)\n",
78 fbuf_offset, fbuf_chunk, fbuf_left);
Lev Walkinc7400c52004-09-29 13:14:36 +000079 rval = ber_decode(0, &asn_DEF_T, (void **)&st,
Lev Walkin1e609cf2004-09-27 20:50:48 +000080 fbuf + fbuf_offset,
81 fbuf_chunk < fbuf_left
82 ? fbuf_chunk : fbuf_left);
83 fbuf_offset += rval.consumed;
84 fbuf_left -= rval.consumed;
85 if(rval.code == RC_WMORE)
86 fbuf_chunk += 1; /* Give little more */
87 else
88 fbuf_chunk = csize; /* Back off */
89 } while(fbuf_left && rval.code == RC_WMORE);
90
91 if(expectation != EXP_BROKEN) {
92 assert(rval.code == RC_OK);
Lev Walkin75c344b2004-09-29 14:29:05 +000093 assert(fbuf_offset == size);
Lev Walkin1e609cf2004-09-27 20:50:48 +000094 } else {
95 assert(rval.code != RC_OK);
96 fprintf(stderr, "Failed, but this was expected\n");
Lev Walkinc7400c52004-09-29 13:14:36 +000097 asn_DEF_T.free_struct(&asn_DEF_T, st, 0);
Lev Walkin1e609cf2004-09-27 20:50:48 +000098 st = 0; /* ignore leak for now */
99 }
100 }
101
Lev Walkinc7400c52004-09-29 13:14:36 +0000102 if(st) asn_fprint(stderr, &asn_DEF_T, st);
Lev Walkin1e609cf2004-09-27 20:50:48 +0000103 return st;
104}
105
106
107static void
108process_data(enum expectation expectation, char *fbuf, int size) {
109 T_t *st;
110 int ret;
111
112 st = load_object(expectation, fbuf, size);
113 if(!st) return;
114
115 ret = save_object(st);
116 assert(buf_offset < sizeof(buf));
117 assert(ret == 0);
118
Lev Walkinc5364602004-10-05 06:38:38 +0000119 switch(expectation) {
120 case EXP_RECLESS:
Lev Walkin1e609cf2004-09-27 20:50:48 +0000121 assert(buf_offset > 0 && buf_offset < size);
122 assert(memcmp(buf + 2, fbuf + 2, buf_offset - 2) == 0);
Lev Walkinc5364602004-10-05 06:38:38 +0000123 break;
124 case EXP_DIFFERENT:
125 assert(buf_offset > 0 && buf_offset < size);
126 break;
127 case EXP_BROKEN:
Lev Walkin1e609cf2004-09-27 20:50:48 +0000128 assert(buf_offset == size);
129 assert(memcmp(buf, fbuf, buf_offset) == 0);
Lev Walkinc5364602004-10-05 06:38:38 +0000130 break;
Lev Walkin1e609cf2004-09-27 20:50:48 +0000131 }
132
Lev Walkinc7400c52004-09-29 13:14:36 +0000133 asn_DEF_T.free_struct(&asn_DEF_T, st, 0);
Lev Walkin1e609cf2004-09-27 20:50:48 +0000134}
135
136/*
137 * Decode the .der files and try to regenerate them.
138 */
139static int
140process(const char *fname) {
141 char fbuf[4096];
142 char *ext = strrchr(fname, '.');
143 enum expectation expectation;
144 int ret;
145 int rd;
146 FILE *fp;
147
148 if(ext == 0 || strcmp(ext, ".ber"))
149 return 0;
150
151 switch(ext[-1]) {
152 case 'B': /* The file is intentionally broken */
153 expectation = EXP_BROKEN; break;
Lev Walkinc5364602004-10-05 06:38:38 +0000154 case 'D': /* Reconstructing should yield different data */
155 expectation = EXP_DIFFERENT; break;
Lev Walkin1e609cf2004-09-27 20:50:48 +0000156 case 'L': /* Extensions are present */
157 expectation = EXP_RECLESS; break;
158 default:
159 expectation = EXP_OK; break;
160 }
161
162 fprintf(stderr, "\nProcessing file [../%s]\n", fname);
163
164 ret = chdir("../data-62");
165 assert(ret == 0);
166 fp = fopen(fname, "r");
167 ret = chdir("../test-check-62");
168 assert(ret == 0);
169 assert(fp);
170
171 rd = fread(fbuf, 1, sizeof(fbuf), fp);
172 fclose(fp);
173
174 assert(rd < sizeof(fbuf)); /* expect small files */
175
176 process_data(expectation, fbuf, rd);
177
178 return 1;
179}
180
181int
182main() {
183 DIR *dir;
184 struct dirent *dent;
185 int processed_files = 0;
Lev Walkinc5364602004-10-05 06:38:38 +0000186 char *str;
Lev Walkin1e609cf2004-09-27 20:50:48 +0000187
188 dir = opendir("../data-62");
189 assert(dir);
190
Lev Walkinc5364602004-10-05 06:38:38 +0000191 str = getenv("DATA_62_FILE");
192 if(str && strncmp(str, "data-62-", 8) == 0)
193 process(str);
Lev Walkin1e609cf2004-09-27 20:50:48 +0000194
Lev Walkinc5364602004-10-05 06:38:38 +0000195 while((dent = readdir(dir))) {
196 if(strncmp(dent->d_name, "data-62-", 8) == 0)
197 if(process(dent->d_name))
198 processed_files++;
Lev Walkin1e609cf2004-09-27 20:50:48 +0000199 }
200
201 assert(processed_files);
202 closedir(dir);
203
204 return 0;
205}
206