3f1b1cdf8b7b8c28021aacc60b719ae16aea63c8
[com/asn1c.git] / tests / tests-c-compiler / check-src / check-30.-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
11 /*
12  * Test that the optional member (c) is really optional.
13  */
14 uint8_t buf1[] = {
15         32 | 17,                /* [UNIVERSAL 17], constructed */
16         8,      /* L */
17
18         /* a INTEGER */
19         64 | 3,                 /* [APPLICATION 3] */
20         1,      /* L */
21   96,
22
23         /* b IA5String */
24         22,                     /* [UNIVERSAL 22] */
25         3,      /* L */
26         'x',
27         'y',
28         'z'
29 };
30
31 /*
32  * This buffer aims at checking the duplication.
33  */
34 uint8_t buf2[] = {
35         32 | 17,                /* [UNIVERSAL 17], constructed */
36         8,      /* L */
37
38         /* a INTEGER */
39         64 | 3,                 /* [APPLICATION 3] */
40         1,      /* L */
41   96,
42
43         /* a INTEGER _again_ */
44         64 | 3,                 /* [APPLICATION 3] */
45         1,      /* L */
46   97,
47 };
48
49 /*
50  * This buffer checks that an unexpected member may be properly ignored.
51  */
52 uint8_t buf3[] = {
53         32 | 17,                /* [UNIVERSAL 17], constructed */
54         14,     /* L */
55
56         /* INTEGER */
57         64 | 3,                 /* [APPLICATION 3] */
58         1,      /* L */
59   96,
60
61         /* IA5String */
62         22,                     /* [UNIVERSAL 22] */
63         3,      /* L */
64         'x',
65         'y',
66         'z',
67
68         /* unexpected INTEGER */
69         64 | 4,                 /* [APPLICATION 4] */
70         1,      /* L */
71   96,
72
73         /* [2] BOOLEAN */
74         ((2 << 6) + 2),                 /* [2] */
75         1,      /* L */
76         0xff
77 };
78
79 /*
80  * This buffer checks that an unexpected member may be properly ignored.
81  * This time, with indefinite length encoding.
82  */
83 uint8_t buf4[] = {
84         32 | 17,                /* [UNIVERSAL 17], constructed */
85         16,     /* L */
86
87         /* a INTEGER */
88         64 | 3,                 /* [APPLICATION 3] */
89         1,      /* L */
90   96,
91
92         /* b IA5String */
93         22,                     /* [UNIVERSAL 22] */
94         3,      /* L */
95         'x',
96         'y',
97         'z',
98
99         /* unexpected data structure */
100         32 | 64 | 4,                    /* [APPLICATION 4] */
101         0x80,   /* indefinite L */
102         64 | 1,                 /* [APPLICATION 1] */
103         2,      /* L */
104         'a', 'b',
105
106         0x00,
107         0x00
108 };
109
110 /*
111  * This buffer checks that an unexpected member may be properly ignored.
112  * This time, with indefinite length encoding at the outer level too.
113  */
114 uint8_t buf5[] = {
115         32 | 17,                /* [UNIVERSAL 17], constructed */
116         0x80,   /* indefinite L */
117
118         /* INTEGER */
119         64 | 3,                 /* [APPLICATION 3] */
120         1,      /* L */
121   96,
122
123         /* IA5String */
124         22,                     /* [UNIVERSAL 22] */
125         3,      /* L */
126         'x',
127         'y',
128         'z',
129
130         /* unexpected data structure */
131         32 | 64 | 4,                    /* [APPLICATION 4] */
132         0x80,   /* indefinite L */
133         64 | 1,                 /* [APPLICATION 1] */
134         2,      /* L */
135         'a', 'b',
136
137         0x00,
138         0x00,
139
140         0x00,
141         0x00
142 };
143
144 static void
145 check(int is_ok, uint8_t *buf, size_t size, size_t consumed) {
146         T_t t, *tp;
147         asn_dec_rval_t rval;
148
149         fprintf(stderr, "\nMust %s:\n", is_ok?"suceed":"fail");
150
151         tp = memset(&t, 0, sizeof(t));
152
153         fprintf(stderr, "Buf %p\n", buf);
154         rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size);
155         fprintf(stderr, "Returned code %d, consumed %zd (out of %zd)\n",
156                 (int)rval.code, rval.consumed, size);
157
158         if(is_ok) {
159                 assert(rval.code == RC_OK);
160                 assert(rval.consumed == consumed);
161
162                 assert(t.i.size == 1);
163                 assert(t.i.buf[0] == 96);
164                 assert(t.s.size == 3);
165                 assert(strcmp((char *)t.s.buf, "xyz") == 0);
166                 if(buf == buf3) {
167                         assert(t.b);
168                 } else {
169                         assert(t.b == 0);
170                 }
171         } else {
172                 if(rval.code == RC_OK) {
173                         assert(t.i.size != 1
174                         || t.s.size != 3
175                         || !t.b
176                         );
177                 }
178                 assert(rval.consumed <= consumed);
179         }
180         ASN_STRUCT_RESET(asn_DEF_T, tp);
181 }
182
183
184 static char xer_buf[128];
185 static int xer_off;
186
187 static int
188 xer_cb(const void *buffer, size_t size, void *key) {
189         (void)key;
190         assert(xer_off + size < sizeof(xer_buf));
191         memcpy(xer_buf + xer_off, buffer, size);
192         xer_off += size;
193         return 0;
194 }
195
196 static void
197 check_xer(uint8_t *buf, uint8_t size, char *xer_sample) {
198         T_t *tp = 0;
199         asn_dec_rval_t rval;
200         asn_enc_rval_t er;
201         int xer_sample_len = strlen(xer_sample);
202
203         rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size);
204         assert(rval.code == RC_OK);
205         assert(rval.consumed == size);
206         assert(tp);
207
208         xer_off = 0;
209         er = xer_encode(&asn_DEF_T, tp, XER_F_CANONICAL, xer_cb, 0);
210         assert(er.encoded == xer_off);
211         assert(xer_off);
212         xer_buf[xer_off] = 0;
213         printf("[%s] vs [%s]\n", xer_buf, xer_sample);
214         assert(xer_off == xer_sample_len);
215         assert(memcmp(xer_buf, xer_sample, xer_off) == 0);
216
217         ASN_STRUCT_FREE(asn_DEF_T, tp);
218 }
219
220 static void
221 try_corrupt(uint8_t *buf, size_t size) {
222         uint8_t tmp[size];
223
224         fprintf(stderr, "\nCorrupting...\n");
225
226         for(int i = 0; i < 1000; i++) {
227                 int loc;
228                 memcpy(tmp, buf, size);
229
230                 /* Corrupt random _non-value_ location. */
231                 do { loc = random() % size; } while(tmp[loc] >= 70);
232                 do { tmp[loc] = buf[loc] ^ random(); } while(
233                         (tmp[loc] == buf[loc])
234                         || (buf[loc] == 0 && tmp[loc] == 0x80));
235
236                 fprintf(stderr, "\nTry %d: corrupting byte %d (%d->%d)\n",
237                         i, loc, buf[loc], tmp[loc]);
238
239                 check(0, tmp, size, size);
240         }
241 }
242
243 int
244 main(int ac, char **av) {
245
246         (void)ac;       /* Unused argument */
247         (void)av;       /* Unused argument */
248
249         check(1, buf1, sizeof(buf1) + 20, sizeof(buf1));
250         check(0, buf2, sizeof(buf2) + 1, 5);
251         check(1, buf3, sizeof(buf3) + 1, sizeof(buf3));
252         check(1, buf4, sizeof(buf4), sizeof(buf4));
253         check(1, buf5, sizeof(buf5), sizeof(buf5));
254         check(1, buf5, sizeof(buf5) + 1, sizeof(buf5));
255         check(0, buf5, sizeof(buf5) - 1, sizeof(buf5));
256
257         check_xer(buf1, sizeof(buf1), "<T><s>xyz</s><i>96</i></T>");
258         check_xer(buf3, sizeof(buf3), "<T><s>xyz</s><i>96</i><b><true/></b></T>");
259
260         fprintf(stderr, "\nPseudo-random buffer corruptions must fail\n");
261         try_corrupt(buf1, sizeof(buf1));
262
263         return 0;
264 }