xref: /aosp_15_r20/external/cn-cbor/test/test.c (revision 254b1274ba1d768fbd68f5671e61c44001b5d4a8)
1*254b1274SAndroid Build Coastguard Worker #include <unistd.h>
2*254b1274SAndroid Build Coastguard Worker #include <stdio.h>
3*254b1274SAndroid Build Coastguard Worker #include <stdlib.h>
4*254b1274SAndroid Build Coastguard Worker #include <sys/stat.h>
5*254b1274SAndroid Build Coastguard Worker #include <fcntl.h>
6*254b1274SAndroid Build Coastguard Worker #include <string.h>
7*254b1274SAndroid Build Coastguard Worker 
8*254b1274SAndroid Build Coastguard Worker #include "cn-cbor/cn-cbor.h"
9*254b1274SAndroid Build Coastguard Worker 
10*254b1274SAndroid Build Coastguard Worker #ifdef USE_CBOR_CONTEXT
11*254b1274SAndroid Build Coastguard Worker #define CBOR_CONTEXT_PARAM , NULL
12*254b1274SAndroid Build Coastguard Worker #else
13*254b1274SAndroid Build Coastguard Worker #define CBOR_CONTEXT_PARAM
14*254b1274SAndroid Build Coastguard Worker #endif
15*254b1274SAndroid Build Coastguard Worker 
16*254b1274SAndroid Build Coastguard Worker #define ERROR(msg, p) fprintf(stderr, "ERROR: " msg " %s\n", (p));
17*254b1274SAndroid Build Coastguard Worker 
load_file(const char * filepath,unsigned char ** end)18*254b1274SAndroid Build Coastguard Worker static unsigned char* load_file(const char* filepath, unsigned char **end) {
19*254b1274SAndroid Build Coastguard Worker   struct stat st;
20*254b1274SAndroid Build Coastguard Worker   if (stat(filepath, &st)==-1) {
21*254b1274SAndroid Build Coastguard Worker     ERROR("can't find file", filepath);
22*254b1274SAndroid Build Coastguard Worker     return 0;
23*254b1274SAndroid Build Coastguard Worker   }
24*254b1274SAndroid Build Coastguard Worker   int fd=open(filepath, O_RDONLY);
25*254b1274SAndroid Build Coastguard Worker   if (fd==-1) {
26*254b1274SAndroid Build Coastguard Worker     ERROR("can't open file", filepath);
27*254b1274SAndroid Build Coastguard Worker     return 0;
28*254b1274SAndroid Build Coastguard Worker   }
29*254b1274SAndroid Build Coastguard Worker   unsigned char* text=malloc(st.st_size+1); // this is not going to be freed
30*254b1274SAndroid Build Coastguard Worker   if (st.st_size!=read(fd, text, st.st_size)) {
31*254b1274SAndroid Build Coastguard Worker     ERROR("can't read file", filepath);
32*254b1274SAndroid Build Coastguard Worker     close(fd);
33*254b1274SAndroid Build Coastguard Worker     return 0;
34*254b1274SAndroid Build Coastguard Worker   }
35*254b1274SAndroid Build Coastguard Worker   close(fd);
36*254b1274SAndroid Build Coastguard Worker   text[st.st_size]='\0';
37*254b1274SAndroid Build Coastguard Worker   *end = text + st.st_size;
38*254b1274SAndroid Build Coastguard Worker   return text;
39*254b1274SAndroid Build Coastguard Worker }
40*254b1274SAndroid Build Coastguard Worker 
dump(const cn_cbor * cb,char * out,char ** end,int indent)41*254b1274SAndroid Build Coastguard Worker static void dump(const cn_cbor* cb, char* out, char** end, int indent) {
42*254b1274SAndroid Build Coastguard Worker   if (!cb)
43*254b1274SAndroid Build Coastguard Worker     goto done;
44*254b1274SAndroid Build Coastguard Worker   int i;
45*254b1274SAndroid Build Coastguard Worker   cn_cbor* cp;
46*254b1274SAndroid Build Coastguard Worker   char finchar = ')';           /* most likely */
47*254b1274SAndroid Build Coastguard Worker 
48*254b1274SAndroid Build Coastguard Worker #define CPY(s, l) memcpy(out, s, l); out += l;
49*254b1274SAndroid Build Coastguard Worker #define OUT(s) CPY(s, sizeof(s)-1)
50*254b1274SAndroid Build Coastguard Worker #define PRF(f, a) out += sprintf(out, f, a)
51*254b1274SAndroid Build Coastguard Worker 
52*254b1274SAndroid Build Coastguard Worker   for (i = 0; i < indent; i++) *out++ = ' ';
53*254b1274SAndroid Build Coastguard Worker   switch (cb->type) {
54*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_TEXT_CHUNKED:   OUT("(_\n");                  goto sequence;
55*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_BYTES_CHUNKED:  OUT("(_\n\n");                goto sequence;
56*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_TAG:            PRF("%ld(\n", cb->v.sint);    goto sequence;
57*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_ARRAY:  finchar = ']'; OUT("[\n");            goto sequence;
58*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_MAP:    finchar = '}'; OUT("{\n");            goto sequence;
59*254b1274SAndroid Build Coastguard Worker   sequence:
60*254b1274SAndroid Build Coastguard Worker     for (cp = cb->first_child; cp; cp = cp->next) {
61*254b1274SAndroid Build Coastguard Worker       dump(cp, out, &out, indent+2);
62*254b1274SAndroid Build Coastguard Worker     }
63*254b1274SAndroid Build Coastguard Worker     for (i=0; i<indent; i++) *out++ = ' ';
64*254b1274SAndroid Build Coastguard Worker     *out++ = finchar;
65*254b1274SAndroid Build Coastguard Worker     break;
66*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_BYTES:   OUT("h'");
67*254b1274SAndroid Build Coastguard Worker     for (i=0; i<cb->length; i++)
68*254b1274SAndroid Build Coastguard Worker       PRF("%02x", cb->v.str[i] & 0xff);
69*254b1274SAndroid Build Coastguard Worker     *out++ = '\'';
70*254b1274SAndroid Build Coastguard Worker     break;
71*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_TEXT:    *out++ = '"';
72*254b1274SAndroid Build Coastguard Worker     CPY(cb->v.str, cb->length); /* should escape stuff */
73*254b1274SAndroid Build Coastguard Worker     *out++ = '"';
74*254b1274SAndroid Build Coastguard Worker     break;
75*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_NULL:   OUT("null");                      break;
76*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_TRUE:   OUT("true");                      break;
77*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_FALSE:  OUT("false");                     break;
78*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_UNDEF:  OUT("simple(23)");                break;
79*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_INT:    PRF("%ld", cb->v.sint);           break;
80*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_UINT:   PRF("%lu", cb->v.uint);           break;
81*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_DOUBLE: PRF("%e", cb->v.dbl);             break;
82*254b1274SAndroid Build Coastguard Worker   case CN_CBOR_SIMPLE: PRF("simple(%ld)", cb->v.sint);   break;
83*254b1274SAndroid Build Coastguard Worker   default:             PRF("???%d???", cb->type);        break;
84*254b1274SAndroid Build Coastguard Worker   }
85*254b1274SAndroid Build Coastguard Worker   *out++ = '\n';
86*254b1274SAndroid Build Coastguard Worker done:
87*254b1274SAndroid Build Coastguard Worker   *end = out;
88*254b1274SAndroid Build Coastguard Worker }
89*254b1274SAndroid Build Coastguard Worker 
90*254b1274SAndroid Build Coastguard Worker 
91*254b1274SAndroid Build Coastguard Worker const char *err_name[] = {
92*254b1274SAndroid Build Coastguard Worker   "CN_CBOR_NO_ERROR",
93*254b1274SAndroid Build Coastguard Worker   "CN_CBOR_ERR_OUT_OF_DATA",
94*254b1274SAndroid Build Coastguard Worker   "CN_CBOR_ERR_NOT_ALL_DATA_CONSUMED",
95*254b1274SAndroid Build Coastguard Worker   "CN_CBOR_ERR_ODD_SIZE_INDEF_MAP",
96*254b1274SAndroid Build Coastguard Worker   "CN_CBOR_ERR_BREAK_OUTSIDE_INDEF",
97*254b1274SAndroid Build Coastguard Worker   "CN_CBOR_ERR_MT_UNDEF_FOR_INDEF",
98*254b1274SAndroid Build Coastguard Worker   "CN_CBOR_ERR_RESERVED_AI",
99*254b1274SAndroid Build Coastguard Worker   "CN_CBOR_ERR_WRONG_NESTING_IN_INDEF_STRING",
100*254b1274SAndroid Build Coastguard Worker   "CN_CBOR_ERR_OUT_OF_MEMORY",
101*254b1274SAndroid Build Coastguard Worker   "CN_CBOR_ERR_FLOAT_NOT_SUPPORTED",
102*254b1274SAndroid Build Coastguard Worker };
103*254b1274SAndroid Build Coastguard Worker 
cn_cbor_decode_test(const unsigned char * buf,int len)104*254b1274SAndroid Build Coastguard Worker static void cn_cbor_decode_test(const unsigned char *buf, int len) {
105*254b1274SAndroid Build Coastguard Worker   struct cn_cbor_errback back;
106*254b1274SAndroid Build Coastguard Worker   const cn_cbor *ret = cn_cbor_decode(buf, len CBOR_CONTEXT_PARAM, &back);
107*254b1274SAndroid Build Coastguard Worker   if (ret)
108*254b1274SAndroid Build Coastguard Worker     printf("oops 1");
109*254b1274SAndroid Build Coastguard Worker   printf("%s at %d\n", err_name[back.err], back.pos);
110*254b1274SAndroid Build Coastguard Worker }
111*254b1274SAndroid Build Coastguard Worker 
main(void)112*254b1274SAndroid Build Coastguard Worker int main(void) {
113*254b1274SAndroid Build Coastguard Worker   char buf[100000];
114*254b1274SAndroid Build Coastguard Worker   unsigned char *end;
115*254b1274SAndroid Build Coastguard Worker   char *bufend;
116*254b1274SAndroid Build Coastguard Worker   unsigned char *s = load_file("cases.cbor", &end);
117*254b1274SAndroid Build Coastguard Worker   printf("%zd\n", end-s);
118*254b1274SAndroid Build Coastguard Worker   cn_cbor *cb = cn_cbor_decode(s, end-s CBOR_CONTEXT_PARAM, 0);
119*254b1274SAndroid Build Coastguard Worker   if (cb) {
120*254b1274SAndroid Build Coastguard Worker     dump(cb, buf, &bufend, 0);
121*254b1274SAndroid Build Coastguard Worker     *bufend = 0;
122*254b1274SAndroid Build Coastguard Worker     printf("%s\n", buf);
123*254b1274SAndroid Build Coastguard Worker     cn_cbor_free(cb CBOR_CONTEXT_PARAM);
124*254b1274SAndroid Build Coastguard Worker     cb = 0;                     /* for leaks testing */
125*254b1274SAndroid Build Coastguard Worker   }
126*254b1274SAndroid Build Coastguard Worker   cn_cbor_decode_test((const unsigned char*)"\xff", 1);    /* break outside indef */
127*254b1274SAndroid Build Coastguard Worker   cn_cbor_decode_test((const unsigned char*)"\x1f", 1);    /* mt undef for indef */
128*254b1274SAndroid Build Coastguard Worker   cn_cbor_decode_test((const unsigned char*)"\x00\x00", 2);    /* not all data consumed */
129*254b1274SAndroid Build Coastguard Worker   cn_cbor_decode_test((const unsigned char*)"\x81", 1);    /* out of data */
130*254b1274SAndroid Build Coastguard Worker   cn_cbor_decode_test((const unsigned char*)"\x1c", 1);    /* reserved ai */
131*254b1274SAndroid Build Coastguard Worker   cn_cbor_decode_test((const unsigned char*)"\xbf\x00\xff", 3);    /* odd size indef map */
132*254b1274SAndroid Build Coastguard Worker   cn_cbor_decode_test((const unsigned char*)"\x7f\x40\xff", 3);    /* wrong nesting in indef string */
133*254b1274SAndroid Build Coastguard Worker   system("leaks test");
134*254b1274SAndroid Build Coastguard Worker }
135*254b1274SAndroid Build Coastguard Worker 
136*254b1274SAndroid Build Coastguard Worker /* cn-cbor.c:112:    CN_CBOR_FAIL("out of memory"); */
137