NativeEnumerated.c vars NULL init and check
[com/asn1c.git] / tests / tests-skeletons / check-OIDs.c
1 #include <stdio.h>
2 #include <assert.h>
3 #include <errno.h>
4 #include <sys/time.h>
5
6 #include <OBJECT_IDENTIFIER.h>
7 #include <RELATIVE-OID.h>
8
9 static int
10 _print(const void *buffer, size_t size, void *app_key) {
11         (void)app_key;
12         fwrite(buffer, size, 1, stdout);
13         return 0;
14 }
15
16 static void
17 check_OID(int lineno, uint8_t *buf, size_t len, unsigned *ck_buf, int ck_len) {
18         OBJECT_IDENTIFIER_t *oid;
19         asn_dec_rval_t rval;
20         uint32_t arcs[11];
21         int alen;
22         int i;
23
24         printf("%03d: Checking {", lineno);
25         for(i = 0; i < (int)len; i++) { printf("%s%02x", i?" ":"", buf[i]); }
26         printf("} against {");
27         for(i = 0; i < ck_len; i++) { printf("%s%u", i?" ":"", ck_buf[i]); }
28         printf("}\n");
29
30         oid = NULL;
31         rval = ber_decode(0, &asn_DEF_OBJECT_IDENTIFIER, (void *)&oid, buf, len);
32         assert(rval.code == RC_OK);
33
34         assert((ssize_t)oid->size == (ssize_t)len - 2);
35
36         /*
37          * Print the contents for visual debugging.
38          */
39         printf("OBJECT_IDENTIFIER_print() => ");
40         OBJECT_IDENTIFIER_print(&asn_DEF_OBJECT_IDENTIFIER, oid, 0, _print, 0);
41         printf("\n");
42
43         memset(arcs, 'A', sizeof(arcs));
44     alen =
45         OBJECT_IDENTIFIER_get_arcs(oid, arcs, sizeof(arcs) / sizeof(arcs[0]));
46     assert(alen > 0);
47
48         printf("OBJECT_IDENTIFIER_get_arcs() => {");
49         /*
50          * Make sure they are equivalent.
51          */
52         for(i = 0; i < alen; i++) {
53         printf(" %" PRIu32, arcs[i]);
54         if(alen == ck_len) {
55                         assert(arcs[i] == ck_buf[i]);
56                 }
57         }
58         printf(" }\n");
59         assert(alen == ck_len);
60
61         ASN_STRUCT_FREE(asn_DEF_OBJECT_IDENTIFIER, oid);
62 }
63
64 static void
65 check_ROID(int lineno, uint8_t *buf, size_t len, unsigned *ck_buf,
66            size_t ck_len) {
67     RELATIVE_OID_t *oid;
68         asn_dec_rval_t rval;
69         uint32_t arcs[10];
70         int alen;
71         size_t i;
72
73         printf("%03d: Checking {", lineno);
74         for(i = 0; i < len; i++) { printf("%s%02x", i?" ":"", buf[i]); }
75         printf("} against {");
76         for(i = 0; i < ck_len; i++) { printf("%s%u", i?" ":"", ck_buf[i]); }
77         printf("}\n");
78
79         oid = NULL;
80         rval = ber_decode(0, &asn_DEF_RELATIVE_OID, (void *)&oid, buf, len);
81         assert(rval.code == RC_OK);
82
83         assert((ssize_t)oid->size == (ssize_t)len - 2);
84
85         /*
86          * Print the contents for visual debugging.
87          */
88         printf("RELATIVE_OID_print() => ");
89         RELATIVE_OID_print(&asn_DEF_RELATIVE_OID, oid, 0, _print, 0);
90         printf("\n");
91
92         memset(arcs, 'A', sizeof(arcs));
93     alen = RELATIVE_OID_get_arcs(oid, arcs, sizeof(arcs) / sizeof(arcs[0]));
94     assert(alen > 0);
95         assert((size_t)alen == ck_len);
96
97         /*
98          * Make sure they are equivalent.
99          */
100         printf("RELATIVE_OID_get_arcs() => {");
101         for(i = 0; i < (size_t)alen; i++) {
102         printf(" %" PRIu32, arcs[i]);
103         assert(arcs[i] == ck_buf[i]);
104         }
105         printf(" }\n");
106         ASN_STRUCT_FREE(asn_DEF_RELATIVE_OID, oid);
107 }
108
109 static int
110 check_speed() {
111         uint8_t buf[] = { 0x80 | 7, 0x80 | 2, 0x80 | 3, 0x80 | 4, 13 };
112         int ret = 0;
113         int cycles = 100000000;
114         double a, b, c;
115         struct timeval tv;
116         uint32_t value;
117         int i;
118
119     ret = OBJECT_IDENTIFIER_get_single_arc(buf, sizeof(buf), &value);
120     assert(ret == 0);
121         assert(value == 0x7040c20d);
122
123         gettimeofday(&tv, 0);
124         a = tv.tv_sec + tv.tv_usec / 1000000.0;
125         for(i = 0; i < cycles; i++) {
126                 ret = OBJECT_IDENTIFIER_get_single_arc(buf, sizeof(buf), &value);
127         }
128         assert(ret == 0);
129         assert(value == 0x7040c20d);
130         gettimeofday(&tv, 0);
131         b = tv.tv_sec + tv.tv_usec / 1000000.0;
132         for(i = 0; i < cycles; i++) {
133         ret = OBJECT_IDENTIFIER_get_single_arc(buf, sizeof(buf), &value);
134     }
135         assert(ret == 0);
136         assert(value == 0x7040c20d);
137         gettimeofday(&tv, 0);
138         c = tv.tv_sec + tv.tv_usec / 1000000.0;
139
140         a = b - a;
141         b = c - b;
142         printf("Time for single_arc(): %f\n", a);
143         printf("Time for  get_arc_l(): %f\n", b);
144
145         return 0;
146 }
147
148 #define CHECK_PARSE(a, b) check_parse(__LINE__, a, b)
149 static void check_parse(int lineno, const char *oid_txt, int retval) {
150         int ret;
151         uint32_t arcs[2];
152         const char *p = oid_txt - 13;
153         assert(p < oid_txt);
154
155         ret = OBJECT_IDENTIFIER_parse_arcs(oid_txt, -1, arcs, 2, &p);
156         printf("%03d: [%s] => %d == %d\n", lineno, oid_txt, ret, retval);
157         assert(ret == retval);
158         assert(p >= oid_txt);
159 }
160
161 static void
162 check_xer(int lineno, asn_TYPE_descriptor_t *td, ssize_t expect_arcs, char *xer,
163           const asn_oid_arc_t *expected_arcs) {
164     asn_dec_rval_t rc;
165     void *st = 0;
166     uint32_t arcs[10];
167     ssize_t got_arcs;
168     ssize_t i;
169
170     printf("%03d: [%s] => ", lineno, xer);
171     fflush(stdout);
172     rc = td->op->xer_decoder(0, td, (void **)&st, "t", xer, strlen(xer));
173     if(expect_arcs == -1) {
174                 if(rc.code != RC_OK) {
175                         printf("-1\n");
176                         ASN_STRUCT_FREE(*td, st);
177                         return;
178                 }
179         }
180         assert(rc.code == RC_OK);
181
182     if(td == &asn_DEF_OBJECT_IDENTIFIER) {
183         got_arcs = OBJECT_IDENTIFIER_get_arcs(st, arcs,
184                                               sizeof(arcs) / sizeof(arcs[0]));
185     } else if(td == &asn_DEF_RELATIVE_OID) {
186         got_arcs =
187             RELATIVE_OID_get_arcs(st, arcs, sizeof(arcs) / sizeof(arcs[0]));
188     } else {
189         assert(!"Unreachable");
190     }
191         assert(got_arcs < 10);
192         if(expect_arcs == -1) {
193                 assert(got_arcs == -1);
194                 ASN_STRUCT_FREE(*td, st);
195                 return;
196         }
197         for(i = 0; i < got_arcs; i++) {
198                 if(i) printf(".");
199         printf("%" PRIu32, arcs[i]);
200         if(arcs[i] != expected_arcs[i]) {
201             printf(" != %" PRIu32 "\n", expected_arcs[i]);
202         }
203         assert(arcs[i] == expected_arcs[i]);
204         }
205         printf(": %zd == %zd\n", got_arcs, expect_arcs);
206         assert(got_arcs == expect_arcs);
207         ASN_STRUCT_FREE(*td, st);
208 }
209
210 #define CHECK_OID(n)                                            \
211     check_OID(__LINE__, buf##n, sizeof(buf##n), buf##n##_check, \
212               sizeof(buf##n##_check) / sizeof(buf##n##_check[0]))
213 #define CHECK_ROID(n)                                            \
214     check_ROID(__LINE__, buf##n, sizeof(buf##n), buf##n##_check, \
215                sizeof(buf##n##_check) / sizeof(buf##n##_check[0]))
216
217 static void
218 check_binary_parsing() {
219
220     /* {0 0} */
221         uint8_t buf0[] = {
222                 0x06,   /* OBJECT IDENTIFIER */
223                 0x01,   /* Length */
224                 0x00
225         };
226         uint32_t buf0_check[] = { 0, 0 };
227
228     /* {joint-iso-itu-t 230 3} */
229         uint8_t buf1[] = {
230                 0x06,   /* OBJECT IDENTIFIER */
231                 0x03,   /* Length */
232                 0x82, 0x36, 0x03
233         };
234         uint32_t buf1_check[] = { 2, 230, 3 };
235
236         /* {joint-iso-itu-t 42 } */
237         uint8_t buf2[] = {
238                 0x06,   /* OBJECT IDENTIFIER */
239                 0x01,   /* Length */
240                 0x7A
241         };
242         uint32_t buf2_check[] = { 2, 42 };
243
244         /* {joint-iso-itu-t 25957 } */
245         uint8_t buf3[] = {
246                 0x06,   /* OBJECT IDENTIFIER */
247                 0x03,   /* Length */
248                 0x81, 0x80 + 0x4B, 0x35
249         };
250         uint32_t buf3_check[] = { 2, 25957 };
251
252         /* { jounsigned-iso-itu-t 2 1 1 } */
253         uint8_t buf4[] = {
254                 0x06,   /* OBJECT IDENTIFIER */
255                 0x03,   /* Length */
256                 0x52, 0x01, 0x01
257         };
258         uint32_t buf4_check[] = { 2, 2, 1, 1 };
259
260         /* { jounsigned-iso-itu-t 2 1 0 1 } */
261         uint8_t buf5[] = {
262                 0x06,   /* OBJECT IDENTIFIER */
263                 0x04,   /* Length */
264                 0x52, 0x01, 0x00, 0x01
265         };
266         uint32_t buf5_check[] = { 2, 2, 1, 0, 1 };
267
268         /* {joint-iso-itu-t 25957 } */
269         uint8_t buf6[] = {
270                 0x06,   /* OBJECT IDENTIFIER */
271                 0x0c,   /* Length */
272                 0x2a, 0x03, 0x01, 0x01, 0x01, 0x81, 0xaa, 0x11, 0x03, 0x05, 0x01, 0x01
273         };
274         uint32_t buf6_check[] = { 1, 2, 3, 1, 1, 1, 21777, 3, 5, 1, 1 };
275
276         /* {0 0} */
277         uint8_t buf10[] = {
278                 0x0D,   /* RELATIVE-OID */
279                 0x01,   /* Length */
280                 0x00
281         };
282         uint32_t buf10_check[] = { 0 };
283
284     /* {0 0} */
285         uint8_t buf11[] = {
286                 0x0D,   /* RELATIVE-OID */
287                 0x02,   /* Length */
288                 0x00, 0x00
289         };
290         uint32_t buf11_check[] = { 0, 0 };
291
292         /* {8571 3 2} */
293         uint8_t buf12[] = {
294                 0x0D,   /* RELATIVE-OID */
295                 0x04,   /* Length */
296                 0xC2, 0x7B, 0x03, 0x02
297         };
298         uint32_t buf12_check[] = { 8571, 3, 2 };
299
300         CHECK_OID(0);
301         CHECK_OID(1);
302         CHECK_OID(2);
303         CHECK_OID(3);
304         CHECK_OID(4);
305         CHECK_OID(5);
306         CHECK_OID(6);
307
308         CHECK_ROID(10);
309         CHECK_ROID(11);
310         CHECK_ROID(12);
311 }
312
313 static void
314 check_text_parsing() {
315     CHECK_PARSE("", 0);
316     CHECK_PARSE(" ", 0);
317         CHECK_PARSE(".", -1);
318         CHECK_PARSE(" .", -1);
319         CHECK_PARSE(".1", -1);
320         CHECK_PARSE("1.", -1);
321         CHECK_PARSE("1. ", -1);
322         CHECK_PARSE(".1. ", -1);
323         CHECK_PARSE(" .1. ", -1);
324         CHECK_PARSE(" 1", 1);
325         CHECK_PARSE(" 1.2", 2);
326         CHECK_PARSE(" 1.", -1);
327         CHECK_PARSE(" 1. ", -1);
328         CHECK_PARSE("1. ", -1);
329         CHECK_PARSE("1.2", 2);
330         CHECK_PARSE("1.2 ", 2);
331         CHECK_PARSE("1.2  ", 2);
332         CHECK_PARSE("  1.2  ", 2);
333         CHECK_PARSE("1. 2", -1);
334         CHECK_PARSE("1 .2", -1);
335         CHECK_PARSE(" 1 .2", -1);
336         CHECK_PARSE(" 1 .2 ", -1);
337         CHECK_PARSE("1 .2 ", -1);
338         CHECK_PARSE("1.+1", -1);
339         CHECK_PARSE("2.0", 2);
340         CHECK_PARSE("2.1", 2);
341         CHECK_PARSE("10.30.234.234", 4);
342         CHECK_PARSE("10.30.234.234 ", 4);
343         CHECK_PARSE("10.30.234. 234 ", -1);
344         CHECK_PARSE("10.30.234.234.", -1);
345         CHECK_PARSE("1.2000000000.3", 3);
346         CHECK_PARSE("1.2147483647.3", 3);
347     CHECK_PARSE("1.4294967295.3", 3);
348     CHECK_PARSE("1.4294967296.3", -1); /* overflow on ILP32 */
349     CHECK_PARSE("1.3000000000.3", 3);
350     CHECK_PARSE("1.4000000000.3", 3);
351     CHECK_PARSE("1.5000000000.3", -1);
352     CHECK_PARSE("1.6000000000.3", -1);
353     CHECK_PARSE("1.9000000000.3", -1);
354         CHECK_PARSE("1.900a0000000.3", -1);
355         CHECK_PARSE("1.900a.3", -1);
356 }
357
358 #define CHECK_XER(a, b, c, data) check_xer(__LINE__, &asn_DEF_##a, b, c, data)
359
360 static void
361 check_xer_parsing() {
362     asn_oid_arc_t zero_zero[] = {0, 0};
363     asn_oid_arc_t zero_one[] = {0, 1};
364     asn_oid_arc_t one_zero[] = {1, 0};
365     asn_oid_arc_t one_one[] = {1, 1};
366     asn_oid_arc_t one_two[] = {1, 2};
367     asn_oid_arc_t two_one[] = {2, 1};
368     asn_oid_arc_t one_two_three[] = {1, 2,3};
369
370     CHECK_XER(RELATIVE_OID, -1, "<t></t>", 0);
371         CHECK_XER(RELATIVE_OID, -1, "<t>1.</t>", 0);
372     CHECK_XER(RELATIVE_OID, -1, "<t>2.1.</t>", 0);
373     CHECK_XER(RELATIVE_OID, 2, "<t>0.0</t>", zero_zero);
374     CHECK_XER(RELATIVE_OID, 2, "<t>0.1</t>", zero_one);
375     CHECK_XER(RELATIVE_OID, 2, "<t>1.0</t>", one_zero);
376     CHECK_XER(RELATIVE_OID, 2, "<t>1.2</t>", one_two);
377     CHECK_XER(RELATIVE_OID, -1, "<t>1.-2</t>", 0);
378     CHECK_XER(RELATIVE_OID, -1, "<t>1.+2</t>", 0);
379     CHECK_XER(RELATIVE_OID, 3, "<t>1.2.3</t>", one_two_three);
380     CHECK_XER(RELATIVE_OID, 3, "<t> 1.2.3 </t>", one_two_three);
381     CHECK_XER(RELATIVE_OID, -1, "<t>1.2.3 1</t>", 0);
382         CHECK_XER(RELATIVE_OID, 2, "<t>2.1</t>", two_one);
383
384         CHECK_XER(OBJECT_IDENTIFIER, -1, "<t></t>", 0);
385         CHECK_XER(OBJECT_IDENTIFIER, -1, "<t>1</t>", 0);
386         CHECK_XER(OBJECT_IDENTIFIER, -1, "<t>1.</t>", 0);
387         CHECK_XER(OBJECT_IDENTIFIER, -1, "<t>2.1.</t>", 0);
388     CHECK_XER(OBJECT_IDENTIFIER, 2, "<t>0.0</t>", zero_zero);
389     CHECK_XER(OBJECT_IDENTIFIER, 2, "<t>0.1</t>", zero_one);
390     CHECK_XER(OBJECT_IDENTIFIER, 2, "<t>1.0</t>", one_zero);
391     CHECK_XER(OBJECT_IDENTIFIER, 2, "<t>1.1</t>", one_one);
392     CHECK_XER(OBJECT_IDENTIFIER, 2, "<t>1.2</t>", one_two);
393     CHECK_XER(OBJECT_IDENTIFIER, -1, "<t>1.-2</t>", 0);
394     CHECK_XER(OBJECT_IDENTIFIER, -1, "<t>1.+2</t>", 0);
395     CHECK_XER(OBJECT_IDENTIFIER, 3, "<t>1.2.3</t>", one_two_three);
396     CHECK_XER(OBJECT_IDENTIFIER, 3, "<t> 1.2.3 </t>", one_two_three);
397     CHECK_XER(OBJECT_IDENTIFIER, -1, "<t>1.2.3 1</t>", 0);
398     CHECK_XER(OBJECT_IDENTIFIER, 2, "<t> 2.1 </t>", two_one);
399 }
400
401 int
402 main() {
403     check_binary_parsing();
404     check_text_parsing();
405     check_xer_parsing();
406
407         if(getenv("CHECK_SPEED")) {
408                 /* Useful for developers only */
409                 check_speed();
410         }
411
412         return 0;
413 }
414