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