5 #include <unistd.h> /* for chdir(2), getcwd(3) */
16 #define STRINGIFY_MACRO2(x) #x
17 #define STRINGIFY_MACRO(x) STRINGIFY_MACRO2(x)
18 #define SRCDIR_S STRINGIFY_MACRO(SRCDIR)
22 EXP_OK, /* Encoding/decoding must succeed */
23 EXP_BROKEN, /* Decoding must fail */
24 EXP_RECLESS, /* Reconstruction is allowed to yield less data */
25 EXP_DIFFERENT, /* Reconstruction will yield different encoding */
28 static unsigned char buf[4096];
29 static int buf_offset;
32 _buf_writer(const void *buffer, size_t size, void *app_key) {
33 unsigned char *b, *bend;
35 assert(buf_offset + size < sizeof(buf));
37 memcpy(buf + buf_offset, buffer, size);
44 printf("]:%zd\n", size);
50 save_object(T_t *st) {
51 asn_enc_rval_t rval; /* Return value */
55 rval = der_encode(&asn_DEF_T, st, _buf_writer, 0);
56 if (rval.encoded == -1) {
58 "Cannot encode %s: %s\n",
59 rval.failed_type->name, strerror(errno));
60 assert(rval.encoded != -1);
64 fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset);
70 load_object(enum expectation expectation, unsigned char *fbuf, size_t size) {
75 fprintf(stderr, "LOADING OBJECT OF SIZE %d\n", (int)size);
77 /* Perform multiple iterations with multiple chunks sizes */
78 for(csize = 1; csize < 20; csize += 1) {
81 int fbuf_chunk = csize;
83 if(st) ASN_STRUCT_FREE(asn_DEF_T, st);
87 fprintf(stderr, "Decoding from %d with %d (left %d)\n",
88 fbuf_offset, fbuf_chunk, fbuf_left);
89 rval = ber_decode(0, &asn_DEF_T, (void **)&st,
91 fbuf_chunk < fbuf_left
92 ? fbuf_chunk : fbuf_left);
93 fbuf_offset += rval.consumed;
94 fbuf_left -= rval.consumed;
95 if(rval.code == RC_WMORE)
96 fbuf_chunk += 1; /* Give little more */
98 fbuf_chunk = csize; /* Back off */
99 } while(fbuf_left && rval.code == RC_WMORE);
101 if(expectation != EXP_BROKEN) {
102 assert(rval.code == RC_OK);
103 assert(fbuf_offset == (ssize_t)size);
105 assert(rval.code != RC_OK);
106 fprintf(stderr, "Failed, but this was expected\n");
107 ASN_STRUCT_FREE(asn_DEF_T, st);
108 st = 0; /* ignore leak for now */
112 if(st) asn_fprint(stderr, &asn_DEF_T, st);
118 process_data(enum expectation expectation, unsigned char *fbuf, ssize_t size) {
122 st = load_object(expectation, fbuf, size);
125 ret = save_object(st);
126 assert(buf_offset < (ssize_t)sizeof(buf));
129 switch(expectation) {
131 assert(buf_offset > 0 && buf_offset < size);
132 assert(memcmp(buf + 2, fbuf + 2, buf_offset - 2) == 0);
135 assert(buf_offset > 0 && buf_offset < size);
138 assert(buf_offset != size
139 || memcmp(buf, fbuf, buf_offset));
142 assert(buf_offset == (ssize_t)size);
143 assert(memcmp(buf, fbuf, buf_offset) == 0);
147 ASN_STRUCT_FREE(asn_DEF_T, st);
151 * Decode the .der files and try to regenerate them.
154 process(const char *fname) {
156 unsigned char fbuf[4096];
157 char *ext = strrchr(fname, '.');
158 enum expectation expectation;
164 if(ext == 0 || strcmp(ext, ".ber"))
168 case 'B': /* The file is intentionally broken */
169 expectation = EXP_BROKEN; break;
170 case 'D': /* Reconstructing should yield different data */
171 expectation = EXP_DIFFERENT; break;
172 case 'L': /* Extensions are present */
173 expectation = EXP_RECLESS; break;
175 expectation = EXP_OK; break;
178 fprintf(stderr, "\nProcessing file [../%s]\n", fname);
180 cwd = getcwd(prevdir, sizeof(prevdir));
182 ret = chdir(SRCDIR_S "/data-62");
184 fp = fopen(fname, "r");
185 ret = chdir(prevdir);
189 rd = fread(fbuf, 1, sizeof(fbuf), fp);
192 assert(rd < (ssize_t)sizeof(fbuf)); /* expect small files */
194 process_data(expectation, fbuf, rd);
203 int processed_files = 0;
206 dir = opendir(SRCDIR_S "/data-62");
209 str = getenv("DATA_62_FILE");
210 if(str && strncmp(str, "data-62-", 8) == 0)
213 while((dent = readdir(dir))) {
214 if(strncmp(dent->d_name, "data-62-", 8) == 0)
215 if(process(dent->d_name))
219 assert(processed_files);