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