cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

test-string-input-visitor.c (14159B)


      1/*
      2 * String Input Visitor unit-tests.
      3 *
      4 * Copyright (C) 2012 Red Hat Inc.
      5 *
      6 * Authors:
      7 *  Paolo Bonzini <pbonzini@redhat.com> (based on test-qobject-input-visitor)
      8 *
      9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
     10 * See the COPYING file in the top-level directory.
     11 */
     12
     13#include "qemu/osdep.h"
     14
     15#include "qemu-common.h"
     16#include "qapi/error.h"
     17#include "qapi/string-input-visitor.h"
     18#include "test-qapi-visit.h"
     19
     20typedef struct TestInputVisitorData {
     21    Visitor *v;
     22} TestInputVisitorData;
     23
     24static void visitor_input_teardown(TestInputVisitorData *data,
     25                                   const void *unused)
     26{
     27    if (data->v) {
     28        visit_free(data->v);
     29        data->v = NULL;
     30    }
     31}
     32
     33/* This is provided instead of a test setup function so that the JSON
     34   string used by the tests are kept in the test functions (and not
     35   int main()) */
     36static
     37Visitor *visitor_input_test_init(TestInputVisitorData *data,
     38                                 const char *string)
     39{
     40    visitor_input_teardown(data, NULL);
     41
     42    data->v = string_input_visitor_new(string);
     43    g_assert(data->v);
     44    return data->v;
     45}
     46
     47static void test_visitor_in_int(TestInputVisitorData *data,
     48                                const void *unused)
     49{
     50    int64_t res = 0, value = -42;
     51    Error *err = NULL;
     52    Visitor *v;
     53
     54    v = visitor_input_test_init(data, "-42");
     55
     56    visit_type_int(v, NULL, &res, &error_abort);
     57    g_assert_cmpint(res, ==, value);
     58
     59    v = visitor_input_test_init(data, "not an int");
     60
     61    visit_type_int(v, NULL, &res, &err);
     62    error_free_or_abort(&err);
     63
     64    v = visitor_input_test_init(data, "");
     65
     66    visit_type_int(v, NULL, &res, &err);
     67    error_free_or_abort(&err);
     68}
     69
     70static void check_ilist(Visitor *v, int64_t *expected, size_t n)
     71{
     72    int64List *res = NULL;
     73    int64List *tail;
     74    int i;
     75
     76    visit_type_int64List(v, NULL, &res, &error_abort);
     77    tail = res;
     78    for (i = 0; i < n; i++) {
     79        g_assert(tail);
     80        g_assert_cmpint(tail->value, ==, expected[i]);
     81        tail = tail->next;
     82    }
     83    g_assert(!tail);
     84
     85    qapi_free_int64List(res);
     86}
     87
     88static void check_ulist(Visitor *v, uint64_t *expected, size_t n)
     89{
     90    uint64List *res = NULL;
     91    uint64List *tail;
     92    int i;
     93
     94    visit_type_uint64List(v, NULL, &res, &error_abort);
     95    tail = res;
     96    for (i = 0; i < n; i++) {
     97        g_assert(tail);
     98        g_assert_cmpuint(tail->value, ==, expected[i]);
     99        tail = tail->next;
    100    }
    101    g_assert(!tail);
    102
    103    qapi_free_uint64List(res);
    104}
    105
    106static void test_visitor_in_intList(TestInputVisitorData *data,
    107                                    const void *unused)
    108{
    109    int64_t expect1[] = { 1, 2, 0, 2, 3, 4, 20, 5, 6, 7,
    110                          8, 9, 1, 2, 3, 4, 5, 6, 7, 8 };
    111    int64_t expect2[] = { 32767, -32768, -32767 };
    112    int64_t expect3[] = { INT64_MIN, INT64_MAX };
    113    int64_t expect4[] = { 1 };
    114    int64_t expect5[] = { INT64_MAX - 2,  INT64_MAX - 1, INT64_MAX };
    115    Error *err = NULL;
    116    int64List *res = NULL;
    117    Visitor *v;
    118    int64_t val;
    119
    120    /* Valid lists */
    121
    122    v = visitor_input_test_init(data, "1,2,0,2-4,20,5-9,1-8");
    123    check_ilist(v, expect1, ARRAY_SIZE(expect1));
    124
    125    v = visitor_input_test_init(data, "32767,-32768--32767");
    126    check_ilist(v, expect2, ARRAY_SIZE(expect2));
    127
    128    v = visitor_input_test_init(data,
    129                                "-9223372036854775808,9223372036854775807");
    130    check_ilist(v, expect3, ARRAY_SIZE(expect3));
    131
    132    v = visitor_input_test_init(data, "1-1");
    133    check_ilist(v, expect4, ARRAY_SIZE(expect4));
    134
    135    v = visitor_input_test_init(data,
    136                                "9223372036854775805-9223372036854775807");
    137    check_ilist(v, expect5, ARRAY_SIZE(expect5));
    138
    139    /* Value too large */
    140
    141    v = visitor_input_test_init(data, "9223372036854775808");
    142    visit_type_int64List(v, NULL, &res, &err);
    143    error_free_or_abort(&err);
    144    g_assert(!res);
    145
    146    /* Value too small */
    147
    148    v = visitor_input_test_init(data, "-9223372036854775809");
    149    visit_type_int64List(v, NULL, &res, &err);
    150    error_free_or_abort(&err);
    151    g_assert(!res);
    152
    153    /* Range not ascending */
    154
    155    v = visitor_input_test_init(data, "3-1");
    156    visit_type_int64List(v, NULL, &res, &err);
    157    error_free_or_abort(&err);
    158    g_assert(!res);
    159
    160    v = visitor_input_test_init(data, "9223372036854775807-0");
    161    visit_type_int64List(v, NULL, &res, &err);
    162    error_free_or_abort(&err);
    163    g_assert(!res);
    164
    165    /* Range too big (65536 is the limit against DOS attacks) */
    166
    167    v = visitor_input_test_init(data, "0-65536");
    168    visit_type_int64List(v, NULL, &res, &err);
    169    error_free_or_abort(&err);
    170    g_assert(!res);
    171
    172    /* Empty list */
    173
    174    v = visitor_input_test_init(data, "");
    175    visit_type_int64List(v, NULL, &res, &error_abort);
    176    g_assert(!res);
    177
    178    /* Not a list */
    179
    180    v = visitor_input_test_init(data, "not an int list");
    181
    182    visit_type_int64List(v, NULL, &res, &err);
    183    error_free_or_abort(&err);
    184    g_assert(!res);
    185
    186    /* Unvisited list tail */
    187
    188    v = visitor_input_test_init(data, "0,2-3");
    189
    190    visit_start_list(v, NULL, NULL, 0, &error_abort);
    191    visit_type_int64(v, NULL, &val, &error_abort);
    192    g_assert_cmpint(val, ==, 0);
    193    visit_type_int64(v, NULL, &val, &error_abort);
    194    g_assert_cmpint(val, ==, 2);
    195
    196    visit_check_list(v, &err);
    197    error_free_or_abort(&err);
    198    visit_end_list(v, NULL);
    199
    200    /* Visit beyond end of list */
    201
    202    v = visitor_input_test_init(data, "0");
    203
    204    visit_start_list(v, NULL, NULL, 0, &error_abort);
    205    visit_type_int64(v, NULL, &val, &err);
    206    g_assert_cmpint(val, ==, 0);
    207    visit_type_int64(v, NULL, &val, &err);
    208    error_free_or_abort(&err);
    209
    210    visit_check_list(v, &error_abort);
    211    visit_end_list(v, NULL);
    212}
    213
    214static void test_visitor_in_uintList(TestInputVisitorData *data,
    215                                     const void *unused)
    216{
    217    uint64_t expect1[] = { 1, 2, 0, 2, 3, 4, 20, 5, 6, 7,
    218                           8, 9, 1, 2, 3, 4, 5, 6, 7, 8 };
    219    uint64_t expect2[] = { 32767, -32768, -32767 };
    220    uint64_t expect3[] = { INT64_MIN, INT64_MAX };
    221    uint64_t expect4[] = { 1 };
    222    uint64_t expect5[] = { UINT64_MAX };
    223    uint64_t expect6[] = { UINT64_MAX - 2,  UINT64_MAX - 1, UINT64_MAX };
    224    Error *err = NULL;
    225    uint64List *res = NULL;
    226    Visitor *v;
    227    uint64_t val;
    228
    229    /* Valid lists */
    230
    231    v = visitor_input_test_init(data, "1,2,0,2-4,20,5-9,1-8");
    232    check_ulist(v, expect1, ARRAY_SIZE(expect1));
    233
    234    v = visitor_input_test_init(data, "32767,-32768--32767");
    235    check_ulist(v, expect2, ARRAY_SIZE(expect2));
    236
    237    v = visitor_input_test_init(data,
    238                                "-9223372036854775808,9223372036854775807");
    239    check_ulist(v, expect3, ARRAY_SIZE(expect3));
    240
    241    v = visitor_input_test_init(data, "1-1");
    242    check_ulist(v, expect4, ARRAY_SIZE(expect4));
    243
    244    v = visitor_input_test_init(data, "18446744073709551615");
    245    check_ulist(v, expect5, ARRAY_SIZE(expect5));
    246
    247    v = visitor_input_test_init(data,
    248                                "18446744073709551613-18446744073709551615");
    249    check_ulist(v, expect6, ARRAY_SIZE(expect6));
    250
    251    /* Value too large */
    252
    253    v = visitor_input_test_init(data, "18446744073709551616");
    254    visit_type_uint64List(v, NULL, &res, &err);
    255    error_free_or_abort(&err);
    256    g_assert(!res);
    257
    258    /* Value too small */
    259
    260    v = visitor_input_test_init(data, "-18446744073709551616");
    261    visit_type_uint64List(v, NULL, &res, &err);
    262    error_free_or_abort(&err);
    263    g_assert(!res);
    264
    265    /* Range not ascending */
    266
    267    v = visitor_input_test_init(data, "3-1");
    268    visit_type_uint64List(v, NULL, &res, &err);
    269    error_free_or_abort(&err);
    270    g_assert(!res);
    271
    272    v = visitor_input_test_init(data, "18446744073709551615-0");
    273    visit_type_uint64List(v, NULL, &res, &err);
    274    error_free_or_abort(&err);
    275    g_assert(!res);
    276
    277    /* Range too big (65536 is the limit against DOS attacks) */
    278
    279    v = visitor_input_test_init(data, "0-65536");
    280    visit_type_uint64List(v, NULL, &res, &err);
    281    error_free_or_abort(&err);
    282    g_assert(!res);
    283
    284    /* Empty list */
    285
    286    v = visitor_input_test_init(data, "");
    287    visit_type_uint64List(v, NULL, &res, &error_abort);
    288    g_assert(!res);
    289
    290    /* Not a list */
    291
    292    v = visitor_input_test_init(data, "not an uint list");
    293
    294    visit_type_uint64List(v, NULL, &res, &err);
    295    error_free_or_abort(&err);
    296    g_assert(!res);
    297
    298    /* Unvisited list tail */
    299
    300    v = visitor_input_test_init(data, "0,2-3");
    301
    302    visit_start_list(v, NULL, NULL, 0, &error_abort);
    303    visit_type_uint64(v, NULL, &val, &error_abort);
    304    g_assert_cmpuint(val, ==, 0);
    305    visit_type_uint64(v, NULL, &val, &error_abort);
    306    g_assert_cmpuint(val, ==, 2);
    307
    308    visit_check_list(v, &err);
    309    error_free_or_abort(&err);
    310    visit_end_list(v, NULL);
    311
    312    /* Visit beyond end of list */
    313
    314    v = visitor_input_test_init(data, "0");
    315
    316    visit_start_list(v, NULL, NULL, 0, &error_abort);
    317    visit_type_uint64(v, NULL, &val, &err);
    318    g_assert_cmpuint(val, ==, 0);
    319    visit_type_uint64(v, NULL, &val, &err);
    320    error_free_or_abort(&err);
    321
    322    visit_check_list(v, &error_abort);
    323    visit_end_list(v, NULL);
    324}
    325
    326static void test_visitor_in_bool(TestInputVisitorData *data,
    327                                 const void *unused)
    328{
    329    bool res = false;
    330    Visitor *v;
    331
    332    v = visitor_input_test_init(data, "true");
    333
    334    visit_type_bool(v, NULL, &res, &error_abort);
    335    g_assert_cmpint(res, ==, true);
    336
    337    v = visitor_input_test_init(data, "yes");
    338
    339    visit_type_bool(v, NULL, &res, &error_abort);
    340    g_assert_cmpint(res, ==, true);
    341
    342    v = visitor_input_test_init(data, "on");
    343
    344    visit_type_bool(v, NULL, &res, &error_abort);
    345    g_assert_cmpint(res, ==, true);
    346
    347    v = visitor_input_test_init(data, "false");
    348
    349    visit_type_bool(v, NULL, &res, &error_abort);
    350    g_assert_cmpint(res, ==, false);
    351
    352    v = visitor_input_test_init(data, "no");
    353
    354    visit_type_bool(v, NULL, &res, &error_abort);
    355    g_assert_cmpint(res, ==, false);
    356
    357    v = visitor_input_test_init(data, "off");
    358
    359    visit_type_bool(v, NULL, &res, &error_abort);
    360    g_assert_cmpint(res, ==, false);
    361}
    362
    363static void test_visitor_in_number(TestInputVisitorData *data,
    364                                   const void *unused)
    365{
    366    double res = 0, value = 3.14;
    367    Error *err = NULL;
    368    Visitor *v;
    369
    370    v = visitor_input_test_init(data, "3.14");
    371
    372    visit_type_number(v, NULL, &res, &error_abort);
    373    g_assert_cmpfloat(res, ==, value);
    374
    375    /* NaN and infinity has to be rejected */
    376
    377    v = visitor_input_test_init(data, "NaN");
    378
    379    visit_type_number(v, NULL, &res, &err);
    380    error_free_or_abort(&err);
    381
    382    v = visitor_input_test_init(data, "inf");
    383
    384    visit_type_number(v, NULL, &res, &err);
    385    error_free_or_abort(&err);
    386
    387}
    388
    389static void test_visitor_in_string(TestInputVisitorData *data,
    390                                   const void *unused)
    391{
    392    char *res = NULL, *value = (char *) "Q E M U";
    393    Visitor *v;
    394
    395    v = visitor_input_test_init(data, value);
    396
    397    visit_type_str(v, NULL, &res, &error_abort);
    398    g_assert_cmpstr(res, ==, value);
    399
    400    g_free(res);
    401}
    402
    403static void test_visitor_in_enum(TestInputVisitorData *data,
    404                                 const void *unused)
    405{
    406    Visitor *v;
    407    EnumOne i;
    408
    409    for (i = 0; i < ENUM_ONE__MAX; i++) {
    410        EnumOne res = -1;
    411
    412        v = visitor_input_test_init(data, EnumOne_str(i));
    413
    414        visit_type_EnumOne(v, NULL, &res, &error_abort);
    415        g_assert_cmpint(i, ==, res);
    416    }
    417}
    418
    419/* Try to crash the visitors */
    420static void test_visitor_in_fuzz(TestInputVisitorData *data,
    421                                 const void *unused)
    422{
    423    int64_t ires;
    424    intList *ilres;
    425    bool bres;
    426    double nres;
    427    char *sres;
    428    EnumOne eres;
    429    Visitor *v;
    430    unsigned int i;
    431    char buf[10000];
    432
    433    for (i = 0; i < 100; i++) {
    434        unsigned int j, k;
    435
    436        j = g_test_rand_int_range(0, sizeof(buf) - 1);
    437
    438        buf[j] = '\0';
    439
    440        for (k = 0; k != j; k++) {
    441            buf[k] = (char)g_test_rand_int_range(0, 256);
    442        }
    443
    444        v = visitor_input_test_init(data, buf);
    445        visit_type_int(v, NULL, &ires, NULL);
    446
    447        v = visitor_input_test_init(data, buf);
    448        visit_type_intList(v, NULL, &ilres, NULL);
    449        qapi_free_intList(ilres);
    450
    451        v = visitor_input_test_init(data, buf);
    452        visit_type_bool(v, NULL, &bres, NULL);
    453
    454        v = visitor_input_test_init(data, buf);
    455        visit_type_number(v, NULL, &nres, NULL);
    456
    457        v = visitor_input_test_init(data, buf);
    458        sres = NULL;
    459        visit_type_str(v, NULL, &sres, NULL);
    460        g_free(sres);
    461
    462        v = visitor_input_test_init(data, buf);
    463        visit_type_EnumOne(v, NULL, &eres, NULL);
    464    }
    465}
    466
    467static void input_visitor_test_add(const char *testpath,
    468                                   TestInputVisitorData *data,
    469                                   void (*test_func)(TestInputVisitorData *data, const void *user_data))
    470{
    471    g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
    472               visitor_input_teardown);
    473}
    474
    475int main(int argc, char **argv)
    476{
    477    TestInputVisitorData in_visitor_data;
    478
    479    g_test_init(&argc, &argv, NULL);
    480
    481    input_visitor_test_add("/string-visitor/input/int",
    482                           &in_visitor_data, test_visitor_in_int);
    483    input_visitor_test_add("/string-visitor/input/intList",
    484                           &in_visitor_data, test_visitor_in_intList);
    485    input_visitor_test_add("/string-visitor/input/uintList",
    486                           &in_visitor_data, test_visitor_in_uintList);
    487    input_visitor_test_add("/string-visitor/input/bool",
    488                           &in_visitor_data, test_visitor_in_bool);
    489    input_visitor_test_add("/string-visitor/input/number",
    490                           &in_visitor_data, test_visitor_in_number);
    491    input_visitor_test_add("/string-visitor/input/string",
    492                            &in_visitor_data, test_visitor_in_string);
    493    input_visitor_test_add("/string-visitor/input/enum",
    494                            &in_visitor_data, test_visitor_in_enum);
    495    input_visitor_test_add("/string-visitor/input/fuzz",
    496                            &in_visitor_data, test_visitor_in_fuzz);
    497
    498    g_test_run();
    499
    500    return 0;
    501}