NativeEnumerated.c vars NULL init and check
[com/asn1c.git] / tests / tests-c-compiler / check-src / check-35.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 buf1[] = {
11         32 | 17,                /* [UNIVERSAL 17], constructed */
12         15,     /* L */
13
14         /* b CHOICE { b2 ObjectDescriptor }*/
15         7,                      /* [UNIVERSAL 7] */
16         1,      /* L */
17   'z',
18
19         /* c BOOLEAN */
20         1,                      /* [UNIVERSAL 1] */
21         0,      /* L */
22
23         /* a NumericString */
24         18,                     /* [UNIVERSAL 18] */
25         4,      /* L */
26   '=',
27   '<',
28   '&',
29   '>',
30
31         /* d.r-oid RELATIVE-OID */
32         13,                     /* [UNIVERSAL 13] */
33         2,      /* L */
34   85,
35   79,
36
37 };
38
39 uint8_t buf1_reconstr[] = {
40         32 | 17,                /* [UNIVERSAL 17], constructed */
41         16,     /* L */
42
43         /* c BOOLEAN */
44         1,                      /* [UNIVERSAL 1] */
45         1,      /* L */
46         0,
47
48         /* b CHOICE { b2 ObjectDescriptor }*/
49         7,                      /* [UNIVERSAL 7] */
50         1,      /* L */
51   'z',
52
53         /* d.r-oid RELATIVE-OID */
54         13,                     /* [UNIVERSAL 1] */
55         2,      /* L */
56   85,
57   79,
58
59         /* a NumericString */
60         18,                     /* [UNIVERSAL 18] */
61         4,      /* L */
62   '=',
63   '<',
64   '&',
65   '>',
66 };
67
68 uint8_t buf2[] = {
69         32 | 17,                /* [UNIVERSAL 17], constructed */
70         15,     /* L */
71
72         /* a NumericString */
73         18,                     /* [UNIVERSAL 18] */
74         4,      /* L */
75   '=',
76   '<',
77   '&',
78   '>',
79
80         /* c BOOLEAN */
81         1,                      /* [UNIVERSAL 1] */
82         1,      /* L */
83         2,      /* True */
84
85         /* b CHOICE { b1 IA5String }*/
86         22,                     /* [UNIVERSAL 22] */
87         1,      /* L */
88   'z',
89
90         /* d.oid RELATIVE-OID */
91         6,                      /* [UNIVERSAL 6] */
92         1,      /* L */
93   81,
94
95 };
96
97 uint8_t buf2_reconstr[] = {
98         32 | 17,                /* [UNIVERSAL 17], constructed */
99         15,     /* L */
100
101         /* c BOOLEAN */
102         1,                      /* [UNIVERSAL 1] */
103         1,      /* L */
104         0xff,   /* Canonical True */
105
106         /* d.oid RELATIVE-OID */
107         6,                      /* [UNIVERSAL 6] */
108         1,      /* L */
109   81,
110
111         /* a NumericString */
112         18,                     /* [UNIVERSAL 18] */
113         4,      /* L */
114   '=',
115   '<',
116   '&',
117   '>',
118
119         /* b CHOICE { b1 IA5String }*/
120         22,                     /* [UNIVERSAL 22] */
121         1,      /* L */
122   'z'
123 };
124
125 static void
126 check(T_t *tp, uint8_t *buf, size_t size, size_t consumed) {
127         asn_dec_rval_t rval;
128
129         tp = memset(tp, 0, sizeof(*tp));
130
131         fprintf(stderr, "Buf %p (%zd)\n", buf, size);
132         rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size);
133         fprintf(stderr, "Returned code %d, consumed %zd\n",
134                 (int)rval.code, rval.consumed);
135
136         assert(rval.code == RC_OK);
137         assert(rval.consumed == consumed);
138
139         assert(strcmp((char *)tp->a.buf, "=<&>") == 0);
140         assert(strcmp((char *)tp->b.choice.b1.buf, "z") == 0
141                 && strcmp((char *)tp->b.choice.b2.buf, "z") == 0);
142
143         asn_fprint(stderr, &asn_DEF_T, tp);
144         xer_fprint(stderr, &asn_DEF_T, tp);
145 }
146
147 size_t buf_pos;
148 size_t buf_size;
149 uint8_t *buf;
150
151 static int
152 buf_fill(const void *buffer, size_t size, void *app_key) {
153
154         (void)app_key;
155
156         if(buf_pos + size > buf_size) {
157                 fprintf(stderr, "%zd + %zd > %zd\n",
158                         buf_pos, size, buf_size);
159                 return -1;
160         }
161
162         memcpy(buf + buf_pos, buffer, size);
163         buf_pos += size;
164         fprintf(stderr, "   written %zd (%zd)\n", size, buf_pos);
165
166         return 0;
167 }
168
169 static void
170 compare(T_t *tp, uint8_t *cmp_buf, size_t cmp_buf_size) {
171         asn_enc_rval_t erval;
172         size_t i;
173
174         buf_size = cmp_buf_size + 100;
175     uint8_t scratch[buf_size];
176         buf = scratch;
177         buf_pos = 0;
178
179         /*
180          * Try to re-create using DER encoding.
181          */
182         erval = der_encode(&asn_DEF_T, tp, buf_fill, 0);
183         assert(erval.encoded != -1);
184         if(erval.encoded != (ssize_t)cmp_buf_size) {
185                 printf("%zd != %zd\n", erval.encoded, cmp_buf_size);
186         }
187         assert(erval.encoded == (ssize_t)cmp_buf_size);
188         for(i = 0; i < cmp_buf_size; i++) {
189                 if(buf[i] != cmp_buf[i]) {
190                         fprintf(stderr, "Recreated buffer content mismatch:\n");
191                         fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
192                                 (int)i,
193                                 buf[i], cmp_buf[i],
194                                 buf[i], cmp_buf[i]
195                         );
196                 }
197                 assert(buf[i] == cmp_buf[i]);
198         }
199 }
200
201 static void
202 partial_read(uint8_t *data, size_t size) {
203         T_t t, *tp;
204         asn_dec_rval_t rval;
205         size_t i1, i2;
206         uint8_t data1[size];
207         uint8_t data2[size];
208         uint8_t data3[size];
209
210         fprintf(stderr, "\nPartial read sequence...\n");
211
212         /*
213          * Divide the space (size) into three blocks in various combinations:
214          *   |<----->i1<----->i2<----->|
215          *   ^ data                  ^ data+size
216          * Try to read block by block.
217          */
218         for(i1 = 0; i1 < size; i1++) {
219                 for(i2 = i1; i2 < size; i2++) {
220                         uint8_t *chunk1 = data;
221                         size_t size1 = i1;
222                         uint8_t *chunk2 = data + size1;
223                         size_t size2 = i2 - i1;
224                         uint8_t *chunk3 = data + size1 + size2;
225                         size_t size3 = size - size1 - size2;
226
227                         fprintf(stderr, "\n%zd:{%zd, %zd, %zd}...\n",
228                                 size, size1, size2, size3);
229
230                         memset(data1, 0, size);
231                         memset(data2, 0, size);
232                         memset(data3, 0, size);
233                         memcpy(data1, chunk1, size1);
234                         memcpy(data2, chunk2, size2);
235                         memcpy(data3, chunk3, size3);
236
237                         tp = memset(&t, 0, sizeof(t));
238
239                         fprintf(stderr, "=> Chunk 1 (%zd):\n", size1);
240                         rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
241                                 data1, size1);
242                         assert(rval.code == RC_WMORE);
243                         assert(rval.consumed <= size1);
244                         if(rval.consumed < size1) {
245                                 int leftover = size1 - rval.consumed;
246                                 memcpy(data2, data1 + rval.consumed, leftover);
247                                 memcpy(data2 + leftover, chunk2, size2);
248                                 size2 += leftover;
249                         }
250
251                         fprintf(stderr, "=> Chunk 2 (%zd):\n", size2);
252                         rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
253                                 data2, size2);
254                         assert(rval.code == RC_WMORE);
255                         assert(rval.consumed <= size2);
256                         if(rval.consumed < size2) {
257                                 int leftover = size2 - rval.consumed;
258                                 memcpy(data3, data2 + rval.consumed, leftover);
259                                 memcpy(data3 + leftover, chunk3, size3);
260                                 size3 += leftover;
261                         }
262
263                         fprintf(stderr, "=> Chunk 3 (%zd):\n", size3);
264                         rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
265                                 data3, size3);
266                         assert(rval.code == RC_OK);
267                         assert(rval.consumed == size3);
268
269                         ASN_STRUCT_RESET(asn_DEF_T, &t);
270                 }
271         }
272 }
273
274 static char xer_buf[128];
275 static size_t xer_off;
276
277 static int
278 xer_cb(const void *buffer, size_t size, void *key) {
279         (void)key;
280         assert(xer_off + size < sizeof(xer_buf));
281         memcpy(xer_buf + xer_off, buffer, size);
282         xer_off += size;
283         return 0;
284 }
285
286 static void
287 check_xer(uint8_t *data, uint8_t size, char *xer_sample) {
288         T_t *tp = 0;
289         asn_dec_rval_t rval;
290         asn_enc_rval_t er;
291         size_t xer_sample_len = strlen(xer_sample);
292
293         rval = ber_decode(0, &asn_DEF_T, (void **)&tp, data, size);
294         assert(rval.code == RC_OK);
295         assert(rval.consumed == size);
296         assert(tp);
297
298         xer_off = 0;
299         er = xer_encode(&asn_DEF_T, tp, XER_F_CANONICAL, xer_cb, 0);
300         assert(xer_off);
301         xer_buf[xer_off] = 0;
302         printf("[%s] (%zd/%zd) vs [%s] (%zd)\n",
303                 xer_buf, er.encoded, xer_off, xer_sample, xer_sample_len);
304         assert(er.encoded == (ssize_t)xer_off);
305         assert(xer_off == xer_sample_len);
306         assert(memcmp(xer_buf, xer_sample, xer_off) == 0);
307
308         ASN_STRUCT_FREE(asn_DEF_T, tp);
309 }
310
311
312 int
313 main(int ac, char **av) {
314         T_t t;
315
316         (void)ac;       /* Unused argument */
317         (void)av;       /* Unused argument */
318
319         check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1));
320         compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
321         ASN_STRUCT_RESET(asn_DEF_T, &t);
322         check_xer(buf1, sizeof(buf1), "<T><c><false/></c><b><b2>z</b2></b><a>=&lt;&amp;&gt;</a><d><r-oid>85.79</r-oid></d></T>");
323
324         check(&t, buf2, sizeof(buf2) + 10, sizeof(buf2));
325         compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
326         ASN_STRUCT_RESET(asn_DEF_T, &t);
327         check_xer(buf2, sizeof(buf2), "<T><c><true/></c><b><b1>z</b1></b><a>=&lt;&amp;&gt;</a><d><oid>2.1</oid></d></T>");
328
329         /* Split the buffer in parts and check decoder restartability */
330         partial_read(buf1, sizeof(buf1));
331
332         return 0;
333 }