11 32 | ((2 << 6) + 1), /* [1], constructed */
14 /* string [0] IMPLICIT UTF8String, */
17 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
20 uint8_t buf0_reconstr[] = {
21 32 | ((2 << 6) + 1), /* [1], constructed */
24 /* string [0] IMPLICIT UTF8String, */
27 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z',
33 32 | (2 << 6), /* [0], constructed */
37 /* string [0] IMPLICIT UTF8String, */
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',
50 /* alpha [1] IMPLICIT INTEGER OPTIONAL */
51 (2 << 6) + 1, /* [1] */
56 uint8_t buf1_reconstr[] = {
57 32 | (2 << 6), /* [0], constructed */
61 /* string [0] IMPLICIT UTF8String, */
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',
74 /* alpha [1] IMPLICIT INTEGER OPTIONAL */
75 (2 << 6) + 1, /* [1] */
81 32 | ((2 << 6) + 1), /* [1], constructed */
85 /* string [0] IMPLICIT UTF8String, */
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',
98 /* beta [2] IMPLICIT INTEGER OPTIONAL */
99 (2 << 6) + 2, /* [2] */
104 uint8_t buf2_reconstr[] = {
105 32 | ((2 << 6) + 1), /* [1], constructed */
109 /* string [0] IMPLICIT UTF8String, */
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',
122 /* beta [2] IMPLICIT INTEGER OPTIONAL */
123 (2 << 6) + 2, /* [2] */
133 check(T_t *tp, uint8_t *buf, size_t size, size_t consumed) {
137 tp = memset(tp, 0, sizeof(*tp));
139 fprintf(stderr, "Buf %p (%zd)\n", buf, size);
140 rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size);
141 fprintf(stderr, "Returned code %d, consumed %zd\n",
142 (int)rval.code, rval.consumed);
144 assert(rval.code == RC_OK);
145 assert(rval.consumed == consumed);
147 fprintf(stderr, "=== asn_fprint() ===\n");
148 ret = asn_fprint(stderr, &asn_DEF_T, tp);
150 fprintf(stderr, "=== xer_fprint() ===\n");
151 ret = xer_fprint(stderr, &asn_DEF_T, tp);
152 fprintf(stderr, "=== END ===\n");
156 assert(tp->string.size == 128);
157 assert(strncmp(tp->string.buf, "zz") == 0);
158 assert(strcmp((char *)tp->b.choice.b1.buf, "z") == 0
159 && strcmp((char *)tp->b.choice.b2.buf, "z") == 0);
168 buf_fill(const void *bufp, size_t size, void *app_key) {
170 (void)app_key; /* Unused argument */
172 if(buf_pos + size > buf_size) {
173 fprintf(stderr, "%zd + %zd > %zd\n",
174 buf_pos, size, buf_size);
178 memcpy(buffer + buf_pos, bufp, size);
180 fprintf(stderr, " written %zd (%zd)\n", size, buf_pos);
186 compare(T_t *tp, uint8_t *cmp_buf, size_t cmp_buf_size) {
187 asn_enc_rval_t erval;
190 buf_size = cmp_buf_size + 100;
191 uint8_t scratch[buf_size];
196 * Try to re-create using DER encoding.
198 erval = der_encode(&asn_DEF_T, tp, buf_fill, 0);
199 assert(erval.encoded != -1);
200 if(erval.encoded != (ssize_t)cmp_buf_size) {
201 printf("%zd != %zd\n", erval.encoded, cmp_buf_size);
203 assert(erval.encoded == (ssize_t)cmp_buf_size);
204 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",
209 buffer[i], cmp_buf[i],
210 buffer[i], cmp_buf[i]
213 assert(buffer[i] == cmp_buf[i]);
220 partial_read(uint8_t *data, size_t size) {
227 fprintf(stderr, "\nPartial read sequence...\n");
230 * Divide the space (size) into three blocks in various combinations:
231 * |<----->i1<----->i2<----->|
233 * Try to read block by block.
235 for(size_t i1 = 0; i1 < size; i1++) {
236 for(size_t i2 = i1; i2 < size; i2++) {
237 uint8_t *chunk1 = data;
239 uint8_t *chunk2 = data + size1;
240 size_t size2 = i2 - i1;
241 uint8_t *chunk3 = data + size1 + size2;
242 size_t size3 = size - size1 - size2;
244 fprintf(stderr, "\n%zd:{%zd, %zd, %zd}...\n",
245 size, size1, size2, size3);
247 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);
254 tp = memset(&t, 0, sizeof(t));
256 fprintf(stderr, "=> Chunk 1 (%zd):\n", size1);
257 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
259 assert(rval.code == RC_WMORE);
260 assert(rval.consumed <= size1);
261 if(rval.consumed < size1) {
262 int leftover = size1 - rval.consumed;
263 memcpy(data2, data1 + rval.consumed, leftover);
264 memcpy(data2 + leftover, chunk2, size2);
268 fprintf(stderr, "=> Chunk 2 (%zd):\n", size2);
269 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
271 assert(rval.code == RC_WMORE);
272 assert(rval.consumed <= size2);
273 if(rval.consumed < size2) {
274 int leftover = size2 - rval.consumed;
275 memcpy(data3, data2 + rval.consumed, leftover);
276 memcpy(data3 + leftover, chunk3, size3);
280 fprintf(stderr, "=> Chunk 3 (%zd):\n", size3);
281 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
283 assert(rval.code == RC_OK);
284 assert(rval.consumed == size3);
286 ASN_STRUCT_RESET(asn_DEF_T, &t);
295 /* Check exact buf0 */
296 check(&t, buf0, sizeof(buf0), sizeof(buf0));
297 compare(&t, buf0_reconstr, sizeof(buf0_reconstr));
298 ASN_STRUCT_RESET(asn_DEF_T, &t);
300 /* Check exact buf1 */
301 check(&t, buf1, sizeof(buf1), sizeof(buf1));
302 compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
303 ASN_STRUCT_RESET(asn_DEF_T, &t);
305 /* Check slightly more than buf1 */
306 check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1));
307 compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
308 ASN_STRUCT_RESET(asn_DEF_T, &t);
310 /* Check exact buf2 */
311 check(&t, buf2, sizeof(buf2), sizeof(buf2));
312 compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
313 ASN_STRUCT_RESET(asn_DEF_T, &t);
315 /* Check slightly more than buf2 */
316 check(&t, buf2, sizeof(buf2) + 10, sizeof(buf2));
317 compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
318 ASN_STRUCT_RESET(asn_DEF_T, &t);
320 /* Split the buffer in parts and check decoder restartability */
321 partial_read(buf0, sizeof(buf0));