Home | History | Annotate | Download | only in test
      1 /*
      2  * Copyright (c) 2015 SPUDlib authors.  See LICENSE file.
      3  */
      4 #include <stdlib.h>
      5 #include <stdint.h>
      6 #include <stdbool.h>
      7 #include <stdio.h>
      8 #include <assert.h>
      9 #include <string.h>
     10 
     11 #include "cn-cbor/cn-cbor.h"
     12 
     13 #define CTEST_MAIN
     14 #include "ctest.h"
     15 
     16 int main(int argc, const char *argv[])
     17 {
     18     return ctest_main(argc, argv);
     19 }
     20 
     21 #ifdef USE_CBOR_CONTEXT
     22 #define CONTEXT_NULL , NULL
     23 #define CONTEXT_NULL_COMMA NULL,
     24 #else
     25 #define CONTEXT_NULL
     26 #define CONTEXT_NULL_COMMA
     27 #endif
     28 
     29 typedef struct _buffer {
     30     size_t sz;
     31     unsigned char *ptr;
     32 } buffer;
     33 
     34 static bool parse_hex(char *inp, buffer *b)
     35 {
     36     int len = strlen(inp);
     37     size_t i;
     38     if (len%2 != 0) {
     39         b->sz = -1;
     40         b->ptr = NULL;
     41         return false;
     42     }
     43     b->sz  = len / 2;
     44     b->ptr = malloc(b->sz);
     45     for (i=0; i<b->sz; i++) {
     46         sscanf(inp+(2*i), "%02hhx", &b->ptr[i]);
     47     }
     48     return true;
     49 }
     50 
     51 CTEST(cbor, error)
     52 {
     53     ASSERT_STR(cn_cbor_error_str[CN_CBOR_NO_ERROR], "CN_CBOR_NO_ERROR");
     54     ASSERT_STR(cn_cbor_error_str[CN_CBOR_ERR_OUT_OF_DATA], "CN_CBOR_ERR_OUT_OF_DATA");
     55     ASSERT_STR(cn_cbor_error_str[CN_CBOR_ERR_NOT_ALL_DATA_CONSUMED], "CN_CBOR_ERR_NOT_ALL_DATA_CONSUMED");
     56     ASSERT_STR(cn_cbor_error_str[CN_CBOR_ERR_ODD_SIZE_INDEF_MAP], "CN_CBOR_ERR_ODD_SIZE_INDEF_MAP");
     57     ASSERT_STR(cn_cbor_error_str[CN_CBOR_ERR_BREAK_OUTSIDE_INDEF], "CN_CBOR_ERR_BREAK_OUTSIDE_INDEF");
     58     ASSERT_STR(cn_cbor_error_str[CN_CBOR_ERR_MT_UNDEF_FOR_INDEF], "CN_CBOR_ERR_MT_UNDEF_FOR_INDEF");
     59     ASSERT_STR(cn_cbor_error_str[CN_CBOR_ERR_RESERVED_AI], "CN_CBOR_ERR_RESERVED_AI");
     60     ASSERT_STR(cn_cbor_error_str[CN_CBOR_ERR_WRONG_NESTING_IN_INDEF_STRING], "CN_CBOR_ERR_WRONG_NESTING_IN_INDEF_STRING");
     61     ASSERT_STR(cn_cbor_error_str[CN_CBOR_ERR_INVALID_PARAMETER], "CN_CBOR_ERR_INVALID_PARAMETER");
     62     ASSERT_STR(cn_cbor_error_str[CN_CBOR_ERR_OUT_OF_MEMORY], "CN_CBOR_ERR_OUT_OF_MEMORY");
     63     ASSERT_STR(cn_cbor_error_str[CN_CBOR_ERR_FLOAT_NOT_SUPPORTED], "CN_CBOR_ERR_FLOAT_NOT_SUPPORTED");
     64 }
     65 
     66 CTEST(cbor, parse)
     67 {
     68     cn_cbor_errback err;
     69     char *tests[] = {
     70         "00",         // 0
     71         "01",         // 1
     72         "17",         // 23
     73         "1818",       // 24
     74         "190100",     // 256
     75         "1a00010000", // 65536
     76         "1b0000000100000000", // 4294967296
     77         "20",         // -1
     78         "37",         // -24
     79         "3818",       // -25
     80         "390100",     // -257
     81         "3a00010000", // -65537
     82         "3b0000000100000000", // -4294967297
     83         "4161",     // h"a"
     84         "6161",     // "a"
     85         "80",       // []
     86         "8100",     // [0]
     87         "820102",   // [1,2]
     88         "818100",   // [[0]]
     89         "a1616100",	// {"a":0}
     90         "d8184100", // tag
     91         "f4",	      // false
     92         "f5",	      // true
     93         "f6",	      // null
     94         "f7",	      // undefined
     95         "f8ff",     // simple(255)
     96 #ifndef CBOR_NO_FLOAT
     97         "f93c00",     // 1.0
     98         "f9bc00",     // -1.0
     99         "f903ff",     // 6.097555160522461e-05
    100         "f90400",     // 6.103515625e-05
    101         "f907ff",     // 0.00012201070785522461
    102         "f90800",     // 0.0001220703125
    103         "fa47800000", // 65536.0
    104         "fb3ff199999999999a",     // 1.1
    105         "f97e00",   // NaN
    106 #endif /* CBOR_NO_FLOAT */
    107         "5f42010243030405ff",     // (_ h'0102', h'030405')
    108         "7f61616161ff",           // (_ "a", "a")
    109         "9fff",                   // [_ ]
    110         "9f9f9fffffff",           // [_ [_ [_ ]]]
    111         "9f009f00ff00ff",         // [_ 0, [_ 0], 0]
    112         "bf61610161629f0203ffff", // {_ "a": 1, "b": [_ 2, 3]}
    113     };
    114     cn_cbor *cb;
    115     buffer b;
    116     size_t i;
    117     unsigned char encoded[1024];
    118     ssize_t enc_sz;
    119 
    120     for (i=0; i<sizeof(tests)/sizeof(char*); i++) {
    121         ASSERT_TRUE(parse_hex(tests[i], &b));
    122         err.err = CN_CBOR_NO_ERROR;
    123         cb = cn_cbor_decode(b.ptr, b.sz CONTEXT_NULL, &err);
    124         //CTEST_LOG("%s: %s", tests[i], cn_cbor_error_str[err.err]);
    125         ASSERT_EQUAL(err.err, CN_CBOR_NO_ERROR);
    126         ASSERT_NOT_NULL(cb);
    127 
    128         enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb);
    129         ASSERT_DATA(b.ptr, b.sz, encoded, enc_sz);
    130         free(b.ptr);
    131         cn_cbor_free(cb CONTEXT_NULL);
    132     }
    133 }
    134 
    135 
    136 CTEST(cbor, parse_normalize)
    137 {
    138     cn_cbor_errback err;
    139     char *basic_tests[] = {
    140       "00", "00",                       // 0
    141       "1800", "00",
    142       "1818", "1818",
    143       "190000", "00",
    144       "190018", "1818",
    145       "1a00000000", "00",
    146       "1b0000000000000000", "00",
    147       "20", "20",                       // -1
    148       "3800", "20",
    149       "c600", "c600",                   // 6(0) (undefined tag)
    150       "d80600", "c600",
    151       "d9000600", "c600",
    152     };
    153     char *float_tests[] = {
    154       "fb3ff0000000000000", "f93c00",   // 1.0
    155       "fbbff0000000000000", "f9bc00",   // -1.0
    156       "fb40f86a0000000000", "fa47c35000", // 100000.0
    157       "fb7ff8000000000000", "f97e00",   // NaN
    158       "fb3e70000000000000", "f90001",   // 5.960464477539063e-08
    159       "fb3e78000000000000", "fa33c00000", //  8.940696716308594e-08
    160       "fb3e80000000000000", "f90002",   // 1.1920928955078125e-07
    161     };
    162     cn_cbor *cb;
    163     buffer b, b2;
    164     size_t i;
    165     unsigned char encoded[1024];
    166     ssize_t enc_sz;
    167 
    168     for (i=0; i<sizeof(basic_tests)/sizeof(char*); i+=2) {
    169         ASSERT_TRUE(parse_hex(basic_tests[i], &b));
    170         ASSERT_TRUE(parse_hex(basic_tests[i+1], &b2));
    171         err.err = CN_CBOR_NO_ERROR;
    172         cb = cn_cbor_decode(b.ptr, b.sz CONTEXT_NULL, &err);
    173         CTEST_LOG("%s: %s", basic_tests[i], cn_cbor_error_str[err.err]);
    174         ASSERT_EQUAL(err.err, CN_CBOR_NO_ERROR);
    175         ASSERT_NOT_NULL(cb);
    176 
    177         enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb);
    178         ASSERT_DATA(b2.ptr, b2.sz, encoded, enc_sz);
    179         free(b.ptr);
    180         free(b2.ptr);
    181         cn_cbor_free(cb CONTEXT_NULL);
    182     }
    183 
    184     for (i=0; i<sizeof(float_tests)/sizeof(char*); i+=2) {
    185         ASSERT_TRUE(parse_hex(float_tests[i], &b));
    186         ASSERT_TRUE(parse_hex(float_tests[i+1], &b2));
    187         err.err = CN_CBOR_NO_ERROR;
    188         cb = cn_cbor_decode(b.ptr, b.sz CONTEXT_NULL, &err);
    189         CTEST_LOG("%s: %s", float_tests[i], cn_cbor_error_str[err.err]);
    190 #ifndef CBOR_NO_FLOAT
    191         ASSERT_EQUAL(err.err, CN_CBOR_NO_ERROR);
    192         ASSERT_NOT_NULL(cb);
    193 #else /* CBOR_NO_FLOAT */
    194         ASSERT_EQUAL(err.err, CN_CBOR_ERR_FLOAT_NOT_SUPPORTED);
    195         ASSERT_NULL(cb);
    196 #endif /* CBOR_NO_FLOAT */
    197 
    198         /* enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb); */
    199         /* ASSERT_DATA(b2.ptr, b2.sz, encoded, enc_sz); */
    200         free(b.ptr);
    201         free(b2.ptr);
    202         cn_cbor_free(cb CONTEXT_NULL);
    203     }
    204 }
    205 
    206 typedef struct _cbor_failure
    207 {
    208     char *hex;
    209     cn_cbor_error err;
    210 } cbor_failure;
    211 
    212 CTEST(cbor, fail)
    213 {
    214     cn_cbor_errback err;
    215     cbor_failure tests[] = {
    216         {"81", CN_CBOR_ERR_OUT_OF_DATA},
    217         {"0000", CN_CBOR_ERR_NOT_ALL_DATA_CONSUMED},
    218         {"bf00ff", CN_CBOR_ERR_ODD_SIZE_INDEF_MAP},
    219         {"ff", CN_CBOR_ERR_BREAK_OUTSIDE_INDEF},
    220         {"1f", CN_CBOR_ERR_MT_UNDEF_FOR_INDEF},
    221         {"1c", CN_CBOR_ERR_RESERVED_AI},
    222         {"7f4100", CN_CBOR_ERR_WRONG_NESTING_IN_INDEF_STRING},
    223     };
    224     cn_cbor *cb;
    225     buffer b;
    226     size_t i;
    227     uint8_t buf[10];
    228     cn_cbor inv = {CN_CBOR_INVALID, 0, {0}, 0, NULL, NULL, NULL, NULL};
    229 
    230     ASSERT_EQUAL(-1, cn_cbor_encoder_write(buf, 0, sizeof(buf), &inv));
    231 
    232     for (i=0; i<sizeof(tests)/sizeof(cbor_failure); i++) {
    233         ASSERT_TRUE(parse_hex(tests[i].hex, &b));
    234         cb = cn_cbor_decode(b.ptr, b.sz CONTEXT_NULL, &err);
    235         ASSERT_NULL(cb);
    236         ASSERT_EQUAL(err.err, tests[i].err);
    237 
    238         free(b.ptr);
    239         cn_cbor_free(cb CONTEXT_NULL);
    240     }
    241 }
    242 
    243 // Decoder loses float size information
    244 CTEST(cbor, float)
    245 {
    246 #ifndef CBOR_NO_FLOAT
    247     cn_cbor_errback err;
    248     char *tests[] = {
    249         "f90001", // 5.960464477539063e-08
    250         "f9c400", // -4.0
    251         "fa47c35000", // 100000.0
    252         "f97e00", // Half NaN, half beast
    253         "f9fc00", // -Inf
    254         "f97c00", // Inf
    255     };
    256     cn_cbor *cb;
    257     buffer b;
    258     size_t i;
    259     unsigned char encoded[1024];
    260     ssize_t enc_sz;
    261 
    262     for (i=0; i<sizeof(tests)/sizeof(char*); i++) {
    263         ASSERT_TRUE(parse_hex(tests[i], &b));
    264         cb = cn_cbor_decode(b.ptr, b.sz CONTEXT_NULL, &err);
    265         ASSERT_NOT_NULL(cb);
    266 
    267         enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), cb);
    268         ASSERT_DATA(b.ptr, b.sz, encoded, enc_sz);
    269 
    270         free(b.ptr);
    271         cn_cbor_free(cb CONTEXT_NULL);
    272     }
    273 #endif /* CBOR_NO_FLOAT */
    274 }
    275 
    276 CTEST(cbor, getset)
    277 {
    278     buffer b;
    279     cn_cbor *cb;
    280     cn_cbor *val;
    281     cn_cbor_errback err;
    282 
    283     ASSERT_TRUE(parse_hex("a40000436363630262626201616100", &b));
    284     cb = cn_cbor_decode(b.ptr, b.sz CONTEXT_NULL, &err);
    285     ASSERT_NOT_NULL(cb);
    286     val = cn_cbor_mapget_string(cb, "a");
    287     ASSERT_NOT_NULL(val);
    288     val = cn_cbor_mapget_string(cb, "bb");
    289     ASSERT_NOT_NULL(val);
    290     val = cn_cbor_mapget_string(cb, "ccc");
    291     ASSERT_NOT_NULL(val);
    292     val = cn_cbor_mapget_string(cb, "b");
    293     ASSERT_NULL(val);
    294     free(b.ptr);
    295     cn_cbor_free(cb CONTEXT_NULL);
    296 
    297     ASSERT_TRUE(parse_hex("a3616100006161206162", &b));
    298     cb = cn_cbor_decode(b.ptr, b.sz CONTEXT_NULL, &err);
    299     ASSERT_NOT_NULL(cb);
    300     val = cn_cbor_mapget_int(cb, 0);
    301     ASSERT_NOT_NULL(val);
    302     val = cn_cbor_mapget_int(cb, -1);
    303     ASSERT_NOT_NULL(val);
    304     val = cn_cbor_mapget_int(cb, 1);
    305     ASSERT_NULL(val);
    306     free(b.ptr);
    307     cn_cbor_free(cb CONTEXT_NULL);
    308 
    309     ASSERT_TRUE(parse_hex("8100", &b));
    310     cb = cn_cbor_decode(b.ptr, b.sz CONTEXT_NULL, &err);
    311     ASSERT_NOT_NULL(cb);
    312     val = cn_cbor_index(cb, 0);
    313     ASSERT_NOT_NULL(val);
    314     val = cn_cbor_index(cb, 1);
    315     ASSERT_NULL(val);
    316     val = cn_cbor_index(cb, -1);
    317     ASSERT_NULL(val);
    318     free(b.ptr);
    319     cn_cbor_free(cb CONTEXT_NULL);
    320 }
    321 
    322 CTEST(cbor, create)
    323 {
    324     cn_cbor_errback err;
    325     const cn_cbor* val;
    326     const char* data = "abc";
    327     cn_cbor *cb_map = cn_cbor_map_create(CONTEXT_NULL_COMMA &err);
    328     cn_cbor *cb_int;
    329     cn_cbor *cb_data;
    330 
    331     ASSERT_NOT_NULL(cb_map);
    332     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
    333 
    334     cb_int = cn_cbor_int_create(256 CONTEXT_NULL, &err);
    335     ASSERT_NOT_NULL(cb_int);
    336     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
    337 
    338     cb_data = cn_cbor_data_create((const uint8_t*)data, 4 CONTEXT_NULL, &err);
    339     ASSERT_NOT_NULL(cb_data);
    340     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
    341 
    342     cn_cbor_mapput_int(cb_map, 5, cb_int CONTEXT_NULL, &err);
    343     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
    344     ASSERT_TRUE(cb_map->length == 2);
    345 
    346     cn_cbor_mapput_int(cb_map, -7, cb_data CONTEXT_NULL, &err);
    347     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
    348     ASSERT_TRUE(cb_map->length == 4);
    349 
    350     cn_cbor_mapput_string(cb_map, "foo",
    351                           cn_cbor_string_create(data CONTEXT_NULL, &err)
    352                           CONTEXT_NULL, &err);
    353     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
    354     ASSERT_TRUE(cb_map->length == 6);
    355 
    356     cn_cbor_map_put(cb_map,
    357                     cn_cbor_string_create("bar" CONTEXT_NULL, &err),
    358                     cn_cbor_string_create("qux" CONTEXT_NULL, &err),
    359                     &err);
    360     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
    361     ASSERT_TRUE(cb_map->length == 8);
    362 
    363     val = cn_cbor_mapget_int(cb_map, 5);
    364     ASSERT_NOT_NULL(val);
    365     ASSERT_TRUE(val->v.sint == 256);
    366 
    367     val = cn_cbor_mapget_int(cb_map, -7);
    368     ASSERT_NOT_NULL(val);
    369     ASSERT_STR(val->v.str, "abc");
    370 
    371     cn_cbor_free(cb_map CONTEXT_NULL);
    372 }
    373 
    374 CTEST(cbor, map_errors)
    375 {
    376     cn_cbor_errback err;
    377     cn_cbor *ci;
    378     ci = cn_cbor_int_create(65536, CONTEXT_NULL_COMMA &err);
    379     cn_cbor_mapput_int(ci, -5, NULL, CONTEXT_NULL_COMMA &err);
    380     ASSERT_EQUAL(err.err, CN_CBOR_ERR_INVALID_PARAMETER);
    381     cn_cbor_mapput_string(ci, "foo", NULL, CONTEXT_NULL_COMMA &err);
    382     ASSERT_EQUAL(err.err, CN_CBOR_ERR_INVALID_PARAMETER);
    383     cn_cbor_map_put(ci, NULL, NULL, &err);
    384 }
    385 
    386 CTEST(cbor, array)
    387 {
    388     cn_cbor_errback err;
    389     cn_cbor *a = cn_cbor_array_create(CONTEXT_NULL_COMMA &err);
    390     ASSERT_NOT_NULL(a);
    391     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
    392     ASSERT_EQUAL(a->length, 0);
    393 
    394     cn_cbor_array_append(a, cn_cbor_int_create(256, CONTEXT_NULL_COMMA &err), &err);
    395     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
    396     ASSERT_EQUAL(a->length, 1);
    397 
    398     cn_cbor_array_append(a, cn_cbor_string_create("five", CONTEXT_NULL_COMMA &err), &err);
    399     ASSERT_TRUE(err.err == CN_CBOR_NO_ERROR);
    400     ASSERT_EQUAL(a->length, 2);
    401 }
    402 
    403 CTEST(cbor, array_errors)
    404 {
    405     cn_cbor_errback err;
    406     cn_cbor *ci = cn_cbor_int_create(12, CONTEXT_NULL_COMMA &err);
    407     cn_cbor_array_append(NULL, ci, &err);
    408     ASSERT_EQUAL(err.err, CN_CBOR_ERR_INVALID_PARAMETER);
    409     cn_cbor_array_append(ci, NULL, &err);
    410     ASSERT_EQUAL(err.err, CN_CBOR_ERR_INVALID_PARAMETER);
    411 }
    412 
    413 CTEST(cbor, create_encode)
    414 {
    415   cn_cbor *map;
    416   cn_cbor *cdata;
    417   char data[] = "data";
    418   unsigned char encoded[1024];
    419   ssize_t enc_sz;
    420 
    421   map = cn_cbor_map_create(CONTEXT_NULL_COMMA NULL);
    422   ASSERT_NOT_NULL(map);
    423 
    424   cdata = cn_cbor_data_create((uint8_t*)data, sizeof(data)-1, CONTEXT_NULL_COMMA NULL);
    425   ASSERT_NOT_NULL(cdata);
    426 
    427   ASSERT_TRUE(cn_cbor_mapput_int(map, 0, cdata, CONTEXT_NULL_COMMA NULL));
    428   enc_sz = cn_cbor_encoder_write(encoded, 0, sizeof(encoded), map);
    429   ASSERT_EQUAL(7, enc_sz);
    430 }
    431