blob: 98741f51619469557280068d5d40d9837d692b78 [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;
Lev Walkina4f8e942017-10-08 19:28:20 -0700191 uint8_t scratch[buf_size];
192 buffer = scratch;
Lev Walkin2a744a72013-03-27 01:56:23 -0700193 buf_pos = 0;
194
195 /*
196 * Try to re-create using DER encoding.
197 */
198 erval = der_encode(&asn_DEF_T, tp, buf_fill, 0);
199 assert(erval.encoded != -1);
Lev Walkin5b63acf2014-01-14 01:48:37 -0800200 if(erval.encoded != (ssize_t)cmp_buf_size) {
Lev Walkin1715b322013-03-28 04:02:13 -0700201 printf("%zd != %zd\n", erval.encoded, cmp_buf_size);
Lev Walkin2a744a72013-03-27 01:56:23 -0700202 }
Lev Walkin5b63acf2014-01-14 01:48:37 -0800203 assert(erval.encoded == (ssize_t)cmp_buf_size);
Lev Walkin2a744a72013-03-27 01:56:23 -0700204 for(i = 0; i < cmp_buf_size; i++) {
205 if(buffer[i] != cmp_buf[i]) {
206 fprintf(stderr, "Recreated buffer content mismatch:\n");
207 fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
Lev Walkin5b63acf2014-01-14 01:48:37 -0800208 (int)i,
Lev Walkin2a744a72013-03-27 01:56:23 -0700209 buffer[i], cmp_buf[i],
210 buffer[i], cmp_buf[i]
211 );
212 }
213 assert(buffer[i] == cmp_buf[i]);
214 }
Lev Walkina4f8e942017-10-08 19:28:20 -0700215
216 buffer = 0;
Lev Walkin2a744a72013-03-27 01:56:23 -0700217}
218
219static void
Lev Walkin5b63acf2014-01-14 01:48:37 -0800220partial_read(uint8_t *data, size_t size) {
Lev Walkin2a744a72013-03-27 01:56:23 -0700221 T_t t, *tp;
222 asn_dec_rval_t rval;
Lev Walkina4f8e942017-10-08 19:28:20 -0700223 uint8_t data1[size];
224 uint8_t data2[size];
225 uint8_t data3[size];
Lev Walkin2a744a72013-03-27 01:56:23 -0700226
227 fprintf(stderr, "\nPartial read sequence...\n");
228
229 /*
230 * Divide the space (size) into three blocks in various combinations:
231 * |<----->i1<----->i2<----->|
Lev Walkin5b63acf2014-01-14 01:48:37 -0800232 * ^ data ^ data+size
Lev Walkin2a744a72013-03-27 01:56:23 -0700233 * Try to read block by block.
234 */
Lev Walkina4f8e942017-10-08 19:28:20 -0700235 for(size_t i1 = 0; i1 < size; i1++) {
236 for(size_t i2 = i1; i2 < size; i2++) {
Lev Walkin5b63acf2014-01-14 01:48:37 -0800237 uint8_t *chunk1 = data;
Lev Walkin2a744a72013-03-27 01:56:23 -0700238 size_t size1 = i1;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800239 uint8_t *chunk2 = data + size1;
Lev Walkin2a744a72013-03-27 01:56:23 -0700240 size_t size2 = i2 - i1;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800241 uint8_t *chunk3 = data + size1 + size2;
Lev Walkin2a744a72013-03-27 01:56:23 -0700242 size_t size3 = size - size1 - size2;
243
Lev Walkin1715b322013-03-28 04:02:13 -0700244 fprintf(stderr, "\n%zd:{%zd, %zd, %zd}...\n",
245 size, size1, size2, size3);
Lev Walkin2a744a72013-03-27 01:56:23 -0700246
Lev Walkin5b63acf2014-01-14 01:48:37 -0800247 memset(data1, 0, size);
248 memset(data2, 0, size);
249 memset(data3, 0, size);
250 memcpy(data1, chunk1, size1);
251 memcpy(data2, chunk2, size2);
252 memcpy(data3, chunk3, size3);
Lev Walkin2a744a72013-03-27 01:56:23 -0700253
254 tp = memset(&t, 0, sizeof(t));
255
Lev Walkin1715b322013-03-28 04:02:13 -0700256 fprintf(stderr, "=> Chunk 1 (%zd):\n", size1);
Lev Walkin2a744a72013-03-27 01:56:23 -0700257 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkin5b63acf2014-01-14 01:48:37 -0800258 data1, size1);
Lev Walkin2a744a72013-03-27 01:56:23 -0700259 assert(rval.code == RC_WMORE);
260 assert(rval.consumed <= size1);
261 if(rval.consumed < size1) {
262 int leftover = size1 - rval.consumed;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800263 memcpy(data2, data1 + rval.consumed, leftover);
264 memcpy(data2 + leftover, chunk2, size2);
Lev Walkin2a744a72013-03-27 01:56:23 -0700265 size2 += leftover;
266 }
267
Lev Walkin1715b322013-03-28 04:02:13 -0700268 fprintf(stderr, "=> Chunk 2 (%zd):\n", size2);
Lev Walkin2a744a72013-03-27 01:56:23 -0700269 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkin5b63acf2014-01-14 01:48:37 -0800270 data2, size2);
Lev Walkin2a744a72013-03-27 01:56:23 -0700271 assert(rval.code == RC_WMORE);
272 assert(rval.consumed <= size2);
273 if(rval.consumed < size2) {
274 int leftover = size2 - rval.consumed;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800275 memcpy(data3, data2 + rval.consumed, leftover);
276 memcpy(data3 + leftover, chunk3, size3);
Lev Walkin2a744a72013-03-27 01:56:23 -0700277 size3 += leftover;
278 }
279
Lev Walkin1715b322013-03-28 04:02:13 -0700280 fprintf(stderr, "=> Chunk 3 (%zd):\n", size3);
Lev Walkin2a744a72013-03-27 01:56:23 -0700281 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkin5b63acf2014-01-14 01:48:37 -0800282 data3, size3);
Lev Walkin2a744a72013-03-27 01:56:23 -0700283 assert(rval.code == RC_OK);
284 assert(rval.consumed == size3);
285
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700286 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin2a744a72013-03-27 01:56:23 -0700287 }
288 }
289}
290
291int
292main() {
293 T_t t;
294
295 /* Check exact buf0 */
296 check(&t, buf0, sizeof(buf0), sizeof(buf0));
297 compare(&t, buf0_reconstr, sizeof(buf0_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700298 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin2a744a72013-03-27 01:56:23 -0700299
300 /* Check exact buf1 */
301 check(&t, buf1, sizeof(buf1), sizeof(buf1));
302 compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700303 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin2a744a72013-03-27 01:56:23 -0700304
305 /* Check slightly more than buf1 */
306 check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1));
307 compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700308 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin2a744a72013-03-27 01:56:23 -0700309
310 /* Check exact buf2 */
311 check(&t, buf2, sizeof(buf2), sizeof(buf2));
312 compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700313 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin2a744a72013-03-27 01:56:23 -0700314
315 /* Check slightly more than buf2 */
316 check(&t, buf2, sizeof(buf2) + 10, sizeof(buf2));
317 compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700318 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin2a744a72013-03-27 01:56:23 -0700319
320 /* Split the buffer in parts and check decoder restartability */
321 partial_read(buf0, sizeof(buf0));
322
323 return 0;
324}