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#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}
1519