98741f51619469557280068d5d40d9837d692b78
[com/asn1c.git] / tests / tests-c-compiler / check-src / check-41.-fwide-types.c
1 #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
10 uint8_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
20 uint8_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
32 uint8_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
56 uint8_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
80 uint8_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
104 uint8_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
132 static void
133 check(T_t *tp, uint8_t *buf, size_t size, size_t consumed) {
134         asn_dec_rval_t rval;
135         int ret;
136
137         tp = memset(tp, 0, sizeof(*tp));
138
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);
143
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);
158         assert(strcmp((char *)tp->b.choice.b1.buf, "z") == 0
159                 && strcmp((char *)tp->b.choice.b2.buf, "z") == 0);
160         */
161 }
162
163 size_t buf_pos;
164 size_t buf_size;
165 uint8_t *buffer;
166
167 static int
168 buf_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) {
173                 fprintf(stderr, "%zd + %zd > %zd\n",
174                         buf_pos, size, buf_size);
175                 return -1;
176         }
177
178         memcpy(buffer + buf_pos, bufp, size);
179         buf_pos += size;
180         fprintf(stderr, "   written %zd (%zd)\n", size, buf_pos);
181
182         return 0;
183 }
184
185 static void
186 compare(T_t *tp, uint8_t *cmp_buf, size_t cmp_buf_size) {
187         asn_enc_rval_t erval;
188         size_t i;
189
190         buf_size = cmp_buf_size + 100;
191     uint8_t scratch[buf_size];
192         buffer = scratch;
193         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);
200         if(erval.encoded != (ssize_t)cmp_buf_size) {
201                 printf("%zd != %zd\n", erval.encoded, cmp_buf_size);
202         }
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",
208                                 (int)i,
209                                 buffer[i], cmp_buf[i],
210                                 buffer[i], cmp_buf[i]
211                         );
212                 }
213                 assert(buffer[i] == cmp_buf[i]);
214         }
215
216     buffer = 0;
217 }
218
219 static void
220 partial_read(uint8_t *data, size_t size) {
221         T_t t, *tp;
222         asn_dec_rval_t rval;
223         uint8_t data1[size];
224         uint8_t data2[size];
225         uint8_t data3[size];
226
227         fprintf(stderr, "\nPartial read sequence...\n");
228
229         /*
230          * Divide the space (size) into three blocks in various combinations:
231          *   |<----->i1<----->i2<----->|
232          *   ^ data                    ^ data+size
233          * Try to read block by block.
234          */
235         for(size_t i1 = 0; i1 < size; i1++) {
236                 for(size_t i2 = i1; i2 < size; i2++) {
237                         uint8_t *chunk1 = data;
238                         size_t size1 = i1;
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;
243
244                         fprintf(stderr, "\n%zd:{%zd, %zd, %zd}...\n",
245                                 size, size1, size2, size3);
246
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);
253
254                         tp = memset(&t, 0, sizeof(t));
255
256                         fprintf(stderr, "=> Chunk 1 (%zd):\n", size1);
257                         rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
258                                 data1, size1);
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);
265                                 size2 += leftover;
266                         }
267
268                         fprintf(stderr, "=> Chunk 2 (%zd):\n", size2);
269                         rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
270                                 data2, size2);
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);
277                                 size3 += leftover;
278                         }
279
280                         fprintf(stderr, "=> Chunk 3 (%zd):\n", size3);
281                         rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
282                                 data3, size3);
283                         assert(rval.code == RC_OK);
284                         assert(rval.consumed == size3);
285
286                         ASN_STRUCT_RESET(asn_DEF_T, &t);
287                 }
288         }
289 }
290
291 int
292 main() {
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));
298         ASN_STRUCT_RESET(asn_DEF_T, &t);
299
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);
304
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);
309
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);
314
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);
319
320         /* Split the buffer in parts and check decoder restartability */
321         partial_read(buf0, sizeof(buf0));
322
323         return 0;
324 }