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

check-qjson.c (44293B)


      1/*
      2 * Copyright IBM, Corp. 2009
      3 * Copyright (c) 2013, 2015 Red Hat Inc.
      4 *
      5 * Authors:
      6 *  Anthony Liguori   <aliguori@us.ibm.com>
      7 *  Markus Armbruster <armbru@redhat.com>
      8 *
      9 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
     10 * See the COPYING.LIB file in the top-level directory.
     11 *
     12 */
     13
     14#include "qemu/osdep.h"
     15
     16#include "qapi/error.h"
     17#include "qapi/qmp/qbool.h"
     18#include "qapi/qmp/qjson.h"
     19#include "qapi/qmp/qlit.h"
     20#include "qapi/qmp/qnull.h"
     21#include "qapi/qmp/qnum.h"
     22#include "qapi/qmp/qstring.h"
     23#include "qemu/unicode.h"
     24#include "qemu-common.h"
     25
     26static QString *from_json_str(const char *jstr, bool single, Error **errp)
     27{
     28    char quote = single ? '\'' : '"';
     29    char *qjstr = g_strdup_printf("%c%s%c", quote, jstr, quote);
     30    QString *ret = qobject_to(QString, qobject_from_json(qjstr, errp));
     31
     32    g_free(qjstr);
     33    return ret;
     34}
     35
     36static char *to_json_str(QString *str)
     37{
     38    GString *json = qobject_to_json(QOBJECT(str));
     39
     40    if (!json) {
     41        return NULL;
     42    }
     43    /* peel off double quotes */
     44    g_string_truncate(json, json->len - 1);
     45    g_string_erase(json, 0, 1);
     46    return g_string_free(json, false);
     47}
     48
     49static void escaped_string(void)
     50{
     51    struct {
     52        /* Content of JSON string to parse with qobject_from_json() */
     53        const char *json_in;
     54        /* Expected parse output; to unparse with qobject_to_json() */
     55        const char *utf8_out;
     56        int skip;
     57    } test_cases[] = {
     58        { "\\b\\f\\n\\r\\t\\\\\\\"", "\b\f\n\r\t\\\"" },
     59        { "\\/\\'", "/'", .skip = 1 },
     60        { "single byte utf-8 \\u0020", "single byte utf-8  ", .skip = 1 },
     61        { "double byte utf-8 \\u00A2", "double byte utf-8 \xc2\xa2" },
     62        { "triple byte utf-8 \\u20AC", "triple byte utf-8 \xe2\x82\xac" },
     63        { "quadruple byte utf-8 \\uD834\\uDD1E", /* U+1D11E */
     64          "quadruple byte utf-8 \xF0\x9D\x84\x9E" },
     65        { "\\", NULL },
     66        { "\\z", NULL },
     67        { "\\ux", NULL },
     68        { "\\u1x", NULL },
     69        { "\\u12x", NULL },
     70        { "\\u123x", NULL },
     71        { "\\u12345", "\341\210\2645" },
     72        { "\\u0000x", "\xC0\x80x" },
     73        { "unpaired leading surrogate \\uD800", NULL },
     74        { "unpaired leading surrogate \\uD800\\uCAFE", NULL },
     75        { "unpaired leading surrogate \\uD800\\uD801\\uDC02", NULL },
     76        { "unpaired trailing surrogate \\uDC00", NULL },
     77        { "backward surrogate pair \\uDC00\\uD800", NULL },
     78        { "noncharacter U+FDD0 \\uFDD0", NULL },
     79        { "noncharacter U+FDEF \\uFDEF", NULL },
     80        { "noncharacter U+1FFFE \\uD87F\\uDFFE", NULL },
     81        { "noncharacter U+10FFFF \\uDC3F\\uDFFF", NULL },
     82        {}
     83    };
     84    int i, j;
     85    QString *cstr;
     86    char *jstr;
     87
     88    for (i = 0; test_cases[i].json_in; i++) {
     89        for (j = 0; j < 2; j++) {
     90            if (test_cases[i].utf8_out) {
     91                cstr = from_json_str(test_cases[i].json_in, j, &error_abort);
     92                g_assert_cmpstr(qstring_get_str(cstr),
     93                                ==, test_cases[i].utf8_out);
     94                if (!test_cases[i].skip) {
     95                    jstr = to_json_str(cstr);
     96                    g_assert_cmpstr(jstr, ==, test_cases[i].json_in);
     97                    g_free(jstr);
     98                }
     99                qobject_unref(cstr);
    100            } else {
    101                cstr = from_json_str(test_cases[i].json_in, j, NULL);
    102                g_assert(!cstr);
    103            }
    104        }
    105    }
    106}
    107
    108static void string_with_quotes(void)
    109{
    110    const char *test_cases[] = {
    111        "\"the bee's knees\"",
    112        "'double quote \"'",
    113        NULL
    114    };
    115    int i;
    116    QString *str;
    117    char *cstr;
    118
    119    for (i = 0; test_cases[i]; i++) {
    120        str = qobject_to(QString,
    121                         qobject_from_json(test_cases[i], &error_abort));
    122        g_assert(str);
    123        cstr = g_strndup(test_cases[i] + 1, strlen(test_cases[i]) - 2);
    124        g_assert_cmpstr(qstring_get_str(str), ==, cstr);
    125        g_free(cstr);
    126        qobject_unref(str);
    127    }
    128}
    129
    130static void utf8_string(void)
    131{
    132    /*
    133     * Most test cases are scraped from Markus Kuhn's UTF-8 decoder
    134     * capability and stress test at
    135     * http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
    136     */
    137    static const struct {
    138        /* Content of JSON string to parse with qobject_from_json() */
    139        const char *json_in;
    140        /* Expected parse output */
    141        const char *utf8_out;
    142        /* Expected unparse output, defaults to @json_in */
    143        const char *json_out;
    144    } test_cases[] = {
    145        /* 0  Control characters */
    146        {
    147            /*
    148             * Note: \x00 is impossible, other representations of
    149             * U+0000 are covered under 4.3
    150             */
    151            "\x01\x02\x03\x04\x05\x06\x07"
    152            "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
    153            "\x10\x11\x12\x13\x14\x15\x16\x17"
    154            "\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
    155            NULL,
    156            "\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007"
    157            "\\b\\t\\n\\u000B\\f\\r\\u000E\\u000F"
    158            "\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017"
    159            "\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F",
    160        },
    161        /* 1  Some correct UTF-8 text */
    162        {
    163            /* a bit of German */
    164            "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
    165            " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
    166            "Falsches \xC3\x9C" "ben von Xylophonmusik qu\xC3\xA4lt"
    167            " jeden gr\xC3\xB6\xC3\x9F" "eren Zwerg.",
    168            "Falsches \\u00DCben von Xylophonmusik qu\\u00E4lt"
    169            " jeden gr\\u00F6\\u00DFeren Zwerg.",
    170        },
    171        {
    172            /* a bit of Greek */
    173            "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
    174            "\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
    175            "\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5",
    176        },
    177            /* '%' character when not interpolating */
    178        {
    179            "100%",
    180            "100%",
    181        },
    182        /* 2  Boundary condition test cases */
    183        /* 2.1  First possible sequence of a certain length */
    184        /*
    185         * 2.1.1 1 byte U+0020
    186         * Control characters are already covered by their own test
    187         * case under 0.  Test the first 1 byte non-control character
    188         * here.
    189         */
    190        {
    191            " ",
    192            " ",
    193        },
    194        /* 2.1.2  2 bytes U+0080 */
    195        {
    196            "\xC2\x80",
    197            "\xC2\x80",
    198            "\\u0080",
    199        },
    200        /* 2.1.3  3 bytes U+0800 */
    201        {
    202            "\xE0\xA0\x80",
    203            "\xE0\xA0\x80",
    204            "\\u0800",
    205        },
    206        /* 2.1.4  4 bytes U+10000 */
    207        {
    208            "\xF0\x90\x80\x80",
    209            "\xF0\x90\x80\x80",
    210            "\\uD800\\uDC00",
    211        },
    212        /* 2.1.5  5 bytes U+200000 */
    213        {
    214            "\xF8\x88\x80\x80\x80",
    215            NULL,
    216            "\\uFFFD",
    217        },
    218        /* 2.1.6  6 bytes U+4000000 */
    219        {
    220            "\xFC\x84\x80\x80\x80\x80",
    221            NULL,
    222            "\\uFFFD",
    223        },
    224        /* 2.2  Last possible sequence of a certain length */
    225        /* 2.2.1  1 byte U+007F */
    226        {
    227            "\x7F",
    228            "\x7F",
    229            "\\u007F",
    230        },
    231        /* 2.2.2  2 bytes U+07FF */
    232        {
    233            "\xDF\xBF",
    234            "\xDF\xBF",
    235            "\\u07FF",
    236        },
    237        /*
    238         * 2.2.3  3 bytes U+FFFC
    239         * The last possible sequence is actually U+FFFF.  But that's
    240         * a noncharacter, and already covered by its own test case
    241         * under 5.3.  Same for U+FFFE.  U+FFFD is the last character
    242         * in the BMP, and covered under 2.3.  Because of U+FFFD's
    243         * special role as replacement character, it's worth testing
    244         * U+FFFC here.
    245         */
    246        {
    247            "\xEF\xBF\xBC",
    248            "\xEF\xBF\xBC",
    249            "\\uFFFC",
    250        },
    251        /* 2.2.4  4 bytes U+1FFFFF */
    252        {
    253            "\xF7\xBF\xBF\xBF",
    254            NULL,
    255            "\\uFFFD",
    256        },
    257        /* 2.2.5  5 bytes U+3FFFFFF */
    258        {
    259            "\xFB\xBF\xBF\xBF\xBF",
    260            NULL,
    261            "\\uFFFD",
    262        },
    263        /* 2.2.6  6 bytes U+7FFFFFFF */
    264        {
    265            "\xFD\xBF\xBF\xBF\xBF\xBF",
    266            NULL,
    267            "\\uFFFD",
    268        },
    269        /* 2.3  Other boundary conditions */
    270        {
    271            /* last one before surrogate range: U+D7FF */
    272            "\xED\x9F\xBF",
    273            "\xED\x9F\xBF",
    274            "\\uD7FF",
    275        },
    276        {
    277            /* first one after surrogate range: U+E000 */
    278            "\xEE\x80\x80",
    279            "\xEE\x80\x80",
    280            "\\uE000",
    281        },
    282        {
    283            /* last one in BMP: U+FFFD */
    284            "\xEF\xBF\xBD",
    285            "\xEF\xBF\xBD",
    286            "\\uFFFD",
    287        },
    288        {
    289            /* last one in last plane: U+10FFFD */
    290            "\xF4\x8F\xBF\xBD",
    291            "\xF4\x8F\xBF\xBD",
    292            "\\uDBFF\\uDFFD"
    293        },
    294        {
    295            /* first one beyond Unicode range: U+110000 */
    296            "\xF4\x90\x80\x80",
    297            NULL,
    298            "\\uFFFD",
    299        },
    300        /* 3  Malformed sequences */
    301        /* 3.1  Unexpected continuation bytes */
    302        /* 3.1.1  First continuation byte */
    303        {
    304            "\x80",
    305            NULL,
    306            "\\uFFFD",
    307        },
    308        /* 3.1.2  Last continuation byte */
    309        {
    310            "\xBF",
    311            NULL,
    312            "\\uFFFD",
    313        },
    314        /* 3.1.3  2 continuation bytes */
    315        {
    316            "\x80\xBF",
    317            NULL,
    318            "\\uFFFD\\uFFFD",
    319        },
    320        /* 3.1.4  3 continuation bytes */
    321        {
    322            "\x80\xBF\x80",
    323            NULL,
    324            "\\uFFFD\\uFFFD\\uFFFD",
    325        },
    326        /* 3.1.5  4 continuation bytes */
    327        {
    328            "\x80\xBF\x80\xBF",
    329            NULL,
    330            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
    331        },
    332        /* 3.1.6  5 continuation bytes */
    333        {
    334            "\x80\xBF\x80\xBF\x80",
    335            NULL,
    336            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
    337        },
    338        /* 3.1.7  6 continuation bytes */
    339        {
    340            "\x80\xBF\x80\xBF\x80\xBF",
    341            NULL,
    342            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
    343        },
    344        /* 3.1.8  7 continuation bytes */
    345        {
    346            "\x80\xBF\x80\xBF\x80\xBF\x80",
    347            NULL,
    348            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
    349        },
    350        /* 3.1.9  Sequence of all 64 possible continuation bytes */
    351        {
    352            "\x80\x81\x82\x83\x84\x85\x86\x87"
    353            "\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
    354            "\x90\x91\x92\x93\x94\x95\x96\x97"
    355            "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
    356            "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7"
    357            "\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
    358            "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7"
    359            "\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF",
    360            NULL,
    361            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
    362            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
    363            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
    364            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
    365            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
    366            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
    367            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
    368            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
    369        },
    370        /* 3.2  Lonely start characters */
    371        /* 3.2.1  All 32 first bytes of 2-byte sequences, followed by space */
    372        {
    373            "\xC0 \xC1 \xC2 \xC3 \xC4 \xC5 \xC6 \xC7 "
    374            "\xC8 \xC9 \xCA \xCB \xCC \xCD \xCE \xCF "
    375            "\xD0 \xD1 \xD2 \xD3 \xD4 \xD5 \xD6 \xD7 "
    376            "\xD8 \xD9 \xDA \xDB \xDC \xDD \xDE \xDF ",
    377            NULL,
    378            "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
    379            "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
    380            "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
    381            "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
    382        },
    383        /* 3.2.2  All 16 first bytes of 3-byte sequences, followed by space */
    384        {
    385            "\xE0 \xE1 \xE2 \xE3 \xE4 \xE5 \xE6 \xE7 "
    386            "\xE8 \xE9 \xEA \xEB \xEC \xED \xEE \xEF ",
    387            NULL,
    388            "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD "
    389            "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
    390        },
    391        /* 3.2.3  All 8 first bytes of 4-byte sequences, followed by space */
    392        {
    393            "\xF0 \xF1 \xF2 \xF3 \xF4 \xF5 \xF6 \xF7 ",
    394            NULL,
    395            "\\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
    396        },
    397        /* 3.2.4  All 4 first bytes of 5-byte sequences, followed by space */
    398        {
    399            "\xF8 \xF9 \xFA \xFB ",
    400            NULL,
    401            "\\uFFFD \\uFFFD \\uFFFD \\uFFFD ",
    402        },
    403        /* 3.2.5  All 2 first bytes of 6-byte sequences, followed by space */
    404        {
    405            "\xFC \xFD ",
    406            NULL,
    407            "\\uFFFD \\uFFFD ",
    408        },
    409        /* 3.3  Sequences with last continuation byte missing */
    410        /* 3.3.1  2-byte sequence with last byte missing (U+0000) */
    411        {
    412            "\xC0",
    413            NULL,
    414            "\\uFFFD",
    415        },
    416        /* 3.3.2  3-byte sequence with last byte missing (U+0000) */
    417        {
    418            "\xE0\x80",
    419            NULL,
    420            "\\uFFFD",
    421        },
    422        /* 3.3.3  4-byte sequence with last byte missing (U+0000) */
    423        {
    424            "\xF0\x80\x80",
    425            NULL,
    426            "\\uFFFD",
    427        },
    428        /* 3.3.4  5-byte sequence with last byte missing (U+0000) */
    429        {
    430            "\xF8\x80\x80\x80",
    431            NULL,
    432            "\\uFFFD",
    433        },
    434        /* 3.3.5  6-byte sequence with last byte missing (U+0000) */
    435        {
    436            "\xFC\x80\x80\x80\x80",
    437            NULL,
    438            "\\uFFFD",
    439        },
    440        /* 3.3.6  2-byte sequence with last byte missing (U+07FF) */
    441        {
    442            "\xDF",
    443            NULL,
    444            "\\uFFFD",
    445        },
    446        /* 3.3.7  3-byte sequence with last byte missing (U+FFFF) */
    447        {
    448            "\xEF\xBF",
    449            NULL,
    450            "\\uFFFD",
    451        },
    452        /* 3.3.8  4-byte sequence with last byte missing (U+1FFFFF) */
    453        {
    454            "\xF7\xBF\xBF",
    455            NULL,
    456            "\\uFFFD",
    457        },
    458        /* 3.3.9  5-byte sequence with last byte missing (U+3FFFFFF) */
    459        {
    460            "\xFB\xBF\xBF\xBF",
    461            NULL,
    462            "\\uFFFD",
    463        },
    464        /* 3.3.10  6-byte sequence with last byte missing (U+7FFFFFFF) */
    465        {
    466            "\xFD\xBF\xBF\xBF\xBF",
    467            NULL,
    468            "\\uFFFD",
    469        },
    470        /* 3.4  Concatenation of incomplete sequences */
    471        {
    472            "\xC0\xE0\x80\xF0\x80\x80\xF8\x80\x80\x80\xFC\x80\x80\x80\x80"
    473            "\xDF\xEF\xBF\xF7\xBF\xBF\xFB\xBF\xBF\xBF\xFD\xBF\xBF\xBF\xBF",
    474            NULL,
    475            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
    476            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
    477        },
    478        /* 3.5  Impossible bytes */
    479        {
    480            "\xFE",
    481            NULL,
    482            "\\uFFFD",
    483        },
    484        {
    485            "\xFF",
    486            NULL,
    487            "\\uFFFD",
    488        },
    489        {
    490            "\xFE\xFE\xFF\xFF",
    491            NULL,
    492            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
    493        },
    494        /* 4  Overlong sequences */
    495        /* 4.1  Overlong '/' */
    496        {
    497            "\xC0\xAF",
    498            NULL,
    499            "\\uFFFD",
    500        },
    501        {
    502            "\xE0\x80\xAF",
    503            NULL,
    504            "\\uFFFD",
    505        },
    506        {
    507            "\xF0\x80\x80\xAF",
    508            NULL,
    509            "\\uFFFD",
    510        },
    511        {
    512            "\xF8\x80\x80\x80\xAF",
    513            NULL,
    514            "\\uFFFD",
    515        },
    516        {
    517            "\xFC\x80\x80\x80\x80\xAF",
    518            NULL,
    519            "\\uFFFD",
    520        },
    521        /*
    522         * 4.2  Maximum overlong sequences
    523         * Highest Unicode value that is still resulting in an
    524         * overlong sequence if represented with the given number of
    525         * bytes.  This is a boundary test for safe UTF-8 decoders.
    526         */
    527        {
    528            /* \U+007F */
    529            "\xC1\xBF",
    530            NULL,
    531            "\\uFFFD",
    532        },
    533        {
    534            /* \U+07FF */
    535            "\xE0\x9F\xBF",
    536            NULL,
    537            "\\uFFFD",
    538        },
    539        {
    540            /*
    541             * \U+FFFC
    542             * The actual maximum would be U+FFFF, but that's a
    543             * noncharacter.  Testing U+FFFC seems more useful.  See
    544             * also 2.2.3
    545             */
    546            "\xF0\x8F\xBF\xBC",
    547            NULL,
    548            "\\uFFFD",
    549        },
    550        {
    551            /* \U+1FFFFF */
    552            "\xF8\x87\xBF\xBF\xBF",
    553            NULL,
    554            "\\uFFFD",
    555        },
    556        {
    557            /* \U+3FFFFFF */
    558            "\xFC\x83\xBF\xBF\xBF\xBF",
    559            NULL,
    560            "\\uFFFD",
    561        },
    562        /* 4.3  Overlong representation of the NUL character */
    563        {
    564            /* \U+0000 */
    565            "\xC0\x80",
    566            "\xC0\x80",
    567            "\\u0000",
    568        },
    569        {
    570            /* \U+0000 */
    571            "\xE0\x80\x80",
    572            NULL,
    573            "\\uFFFD",
    574        },
    575        {
    576            /* \U+0000 */
    577            "\xF0\x80\x80\x80",
    578            NULL,
    579            "\\uFFFD",
    580        },
    581        {
    582            /* \U+0000 */
    583            "\xF8\x80\x80\x80\x80",
    584            NULL,
    585            "\\uFFFD",
    586        },
    587        {
    588            /* \U+0000 */
    589            "\xFC\x80\x80\x80\x80\x80",
    590            NULL,
    591            "\\uFFFD",
    592        },
    593        /* 5  Illegal code positions */
    594        /* 5.1  Single UTF-16 surrogates */
    595        {
    596            /* \U+D800 */
    597            "\xED\xA0\x80",
    598            NULL,
    599            "\\uFFFD",
    600        },
    601        {
    602            /* \U+DB7F */
    603            "\xED\xAD\xBF",
    604            NULL,
    605            "\\uFFFD",
    606        },
    607        {
    608            /* \U+DB80 */
    609            "\xED\xAE\x80",
    610            NULL,
    611            "\\uFFFD",
    612        },
    613        {
    614            /* \U+DBFF */
    615            "\xED\xAF\xBF",
    616            NULL,
    617            "\\uFFFD",
    618        },
    619        {
    620            /* \U+DC00 */
    621            "\xED\xB0\x80",
    622            NULL,
    623            "\\uFFFD",
    624        },
    625        {
    626            /* \U+DF80 */
    627            "\xED\xBE\x80",
    628            NULL,
    629            "\\uFFFD",
    630        },
    631        {
    632            /* \U+DFFF */
    633            "\xED\xBF\xBF",
    634            NULL,
    635            "\\uFFFD",
    636        },
    637        /* 5.2  Paired UTF-16 surrogates */
    638        {
    639            /* \U+D800\U+DC00 */
    640            "\xED\xA0\x80\xED\xB0\x80",
    641            NULL,
    642            "\\uFFFD\\uFFFD",
    643        },
    644        {
    645            /* \U+D800\U+DFFF */
    646            "\xED\xA0\x80\xED\xBF\xBF",
    647            NULL,
    648            "\\uFFFD\\uFFFD",
    649        },
    650        {
    651            /* \U+DB7F\U+DC00 */
    652            "\xED\xAD\xBF\xED\xB0\x80",
    653            NULL,
    654            "\\uFFFD\\uFFFD",
    655        },
    656        {
    657            /* \U+DB7F\U+DFFF */
    658            "\xED\xAD\xBF\xED\xBF\xBF",
    659            NULL,
    660            "\\uFFFD\\uFFFD",
    661        },
    662        {
    663            /* \U+DB80\U+DC00 */
    664            "\xED\xAE\x80\xED\xB0\x80",
    665            NULL,
    666            "\\uFFFD\\uFFFD",
    667        },
    668        {
    669            /* \U+DB80\U+DFFF */
    670            "\xED\xAE\x80\xED\xBF\xBF",
    671            NULL,
    672            "\\uFFFD\\uFFFD",
    673        },
    674        {
    675            /* \U+DBFF\U+DC00 */
    676            "\xED\xAF\xBF\xED\xB0\x80",
    677            NULL,
    678            "\\uFFFD\\uFFFD",
    679        },
    680        {
    681            /* \U+DBFF\U+DFFF */
    682            "\xED\xAF\xBF\xED\xBF\xBF",
    683            NULL,
    684            "\\uFFFD\\uFFFD",
    685        },
    686        /* 5.3  Other illegal code positions */
    687        /* BMP noncharacters */
    688        {
    689            /* \U+FFFE */
    690            "\xEF\xBF\xBE",
    691            NULL,
    692            "\\uFFFD",
    693        },
    694        {
    695            /* \U+FFFF */
    696            "\xEF\xBF\xBF",
    697            NULL,
    698            "\\uFFFD",
    699        },
    700        {
    701            /* U+FDD0 */
    702            "\xEF\xB7\x90",
    703            NULL,
    704            "\\uFFFD",
    705        },
    706        {
    707            /* U+FDEF */
    708            "\xEF\xB7\xAF",
    709            NULL,
    710            "\\uFFFD",
    711        },
    712        /* Plane 1 .. 16 noncharacters */
    713        {
    714            /* U+1FFFE U+1FFFF U+2FFFE U+2FFFF ... U+10FFFE U+10FFFF */
    715            "\xF0\x9F\xBF\xBE\xF0\x9F\xBF\xBF"
    716            "\xF0\xAF\xBF\xBE\xF0\xAF\xBF\xBF"
    717            "\xF0\xBF\xBF\xBE\xF0\xBF\xBF\xBF"
    718            "\xF1\x8F\xBF\xBE\xF1\x8F\xBF\xBF"
    719            "\xF1\x9F\xBF\xBE\xF1\x9F\xBF\xBF"
    720            "\xF1\xAF\xBF\xBE\xF1\xAF\xBF\xBF"
    721            "\xF1\xBF\xBF\xBE\xF1\xBF\xBF\xBF"
    722            "\xF2\x8F\xBF\xBE\xF2\x8F\xBF\xBF"
    723            "\xF2\x9F\xBF\xBE\xF2\x9F\xBF\xBF"
    724            "\xF2\xAF\xBF\xBE\xF2\xAF\xBF\xBF"
    725            "\xF2\xBF\xBF\xBE\xF2\xBF\xBF\xBF"
    726            "\xF3\x8F\xBF\xBE\xF3\x8F\xBF\xBF"
    727            "\xF3\x9F\xBF\xBE\xF3\x9F\xBF\xBF"
    728            "\xF3\xAF\xBF\xBE\xF3\xAF\xBF\xBF"
    729            "\xF3\xBF\xBF\xBE\xF3\xBF\xBF\xBF"
    730            "\xF4\x8F\xBF\xBE\xF4\x8F\xBF\xBF",
    731            NULL,
    732            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
    733            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
    734            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD"
    735            "\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD\\uFFFD",
    736        },
    737        {}
    738    };
    739    int i, j;
    740    QString *str;
    741    const char *json_in, *utf8_out, *utf8_in, *json_out, *tail;
    742    char *end, *in, *jstr;
    743
    744    for (i = 0; test_cases[i].json_in; i++) {
    745        for (j = 0; j < 2; j++) {
    746            json_in = test_cases[i].json_in;
    747            utf8_out = test_cases[i].utf8_out;
    748            utf8_in = test_cases[i].utf8_out ?: test_cases[i].json_in;
    749            json_out = test_cases[i].json_out ?: test_cases[i].json_in;
    750
    751            /* Parse @json_in, expect @utf8_out */
    752            if (utf8_out) {
    753                str = from_json_str(json_in, j, &error_abort);
    754                g_assert_cmpstr(qstring_get_str(str), ==, utf8_out);
    755                qobject_unref(str);
    756            } else {
    757                str = from_json_str(json_in, j, NULL);
    758                g_assert(!str);
    759                /*
    760                 * Failure may be due to any sequence, but *all* sequences
    761                 * are expected to fail.  Test each one in isolation.
    762                 */
    763                for (tail = json_in; *tail; tail = end) {
    764                    mod_utf8_codepoint(tail, 6, &end);
    765                    if (*end == ' ') {
    766                        end++;
    767                    }
    768                    in = g_strndup(tail, end - tail);
    769                    str = from_json_str(in, j, NULL);
    770                    g_assert(!str);
    771                    g_free(in);
    772                }
    773            }
    774
    775            /* Unparse @utf8_in, expect @json_out */
    776            str = qstring_from_str(utf8_in);
    777            jstr = to_json_str(str);
    778            g_assert_cmpstr(jstr, ==, json_out);
    779            qobject_unref(str);
    780            g_free(jstr);
    781
    782            /* Parse @json_out right back, unless it has replacements */
    783            if (!strstr(json_out, "\\uFFFD")) {
    784                str = from_json_str(json_out, j, &error_abort);
    785                g_assert_cmpstr(qstring_get_str(str), ==, utf8_in);
    786                qobject_unref(str);
    787            }
    788        }
    789    }
    790}
    791
    792static void int_number(void)
    793{
    794    struct {
    795        const char *encoded;
    796        int64_t decoded;
    797        const char *reencoded;
    798    } test_cases[] = {
    799        { "0", 0 },
    800        { "1234", 1234 },
    801        { "1", 1 },
    802        { "-32", -32 },
    803        { "-0", 0, "0" },
    804        {},
    805    };
    806    int i;
    807    QNum *qnum;
    808    int64_t ival;
    809    uint64_t uval;
    810    GString *str;
    811
    812    for (i = 0; test_cases[i].encoded; i++) {
    813        qnum = qobject_to(QNum,
    814                          qobject_from_json(test_cases[i].encoded,
    815                                            &error_abort));
    816        g_assert(qnum);
    817        g_assert(qnum_get_try_int(qnum, &ival));
    818        g_assert_cmpint(ival, ==, test_cases[i].decoded);
    819        if (test_cases[i].decoded >= 0) {
    820            g_assert(qnum_get_try_uint(qnum, &uval));
    821            g_assert_cmpuint(uval, ==, (uint64_t)test_cases[i].decoded);
    822        } else {
    823            g_assert(!qnum_get_try_uint(qnum, &uval));
    824        }
    825        g_assert_cmpfloat(qnum_get_double(qnum), ==,
    826                          (double)test_cases[i].decoded);
    827
    828        str = qobject_to_json(QOBJECT(qnum));
    829        g_assert_cmpstr(str->str, ==,
    830                        test_cases[i].reencoded ?: test_cases[i].encoded);
    831        g_string_free(str, true);
    832
    833        qobject_unref(qnum);
    834    }
    835}
    836
    837static void uint_number(void)
    838{
    839    struct {
    840        const char *encoded;
    841        uint64_t decoded;
    842        const char *reencoded;
    843    } test_cases[] = {
    844        { "9223372036854775808", (uint64_t)1 << 63 },
    845        { "18446744073709551615", UINT64_MAX },
    846        {},
    847    };
    848    int i;
    849    QNum *qnum;
    850    int64_t ival;
    851    uint64_t uval;
    852    GString *str;
    853
    854    for (i = 0; test_cases[i].encoded; i++) {
    855        qnum = qobject_to(QNum,
    856                          qobject_from_json(test_cases[i].encoded,
    857                                            &error_abort));
    858        g_assert(qnum);
    859        g_assert(qnum_get_try_uint(qnum, &uval));
    860        g_assert_cmpuint(uval, ==, test_cases[i].decoded);
    861        g_assert(!qnum_get_try_int(qnum, &ival));
    862        g_assert_cmpfloat(qnum_get_double(qnum), ==,
    863                          (double)test_cases[i].decoded);
    864
    865        str = qobject_to_json(QOBJECT(qnum));
    866        g_assert_cmpstr(str->str, ==,
    867                        test_cases[i].reencoded ?: test_cases[i].encoded);
    868        g_string_free(str, true);
    869
    870        qobject_unref(qnum);
    871    }
    872}
    873
    874static void float_number(void)
    875{
    876    struct {
    877        const char *encoded;
    878        double decoded;
    879        const char *reencoded;
    880    } test_cases[] = {
    881        { "32.43", 32.43 },
    882        { "0.222", 0.222 },
    883        { "-32.12313", -32.12313, "-32.123130000000003" },
    884        { "-32.20e-10", -32.20e-10, "-3.22e-09" },
    885        { "18446744073709551616", 0x1p64, "1.8446744073709552e+19" },
    886        { "-9223372036854775809", -0x1p63, "-9.2233720368547758e+18" },
    887        {},
    888    };
    889    int i;
    890    QNum *qnum;
    891    int64_t ival;
    892    uint64_t uval;
    893    GString *str;
    894
    895    for (i = 0; test_cases[i].encoded; i++) {
    896        qnum = qobject_to(QNum,
    897                          qobject_from_json(test_cases[i].encoded,
    898                                            &error_abort));
    899        g_assert(qnum);
    900        g_assert_cmpfloat(qnum_get_double(qnum), ==, test_cases[i].decoded);
    901        g_assert(!qnum_get_try_int(qnum, &ival));
    902        g_assert(!qnum_get_try_uint(qnum, &uval));
    903
    904        str = qobject_to_json(QOBJECT(qnum));
    905        g_assert_cmpstr(str->str, ==,
    906                        test_cases[i].reencoded ?: test_cases[i].encoded);
    907        g_string_free(str, true);
    908
    909        qobject_unref(qnum);
    910    }
    911}
    912
    913static void keyword_literal(void)
    914{
    915    QObject *obj;
    916    QBool *qbool;
    917    QNull *null;
    918    GString *str;
    919
    920    obj = qobject_from_json("true", &error_abort);
    921    qbool = qobject_to(QBool, obj);
    922    g_assert(qbool);
    923    g_assert(qbool_get_bool(qbool) == true);
    924
    925    str = qobject_to_json(obj);
    926    g_assert_cmpstr(str->str, ==, "true");
    927    g_string_free(str, true);
    928
    929    qobject_unref(qbool);
    930
    931    obj = qobject_from_json("false", &error_abort);
    932    qbool = qobject_to(QBool, obj);
    933    g_assert(qbool);
    934    g_assert(qbool_get_bool(qbool) == false);
    935
    936    str = qobject_to_json(obj);
    937    g_assert_cmpstr(str->str, ==, "false");
    938    g_string_free(str, true);
    939
    940    qobject_unref(qbool);
    941
    942    obj = qobject_from_json("null", &error_abort);
    943    g_assert(obj != NULL);
    944    g_assert(qobject_type(obj) == QTYPE_QNULL);
    945
    946    null = qnull();
    947    g_assert(QOBJECT(null) == obj);
    948
    949    qobject_unref(obj);
    950    qobject_unref(null);
    951}
    952
    953static void interpolation_valid(void)
    954{
    955    long long value_lld = 0x123456789abcdefLL;
    956    int64_t value_d64 = value_lld;
    957    long value_ld = (long)value_lld;
    958    int value_d = (int)value_lld;
    959    unsigned long long value_llu = 0xfedcba9876543210ULL;
    960    uint64_t value_u64 = value_llu;
    961    unsigned long value_lu = (unsigned long)value_llu;
    962    unsigned value_u = (unsigned)value_llu;
    963    double value_f = 2.323423423;
    964    const char *value_s = "hello world";
    965    QObject *value_p = QOBJECT(qnull());
    966    QBool *qbool;
    967    QNum *qnum;
    968    QString *qstr;
    969    QObject *qobj;
    970
    971    /* bool */
    972
    973    qbool = qobject_to(QBool, qobject_from_jsonf_nofail("%i", false));
    974    g_assert(qbool);
    975    g_assert(qbool_get_bool(qbool) == false);
    976    qobject_unref(qbool);
    977
    978    /* Test that non-zero values other than 1 get collapsed to true */
    979    qbool = qobject_to(QBool, qobject_from_jsonf_nofail("%i", 2));
    980    g_assert(qbool);
    981    g_assert(qbool_get_bool(qbool) == true);
    982    qobject_unref(qbool);
    983
    984    /* number */
    985
    986    qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%d", value_d));
    987    g_assert_cmpint(qnum_get_int(qnum), ==, value_d);
    988    qobject_unref(qnum);
    989
    990    qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%ld", value_ld));
    991    g_assert_cmpint(qnum_get_int(qnum), ==, value_ld);
    992    qobject_unref(qnum);
    993
    994    qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%lld", value_lld));
    995    g_assert_cmpint(qnum_get_int(qnum), ==, value_lld);
    996    qobject_unref(qnum);
    997
    998    qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%" PRId64, value_d64));
    999    g_assert_cmpint(qnum_get_int(qnum), ==, value_lld);
   1000    qobject_unref(qnum);
   1001
   1002    qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%u", value_u));
   1003    g_assert_cmpuint(qnum_get_uint(qnum), ==, value_u);
   1004    qobject_unref(qnum);
   1005
   1006    qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%lu", value_lu));
   1007    g_assert_cmpuint(qnum_get_uint(qnum), ==, value_lu);
   1008    qobject_unref(qnum);
   1009
   1010    qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%llu", value_llu));
   1011    g_assert_cmpuint(qnum_get_uint(qnum), ==, value_llu);
   1012    qobject_unref(qnum);
   1013
   1014    qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%" PRIu64, value_u64));
   1015    g_assert_cmpuint(qnum_get_uint(qnum), ==, value_llu);
   1016    qobject_unref(qnum);
   1017
   1018    qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%f", value_f));
   1019    g_assert(qnum_get_double(qnum) == value_f);
   1020    qobject_unref(qnum);
   1021
   1022    /* string */
   1023
   1024    qstr = qobject_to(QString, qobject_from_jsonf_nofail("%s", value_s));
   1025    g_assert_cmpstr(qstring_get_str(qstr), ==, value_s);
   1026    qobject_unref(qstr);
   1027
   1028    /* object */
   1029
   1030    qobj = qobject_from_jsonf_nofail("%p", value_p);
   1031    g_assert(qobj == value_p);
   1032}
   1033
   1034static void interpolation_unknown(void)
   1035{
   1036    if (g_test_subprocess()) {
   1037        qobject_from_jsonf_nofail("%x", 666);
   1038    }
   1039    g_test_trap_subprocess(NULL, 0, 0);
   1040    g_test_trap_assert_failed();
   1041    g_test_trap_assert_stderr("*Unexpected error*"
   1042                              "invalid interpolation '%x'*");
   1043}
   1044
   1045static void interpolation_string(void)
   1046{
   1047    if (g_test_subprocess()) {
   1048        qobject_from_jsonf_nofail("['%s', %s]", "eins", "zwei");
   1049    }
   1050    g_test_trap_subprocess(NULL, 0, 0);
   1051    g_test_trap_assert_failed();
   1052    g_test_trap_assert_stderr("*Unexpected error*"
   1053                              "can't interpolate into string*");
   1054}
   1055
   1056static void simple_dict(void)
   1057{
   1058    int i;
   1059    struct {
   1060        const char *encoded;
   1061        QLitObject decoded;
   1062    } test_cases[] = {
   1063        {
   1064            .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",
   1065            .decoded = QLIT_QDICT(((QLitDictEntry[]){
   1066                        { "foo", QLIT_QNUM(42) },
   1067                        { "bar", QLIT_QSTR("hello world") },
   1068                        { }
   1069                    })),
   1070        }, {
   1071            .encoded = "{}",
   1072            .decoded = QLIT_QDICT(((QLitDictEntry[]){
   1073                        { }
   1074                    })),
   1075        }, {
   1076            .encoded = "{\"foo\": 43}",
   1077            .decoded = QLIT_QDICT(((QLitDictEntry[]){
   1078                        { "foo", QLIT_QNUM(43) },
   1079                        { }
   1080                    })),
   1081        },
   1082        { }
   1083    };
   1084
   1085    for (i = 0; test_cases[i].encoded; i++) {
   1086        QObject *obj;
   1087        GString *str;
   1088
   1089        obj = qobject_from_json(test_cases[i].encoded, &error_abort);
   1090        g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
   1091
   1092        str = qobject_to_json(obj);
   1093        qobject_unref(obj);
   1094
   1095        obj = qobject_from_json(str->str, &error_abort);
   1096        g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
   1097        qobject_unref(obj);
   1098        g_string_free(str, true);
   1099    }
   1100}
   1101
   1102/*
   1103 * this generates json of the form:
   1104 * a(0,m) = [0, 1, ..., m-1]
   1105 * a(n,m) = {
   1106 *            'key0': a(0,m),
   1107 *            'key1': a(1,m),
   1108 *            ...
   1109 *            'key(n-1)': a(n-1,m)
   1110 *          }
   1111 */
   1112static void gen_test_json(GString *gstr, int nest_level_max,
   1113                          int elem_count)
   1114{
   1115    int i;
   1116
   1117    g_assert(gstr);
   1118    if (nest_level_max == 0) {
   1119        g_string_append(gstr, "[");
   1120        for (i = 0; i < elem_count; i++) {
   1121            g_string_append_printf(gstr, "%d", i);
   1122            if (i < elem_count - 1) {
   1123                g_string_append_printf(gstr, ", ");
   1124            }
   1125        }
   1126        g_string_append(gstr, "]");
   1127        return;
   1128    }
   1129
   1130    g_string_append(gstr, "{");
   1131    for (i = 0; i < nest_level_max; i++) {
   1132        g_string_append_printf(gstr, "'key%d': ", i);
   1133        gen_test_json(gstr, i, elem_count);
   1134        if (i < nest_level_max - 1) {
   1135            g_string_append(gstr, ",");
   1136        }
   1137    }
   1138    g_string_append(gstr, "}");
   1139}
   1140
   1141static void large_dict(void)
   1142{
   1143    GString *gstr = g_string_new("");
   1144    QObject *obj;
   1145
   1146    gen_test_json(gstr, 10, 100);
   1147    obj = qobject_from_json(gstr->str, &error_abort);
   1148    g_assert(obj != NULL);
   1149
   1150    qobject_unref(obj);
   1151    g_string_free(gstr, true);
   1152}
   1153
   1154static void simple_list(void)
   1155{
   1156    int i;
   1157    struct {
   1158        const char *encoded;
   1159        QLitObject decoded;
   1160    } test_cases[] = {
   1161        {
   1162            .encoded = "[43,42]",
   1163            .decoded = QLIT_QLIST(((QLitObject[]){
   1164                        QLIT_QNUM(43),
   1165                        QLIT_QNUM(42),
   1166                        { }
   1167                    })),
   1168        },
   1169        {
   1170            .encoded = "[43]",
   1171            .decoded = QLIT_QLIST(((QLitObject[]){
   1172                        QLIT_QNUM(43),
   1173                        { }
   1174                    })),
   1175        },
   1176        {
   1177            .encoded = "[]",
   1178            .decoded = QLIT_QLIST(((QLitObject[]){
   1179                        { }
   1180                    })),
   1181        },
   1182        {
   1183            .encoded = "[{}]",
   1184            .decoded = QLIT_QLIST(((QLitObject[]){
   1185                        QLIT_QDICT(((QLitDictEntry[]){
   1186                                    {},
   1187                                        })),
   1188                        {},
   1189                            })),
   1190        },
   1191        { }
   1192    };
   1193
   1194    for (i = 0; test_cases[i].encoded; i++) {
   1195        QObject *obj;
   1196        GString *str;
   1197
   1198        obj = qobject_from_json(test_cases[i].encoded, &error_abort);
   1199        g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
   1200
   1201        str = qobject_to_json(obj);
   1202        qobject_unref(obj);
   1203
   1204        obj = qobject_from_json(str->str, &error_abort);
   1205        g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
   1206        qobject_unref(obj);
   1207        g_string_free(str, true);
   1208    }
   1209}
   1210
   1211static void simple_whitespace(void)
   1212{
   1213    int i;
   1214    struct {
   1215        const char *encoded;
   1216        QLitObject decoded;
   1217    } test_cases[] = {
   1218        {
   1219            .encoded = " [ 43 , 42 ]",
   1220            .decoded = QLIT_QLIST(((QLitObject[]){
   1221                        QLIT_QNUM(43),
   1222                        QLIT_QNUM(42),
   1223                        { }
   1224                    })),
   1225        },
   1226        {
   1227            .encoded = "\t[ 43 , { 'h' : 'b' },\r\n\t[ ], 42 ]\n",
   1228            .decoded = QLIT_QLIST(((QLitObject[]){
   1229                        QLIT_QNUM(43),
   1230                        QLIT_QDICT(((QLitDictEntry[]){
   1231                                    { "h", QLIT_QSTR("b") },
   1232                                    { }})),
   1233                        QLIT_QLIST(((QLitObject[]){
   1234                                    { }})),
   1235                        QLIT_QNUM(42),
   1236                        { }
   1237                    })),
   1238        },
   1239        {
   1240            .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]",
   1241            .decoded = QLIT_QLIST(((QLitObject[]){
   1242                        QLIT_QNUM(43),
   1243                        QLIT_QDICT(((QLitDictEntry[]){
   1244                                    { "h", QLIT_QSTR("b") },
   1245                                    { "a", QLIT_QNUM(32) },
   1246                                    { }})),
   1247                        QLIT_QLIST(((QLitObject[]){
   1248                                    { }})),
   1249                        QLIT_QNUM(42),
   1250                        { }
   1251                    })),
   1252        },
   1253        { }
   1254    };
   1255
   1256    for (i = 0; test_cases[i].encoded; i++) {
   1257        QObject *obj;
   1258        GString *str;
   1259
   1260        obj = qobject_from_json(test_cases[i].encoded, &error_abort);
   1261        g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
   1262
   1263        str = qobject_to_json(obj);
   1264        qobject_unref(obj);
   1265
   1266        obj = qobject_from_json(str->str, &error_abort);
   1267        g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj));
   1268
   1269        qobject_unref(obj);
   1270        g_string_free(str, true);
   1271    }
   1272}
   1273
   1274static void simple_interpolation(void)
   1275{
   1276    QObject *embedded_obj;
   1277    QObject *obj;
   1278    QLitObject decoded = QLIT_QLIST(((QLitObject[]){
   1279            QLIT_QNUM(1),
   1280            QLIT_QSTR("100%"),
   1281            QLIT_QLIST(((QLitObject[]){
   1282                        QLIT_QNUM(32),
   1283                        QLIT_QNUM(42),
   1284                        {}})),
   1285            {}}));
   1286
   1287    embedded_obj = qobject_from_json("[32, 42]", &error_abort);
   1288    g_assert(embedded_obj != NULL);
   1289
   1290    obj = qobject_from_jsonf_nofail("[%d, '100%%', %p]", 1, embedded_obj);
   1291    g_assert(qlit_equal_qobject(&decoded, obj));
   1292
   1293    qobject_unref(obj);
   1294}
   1295
   1296static void empty_input(void)
   1297{
   1298    Error *err = NULL;
   1299    QObject *obj;
   1300
   1301    obj = qobject_from_json("", &err);
   1302    error_free_or_abort(&err);
   1303    g_assert(obj == NULL);
   1304}
   1305
   1306static void blank_input(void)
   1307{
   1308    Error *err = NULL;
   1309    QObject *obj;
   1310
   1311    obj = qobject_from_json("\n ", &err);
   1312    error_free_or_abort(&err);
   1313    g_assert(obj == NULL);
   1314}
   1315
   1316static void junk_input(void)
   1317{
   1318    /* Note: junk within strings is covered elsewhere */
   1319    Error *err = NULL;
   1320    QObject *obj;
   1321
   1322    obj = qobject_from_json("@", &err);
   1323    error_free_or_abort(&err);
   1324    g_assert(obj == NULL);
   1325
   1326    obj = qobject_from_json("{\x01", &err);
   1327    error_free_or_abort(&err);
   1328    g_assert(obj == NULL);
   1329
   1330    obj = qobject_from_json("[0\xFF]", &err);
   1331    error_free_or_abort(&err);
   1332    g_assert(obj == NULL);
   1333
   1334    obj = qobject_from_json("00", &err);
   1335    error_free_or_abort(&err);
   1336    g_assert(obj == NULL);
   1337
   1338    obj = qobject_from_json("[1e", &err);
   1339    error_free_or_abort(&err);
   1340    g_assert(obj == NULL);
   1341
   1342    obj = qobject_from_json("truer", &err);
   1343    error_free_or_abort(&err);
   1344    g_assert(obj == NULL);
   1345}
   1346
   1347static void unterminated_string(void)
   1348{
   1349    Error *err = NULL;
   1350    QObject *obj = qobject_from_json("\"abc", &err);
   1351    error_free_or_abort(&err);
   1352    g_assert(obj == NULL);
   1353}
   1354
   1355static void unterminated_sq_string(void)
   1356{
   1357    Error *err = NULL;
   1358    QObject *obj = qobject_from_json("'abc", &err);
   1359    error_free_or_abort(&err);
   1360    g_assert(obj == NULL);
   1361}
   1362
   1363static void unterminated_escape(void)
   1364{
   1365    Error *err = NULL;
   1366    QObject *obj = qobject_from_json("\"abc\\\"", &err);
   1367    error_free_or_abort(&err);
   1368    g_assert(obj == NULL);
   1369}
   1370
   1371static void unterminated_array(void)
   1372{
   1373    Error *err = NULL;
   1374    QObject *obj = qobject_from_json("[32", &err);
   1375    error_free_or_abort(&err);
   1376    g_assert(obj == NULL);
   1377}
   1378
   1379static void unterminated_array_comma(void)
   1380{
   1381    Error *err = NULL;
   1382    QObject *obj = qobject_from_json("[32,", &err);
   1383    error_free_or_abort(&err);
   1384    g_assert(obj == NULL);
   1385}
   1386
   1387static void invalid_array_comma(void)
   1388{
   1389    Error *err = NULL;
   1390    QObject *obj = qobject_from_json("[32,}", &err);
   1391    error_free_or_abort(&err);
   1392    g_assert(obj == NULL);
   1393}
   1394
   1395static void unterminated_dict(void)
   1396{
   1397    Error *err = NULL;
   1398    QObject *obj = qobject_from_json("{'abc':32", &err);
   1399    error_free_or_abort(&err);
   1400    g_assert(obj == NULL);
   1401}
   1402
   1403static void unterminated_dict_comma(void)
   1404{
   1405    Error *err = NULL;
   1406    QObject *obj = qobject_from_json("{'abc':32,", &err);
   1407    error_free_or_abort(&err);
   1408    g_assert(obj == NULL);
   1409}
   1410
   1411static void invalid_dict_comma(void)
   1412{
   1413    Error *err = NULL;
   1414    QObject *obj = qobject_from_json("{'abc':32,}", &err);
   1415    error_free_or_abort(&err);
   1416    g_assert(obj == NULL);
   1417}
   1418
   1419static void invalid_dict_key(void)
   1420{
   1421    Error *err = NULL;
   1422    QObject *obj = qobject_from_json("{32:'abc'}", &err);
   1423    error_free_or_abort(&err);
   1424    g_assert(obj == NULL);
   1425}
   1426
   1427static void unterminated_literal(void)
   1428{
   1429    Error *err = NULL;
   1430    QObject *obj = qobject_from_json("nul", &err);
   1431    error_free_or_abort(&err);
   1432    g_assert(obj == NULL);
   1433}
   1434
   1435static char *make_nest(char *buf, size_t cnt)
   1436{
   1437    memset(buf, '[', cnt - 1);
   1438    buf[cnt - 1] = '{';
   1439    buf[cnt] = '}';
   1440    memset(buf + cnt + 1, ']', cnt - 1);
   1441    buf[2 * cnt] = 0;
   1442    return buf;
   1443}
   1444
   1445static void limits_nesting(void)
   1446{
   1447    Error *err = NULL;
   1448    enum { max_nesting = 1024 }; /* see qobject/json-streamer.c */
   1449    char buf[2 * (max_nesting + 1) + 1];
   1450    QObject *obj;
   1451
   1452    obj = qobject_from_json(make_nest(buf, max_nesting), &error_abort);
   1453    g_assert(obj != NULL);
   1454    qobject_unref(obj);
   1455
   1456    obj = qobject_from_json(make_nest(buf, max_nesting + 1), &err);
   1457    error_free_or_abort(&err);
   1458    g_assert(obj == NULL);
   1459}
   1460
   1461static void multiple_values(void)
   1462{
   1463    Error *err = NULL;
   1464    QObject *obj;
   1465
   1466    obj = qobject_from_json("false true", &err);
   1467    error_free_or_abort(&err);
   1468    g_assert(obj == NULL);
   1469
   1470    obj = qobject_from_json("} true", &err);
   1471    error_free_or_abort(&err);
   1472    g_assert(obj == NULL);
   1473}
   1474
   1475int main(int argc, char **argv)
   1476{
   1477    g_test_init(&argc, &argv, NULL);
   1478
   1479    g_test_add_func("/literals/string/escaped", escaped_string);
   1480    g_test_add_func("/literals/string/quotes", string_with_quotes);
   1481    g_test_add_func("/literals/string/utf8", utf8_string);
   1482
   1483    g_test_add_func("/literals/number/int", int_number);
   1484    g_test_add_func("/literals/number/uint", uint_number);
   1485    g_test_add_func("/literals/number/float", float_number);
   1486
   1487    g_test_add_func("/literals/keyword", keyword_literal);
   1488
   1489    g_test_add_func("/literals/interpolation/valid", interpolation_valid);
   1490    g_test_add_func("/literals/interpolation/unkown", interpolation_unknown);
   1491    g_test_add_func("/literals/interpolation/string", interpolation_string);
   1492
   1493    g_test_add_func("/dicts/simple_dict", simple_dict);
   1494    g_test_add_func("/dicts/large_dict", large_dict);
   1495    g_test_add_func("/lists/simple_list", simple_list);
   1496
   1497    g_test_add_func("/mixed/simple_whitespace", simple_whitespace);
   1498    g_test_add_func("/mixed/interpolation", simple_interpolation);
   1499
   1500    g_test_add_func("/errors/empty", empty_input);
   1501    g_test_add_func("/errors/blank", blank_input);
   1502    g_test_add_func("/errors/junk", junk_input);
   1503    g_test_add_func("/errors/unterminated/string", unterminated_string);
   1504    g_test_add_func("/errors/unterminated/escape", unterminated_escape);
   1505    g_test_add_func("/errors/unterminated/sq_string", unterminated_sq_string);
   1506    g_test_add_func("/errors/unterminated/array", unterminated_array);
   1507    g_test_add_func("/errors/unterminated/array_comma", unterminated_array_comma);
   1508    g_test_add_func("/errors/unterminated/dict", unterminated_dict);
   1509    g_test_add_func("/errors/unterminated/dict_comma", unterminated_dict_comma);
   1510    g_test_add_func("/errors/invalid_array_comma", invalid_array_comma);
   1511    g_test_add_func("/errors/invalid_dict_comma", invalid_dict_comma);
   1512    g_test_add_func("/errors/invalid_dict_key", invalid_dict_key);
   1513    g_test_add_func("/errors/unterminated/literal", unterminated_literal);
   1514    g_test_add_func("/errors/limits/nesting", limits_nesting);
   1515    g_test_add_func("/errors/multiple_values", multiple_values);
   1516
   1517    return g_test_run();
   1518}