blob: 6e21cf123fbc0a641bd96ba4f1763bb825ca51c9 [file] [log] [blame]
Lev Walkin2a744a72013-03-27 01:56:23 -07001#undef NDEBUG
2#include <stdio.h>
3#include <stdlib.h>
4#include <sys/types.h>
5#include <string.h>
6#include <assert.h>
7
8#include <T.h>
9
10uint8_t buf0[] = {
11 32 | ((2 << 6) + 1), /* [1], constructed */
12 18,
13
14 /* string [0] IMPLICIT UTF8String, */
15 (2 << 6), /* [0] */
16 16, /* L */
17 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
18};
19
20uint8_t buf0_reconstr[] = {
21 32 | ((2 << 6) + 1), /* [1], constructed */
22 18,
23
24 /* string [0] IMPLICIT UTF8String, */
25 (2 << 6), /* [0] */
26 16, /* L */
27 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
28};
29
30
31
32uint8_t buf1[] = {
33 32 | (2 << 6), /* [0], constructed */
34 0x80 | 1, /* L */
35 134,
36
37 /* string [0] IMPLICIT UTF8String, */
38 (2 << 6), /* [0] */
39 0x80 | 1, /* L */
40 128,
41 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
42 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
43 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
44 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
45 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
46 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
47 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
48 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
49
50 /* alpha [1] IMPLICIT INTEGER OPTIONAL */
51 (2 << 6) + 1, /* [1] */
52 1, /* L */
53 75,
54};
55
56uint8_t buf1_reconstr[] = {
57 32 | (2 << 6), /* [0], constructed */
58 0x80 | 1, /* L */
59 134,
60
61 /* string [0] IMPLICIT UTF8String, */
62 (2 << 6), /* [0] */
63 0x80 | 1, /* L */
64 128,
65 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
66 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
67 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
68 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
69 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
70 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
71 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
72 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
73
74 /* alpha [1] IMPLICIT INTEGER OPTIONAL */
75 (2 << 6) + 1, /* [1] */
76 1, /* L */
77 75,
78};
79
80uint8_t buf2[] = {
81 32 | ((2 << 6) + 1), /* [1], constructed */
82 0x80 | 1, /* L */
83 134,
84
85 /* string [0] IMPLICIT UTF8String, */
86 (2 << 6), /* [0] */
87 0x80 | 1, /* L */
88 128,
89 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
90 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
91 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
92 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
93 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
94 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
95 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
96 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
97
98 /* beta [2] IMPLICIT INTEGER OPTIONAL */
99 (2 << 6) + 2, /* [2] */
100 1, /* L */
101 75,
102};
103
104uint8_t buf2_reconstr[] = {
105 32 | ((2 << 6) + 1), /* [1], constructed */
106 0x80 | 1, /* L */
107 134,
108
109 /* string [0] IMPLICIT UTF8String, */
110 (2 << 6), /* [0] */
111 0x80 | 1, /* L */
112 128,
113 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
114 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
115 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
116 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
117 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
118 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
119 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
120 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
121
122 /* beta [2] IMPLICIT INTEGER OPTIONAL */
123 (2 << 6) + 2, /* [2] */
124 1, /* L */
125 75,
126};
127
128
129
130
131
132static void
Lev Walkin1715b322013-03-28 04:02:13 -0700133check(T_t *tp, uint8_t *buf, size_t size, size_t consumed) {
Lev Walkin2a744a72013-03-27 01:56:23 -0700134 asn_dec_rval_t rval;
135 int ret;
136
137 tp = memset(tp, 0, sizeof(*tp));
138
Lev Walkin1715b322013-03-28 04:02:13 -0700139 fprintf(stderr, "Buf %p (%zd)\n", buf, size);
Lev Walkin2a744a72013-03-27 01:56:23 -0700140 rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size);
Lev Walkin1715b322013-03-28 04:02:13 -0700141 fprintf(stderr, "Returned code %d, consumed %zd\n",
142 (int)rval.code, rval.consumed);
Lev Walkin2a744a72013-03-27 01:56:23 -0700143
144 assert(rval.code == RC_OK);
145 assert(rval.consumed == consumed);
146
147 fprintf(stderr, "=== asn_fprint() ===\n");
148 ret = asn_fprint(stderr, &asn_DEF_T, tp);
149 assert(ret == 0);
150 fprintf(stderr, "=== xer_fprint() ===\n");
151 ret = xer_fprint(stderr, &asn_DEF_T, tp);
152 fprintf(stderr, "=== END ===\n");
153 assert(ret == 0);
154
155 /*
156 assert(tp->string.size == 128);
157 assert(strncmp(tp->string.buf, "zz") == 0);
Lev Walkin5b63acf2014-01-14 01:48:37 -0800158 assert(strcmp((char *)tp->b.choice.b1.buf, "z") == 0
159 && strcmp((char *)tp->b.choice.b2.buf, "z") == 0);
Lev Walkin2a744a72013-03-27 01:56:23 -0700160 */
161}
162
163size_t buf_pos;
164size_t buf_size;
165uint8_t *buffer;
166
167static int
168buf_fill(const void *bufp, size_t size, void *app_key) {
169
170 (void)app_key; /* Unused argument */
171
172 if(buf_pos + size > buf_size) {
Lev Walkin1715b322013-03-28 04:02:13 -0700173 fprintf(stderr, "%zd + %zd > %zd\n",
174 buf_pos, size, buf_size);
Lev Walkin2a744a72013-03-27 01:56:23 -0700175 return -1;
176 }
177
178 memcpy(buffer + buf_pos, bufp, size);
179 buf_pos += size;
Lev Walkin1715b322013-03-28 04:02:13 -0700180 fprintf(stderr, " written %zd (%zd)\n", size, buf_pos);
Lev Walkin2a744a72013-03-27 01:56:23 -0700181
182 return 0;
183}
184
185static void
Lev Walkin1715b322013-03-28 04:02:13 -0700186compare(T_t *tp, uint8_t *cmp_buf, size_t cmp_buf_size) {
Lev Walkin2a744a72013-03-27 01:56:23 -0700187 asn_enc_rval_t erval;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800188 size_t i;
Lev Walkin2a744a72013-03-27 01:56:23 -0700189
190 buf_size = cmp_buf_size + 100;
191 buffer = alloca(buf_size);
192 buf_pos = 0;
193
194 /*
195 * Try to re-create using DER encoding.
196 */
197 erval = der_encode(&asn_DEF_T, tp, buf_fill, 0);
198 assert(erval.encoded != -1);
Lev Walkin5b63acf2014-01-14 01:48:37 -0800199 if(erval.encoded != (ssize_t)cmp_buf_size) {
Lev Walkin1715b322013-03-28 04:02:13 -0700200 printf("%zd != %zd\n", erval.encoded, cmp_buf_size);
Lev Walkin2a744a72013-03-27 01:56:23 -0700201 }
Lev Walkin5b63acf2014-01-14 01:48:37 -0800202 assert(erval.encoded == (ssize_t)cmp_buf_size);
Lev Walkin2a744a72013-03-27 01:56:23 -0700203 for(i = 0; i < cmp_buf_size; i++) {
204 if(buffer[i] != cmp_buf[i]) {
205 fprintf(stderr, "Recreated buffer content mismatch:\n");
206 fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
Lev Walkin5b63acf2014-01-14 01:48:37 -0800207 (int)i,
Lev Walkin2a744a72013-03-27 01:56:23 -0700208 buffer[i], cmp_buf[i],
209 buffer[i], cmp_buf[i]
210 );
211 }
212 assert(buffer[i] == cmp_buf[i]);
213 }
214}
215
216static void
Lev Walkin5b63acf2014-01-14 01:48:37 -0800217partial_read(uint8_t *data, size_t size) {
Lev Walkin2a744a72013-03-27 01:56:23 -0700218 T_t t, *tp;
219 asn_dec_rval_t rval;
220 size_t i1, i2;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800221 uint8_t *data1 = alloca(size);
222 uint8_t *data2 = alloca(size);
223 uint8_t *data3 = alloca(size);
Lev Walkin2a744a72013-03-27 01:56:23 -0700224
225 fprintf(stderr, "\nPartial read sequence...\n");
226
227 /*
228 * Divide the space (size) into three blocks in various combinations:
229 * |<----->i1<----->i2<----->|
Lev Walkin5b63acf2014-01-14 01:48:37 -0800230 * ^ data ^ data+size
Lev Walkin2a744a72013-03-27 01:56:23 -0700231 * Try to read block by block.
232 */
233 for(i1 = 0; i1 < size; i1++) {
234 for(i2 = i1; i2 < size; i2++) {
Lev Walkin5b63acf2014-01-14 01:48:37 -0800235 uint8_t *chunk1 = data;
Lev Walkin2a744a72013-03-27 01:56:23 -0700236 size_t size1 = i1;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800237 uint8_t *chunk2 = data + size1;
Lev Walkin2a744a72013-03-27 01:56:23 -0700238 size_t size2 = i2 - i1;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800239 uint8_t *chunk3 = data + size1 + size2;
Lev Walkin2a744a72013-03-27 01:56:23 -0700240 size_t size3 = size - size1 - size2;
241
Lev Walkin1715b322013-03-28 04:02:13 -0700242 fprintf(stderr, "\n%zd:{%zd, %zd, %zd}...\n",
243 size, size1, size2, size3);
Lev Walkin2a744a72013-03-27 01:56:23 -0700244
Lev Walkin5b63acf2014-01-14 01:48:37 -0800245 memset(data1, 0, size);
246 memset(data2, 0, size);
247 memset(data3, 0, size);
248 memcpy(data1, chunk1, size1);
249 memcpy(data2, chunk2, size2);
250 memcpy(data3, chunk3, size3);
Lev Walkin2a744a72013-03-27 01:56:23 -0700251
252 tp = memset(&t, 0, sizeof(t));
253
Lev Walkin1715b322013-03-28 04:02:13 -0700254 fprintf(stderr, "=> Chunk 1 (%zd):\n", size1);
Lev Walkin2a744a72013-03-27 01:56:23 -0700255 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkin5b63acf2014-01-14 01:48:37 -0800256 data1, size1);
Lev Walkin2a744a72013-03-27 01:56:23 -0700257 assert(rval.code == RC_WMORE);
258 assert(rval.consumed <= size1);
259 if(rval.consumed < size1) {
260 int leftover = size1 - rval.consumed;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800261 memcpy(data2, data1 + rval.consumed, leftover);
262 memcpy(data2 + leftover, chunk2, size2);
Lev Walkin2a744a72013-03-27 01:56:23 -0700263 size2 += leftover;
264 }
265
Lev Walkin1715b322013-03-28 04:02:13 -0700266 fprintf(stderr, "=> Chunk 2 (%zd):\n", size2);
Lev Walkin2a744a72013-03-27 01:56:23 -0700267 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkin5b63acf2014-01-14 01:48:37 -0800268 data2, size2);
Lev Walkin2a744a72013-03-27 01:56:23 -0700269 assert(rval.code == RC_WMORE);
270 assert(rval.consumed <= size2);
271 if(rval.consumed < size2) {
272 int leftover = size2 - rval.consumed;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800273 memcpy(data3, data2 + rval.consumed, leftover);
274 memcpy(data3 + leftover, chunk3, size3);
Lev Walkin2a744a72013-03-27 01:56:23 -0700275 size3 += leftover;
276 }
277
Lev Walkin1715b322013-03-28 04:02:13 -0700278 fprintf(stderr, "=> Chunk 3 (%zd):\n", size3);
Lev Walkin2a744a72013-03-27 01:56:23 -0700279 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkin5b63acf2014-01-14 01:48:37 -0800280 data3, size3);
Lev Walkin2a744a72013-03-27 01:56:23 -0700281 assert(rval.code == RC_OK);
282 assert(rval.consumed == size3);
283
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700284 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin2a744a72013-03-27 01:56:23 -0700285 }
286 }
287}
288
289int
290main() {
291 T_t t;
292
293 /* Check exact buf0 */
294 check(&t, buf0, sizeof(buf0), sizeof(buf0));
295 compare(&t, buf0_reconstr, sizeof(buf0_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700296 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin2a744a72013-03-27 01:56:23 -0700297
298 /* Check exact buf1 */
299 check(&t, buf1, sizeof(buf1), sizeof(buf1));
300 compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700301 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin2a744a72013-03-27 01:56:23 -0700302
303 /* Check slightly more than buf1 */
304 check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1));
305 compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700306 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin2a744a72013-03-27 01:56:23 -0700307
308 /* Check exact buf2 */
309 check(&t, buf2, sizeof(buf2), sizeof(buf2));
310 compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700311 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin2a744a72013-03-27 01:56:23 -0700312
313 /* Check slightly more than buf2 */
314 check(&t, buf2, sizeof(buf2) + 10, sizeof(buf2));
315 compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700316 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin2a744a72013-03-27 01:56:23 -0700317
318 /* Split the buffer in parts and check decoder restartability */
319 partial_read(buf0, sizeof(buf0));
320
321 return 0;
322}