1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* util/support/json.c - JSON parser and unparser */ 3 /* 4 * Copyright (c) 2010 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Portions Copyright (c) 2010 Apple Inc. All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * 3. Neither the name of the Institute nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 /* 38 * Copyright (C) 2012 by the Massachusetts Institute of Technology. 39 * All rights reserved. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 45 * * Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 48 * * Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in 50 * the documentation and/or other materials provided with the 51 * distribution. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 54 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 55 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 56 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 57 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 58 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 59 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 60 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 62 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 64 * OF THE POSSIBILITY OF SUCH DAMAGE. 65 */ 66 67 /* 68 * This file implements a minimal dynamic type system for JSON values and a 69 * JSON encoder and decoder. It is loosely based on the heimbase code from 70 * Heimdal. 71 */ 72 73 #include <k5-platform.h> 74 #include <k5-base64.h> 75 #include <k5-json.h> 76 #include <k5-buf.h> 77 78 #define MAX_DECODE_DEPTH 64 79 #define MIN_ALLOC_SLOT 16 80 81 typedef void (*type_dealloc_fn)(void *val); 82 83 typedef struct json_type_st { 84 k5_json_tid tid; 85 const char *name; 86 type_dealloc_fn dealloc; 87 } *json_type; 88 89 struct value_base { 90 json_type isa; 91 unsigned int ref_cnt; 92 }; 93 94 #define PTR2BASE(ptr) (((struct value_base *)ptr) - 1) 95 #define BASE2PTR(ptr) ((void *)(((struct value_base *)ptr) + 1)) 96 97 k5_json_value 98 k5_json_retain(k5_json_value val) 99 { 100 struct value_base *p; 101 102 if (val == NULL) 103 return val; 104 p = PTR2BASE(val); 105 assert(p->ref_cnt != 0); 106 p->ref_cnt++; 107 return val; 108 } 109 110 void 111 k5_json_release(k5_json_value val) 112 { 113 struct value_base *p; 114 115 if (val == NULL) 116 return; 117 p = PTR2BASE(val); 118 assert(p->ref_cnt != 0); 119 p->ref_cnt--; 120 if (p->ref_cnt == 0) { 121 if (p->isa->dealloc != NULL) 122 p->isa->dealloc(val); 123 free(p); 124 } 125 } 126 127 /* Get the type description of a k5_json_value. */ 128 static json_type 129 get_isa(k5_json_value val) 130 { 131 struct value_base *p = PTR2BASE(val); 132 133 return p->isa; 134 } 135 136 k5_json_tid 137 k5_json_get_tid(k5_json_value val) 138 { 139 json_type isa = get_isa(val); 140 141 return isa->tid; 142 } 143 144 static k5_json_value 145 alloc_value(json_type type, size_t size) 146 { 147 struct value_base *p = calloc(1, size + sizeof(*p)); 148 149 if (p == NULL) 150 return NULL; 151 p->isa = type; 152 p->ref_cnt = 1; 153 154 return BASE2PTR(p); 155 } 156 157 /*** Null type ***/ 158 159 static struct json_type_st null_type = { K5_JSON_TID_NULL, "null", NULL }; 160 161 int 162 k5_json_null_create(k5_json_null *val_out) 163 { 164 *val_out = alloc_value(&null_type, 0); 165 return (*val_out == NULL) ? ENOMEM : 0; 166 } 167 168 int 169 k5_json_null_create_val(k5_json_value *val_out) 170 { 171 *val_out = alloc_value(&null_type, 0); 172 return (*val_out == NULL) ? ENOMEM : 0; 173 } 174 175 /*** Boolean type ***/ 176 177 static struct json_type_st bool_type = { K5_JSON_TID_BOOL, "bool", NULL }; 178 179 int 180 k5_json_bool_create(int truth, k5_json_bool *val_out) 181 { 182 k5_json_bool b; 183 184 *val_out = NULL; 185 b = alloc_value(&bool_type, 1); 186 if (b == NULL) 187 return ENOMEM; 188 *(unsigned char *)b = !!truth; 189 *val_out = b; 190 return 0; 191 } 192 193 int 194 k5_json_bool_value(k5_json_bool bval) 195 { 196 return *(unsigned char *)bval; 197 } 198 199 /*** Array type ***/ 200 201 struct k5_json_array_st { 202 k5_json_value *values; 203 size_t len; 204 size_t allocated; 205 }; 206 207 static void 208 array_dealloc(void *ptr) 209 { 210 k5_json_array array = ptr; 211 size_t i; 212 213 for (i = 0; i < array->len; i++) 214 k5_json_release(array->values[i]); 215 free(array->values); 216 } 217 218 static struct json_type_st array_type = { 219 K5_JSON_TID_ARRAY, "array", array_dealloc 220 }; 221 222 int 223 k5_json_array_create(k5_json_array *val_out) 224 { 225 *val_out = alloc_value(&array_type, sizeof(struct k5_json_array_st)); 226 return (*val_out == NULL) ? ENOMEM : 0; 227 } 228 229 int 230 k5_json_array_add(k5_json_array array, k5_json_value val) 231 { 232 k5_json_value *ptr; 233 size_t new_alloc; 234 235 if (array->len >= array->allocated) { 236 /* Increase the number of slots by 50% (MIN_ALLOC_SLOT minimum). */ 237 new_alloc = array->len + 1 + (array->len >> 1); 238 if (new_alloc < MIN_ALLOC_SLOT) 239 new_alloc = MIN_ALLOC_SLOT; 240 ptr = realloc(array->values, new_alloc * sizeof(*array->values)); 241 if (ptr == NULL) 242 return ENOMEM; 243 array->values = ptr; 244 array->allocated = new_alloc; 245 } 246 array->values[array->len++] = k5_json_retain(val); 247 return 0; 248 } 249 250 size_t 251 k5_json_array_length(k5_json_array array) 252 { 253 return array->len; 254 } 255 256 k5_json_value 257 k5_json_array_get(k5_json_array array, size_t idx) 258 { 259 if (idx >= array->len) 260 abort(); 261 return array->values[idx]; 262 } 263 264 void 265 k5_json_array_set(k5_json_array array, size_t idx, k5_json_value val) 266 { 267 if (idx >= array->len) 268 abort(); 269 k5_json_release(array->values[idx]); 270 array->values[idx] = k5_json_retain(val); 271 } 272 273 int 274 k5_json_array_fmt(k5_json_array *array_out, const char *template, ...) 275 { 276 const char *p; 277 va_list ap; 278 const char *cstring; 279 unsigned char *data; 280 size_t len; 281 long long nval; 282 k5_json_array array; 283 k5_json_value val; 284 k5_json_number num; 285 k5_json_string str; 286 k5_json_bool b; 287 k5_json_null null; 288 int truth, ret; 289 290 *array_out = NULL; 291 if (k5_json_array_create(&array)) 292 return ENOMEM; 293 va_start(ap, template); 294 for (p = template; *p != '\0'; p++) { 295 switch (*p) { 296 case 'v': 297 val = k5_json_retain(va_arg(ap, k5_json_value)); 298 break; 299 case 'n': 300 if (k5_json_null_create(&null)) 301 goto err; 302 val = null; 303 break; 304 case 'b': 305 truth = va_arg(ap, int); 306 if (k5_json_bool_create(truth, &b)) 307 goto err; 308 val = b; 309 break; 310 case 'i': 311 nval = va_arg(ap, int); 312 if (k5_json_number_create(nval, &num)) 313 goto err; 314 val = num; 315 break; 316 case 'L': 317 nval = va_arg(ap, long long); 318 if (k5_json_number_create(nval, &num)) 319 goto err; 320 val = num; 321 break; 322 case 's': 323 cstring = va_arg(ap, const char *); 324 if (cstring == NULL) { 325 if (k5_json_null_create(&null)) 326 goto err; 327 val = null; 328 } else { 329 if (k5_json_string_create(cstring, &str)) 330 goto err; 331 val = str; 332 } 333 break; 334 case 'B': 335 data = va_arg(ap, unsigned char *); 336 len = va_arg(ap, size_t); 337 if (k5_json_string_create_base64(data, len, &str)) 338 goto err; 339 val = str; 340 break; 341 default: 342 goto err; 343 } 344 ret = k5_json_array_add(array, val); 345 k5_json_release(val); 346 if (ret) 347 goto err; 348 } 349 va_end(ap); 350 *array_out = array; 351 return 0; 352 353 err: 354 va_end(ap); 355 k5_json_release(array); 356 return ENOMEM; 357 } 358 359 /*** Object type (string:value mapping) ***/ 360 361 struct entry { 362 char *key; 363 k5_json_value value; 364 }; 365 366 struct k5_json_object_st { 367 struct entry *entries; 368 size_t len; 369 size_t allocated; 370 }; 371 372 static void 373 object_dealloc(void *ptr) 374 { 375 k5_json_object obj = ptr; 376 size_t i; 377 378 for (i = 0; i < obj->len; i++) { 379 free(obj->entries[i].key); 380 k5_json_release(obj->entries[i].value); 381 } 382 free(obj->entries); 383 } 384 385 static struct json_type_st object_type = { 386 K5_JSON_TID_OBJECT, "object", object_dealloc 387 }; 388 389 int 390 k5_json_object_create(k5_json_object *val_out) 391 { 392 *val_out = alloc_value(&object_type, sizeof(struct k5_json_object_st)); 393 return (*val_out == NULL) ? ENOMEM : 0; 394 } 395 396 size_t 397 k5_json_object_count(k5_json_object obj) 398 { 399 return obj->len; 400 } 401 402 /* Return the entry for key within obj, or NULL if none exists. */ 403 static struct entry * 404 object_search(k5_json_object obj, const char *key) 405 { 406 size_t i; 407 408 for (i = 0; i < obj->len; i++) { 409 if (strcmp(key, obj->entries[i].key) == 0) 410 return &obj->entries[i]; 411 } 412 return NULL; 413 } 414 415 k5_json_value 416 k5_json_object_get(k5_json_object obj, const char *key) 417 { 418 struct entry *ent; 419 420 ent = object_search(obj, key); 421 if (ent == NULL) 422 return NULL; 423 return ent->value; 424 } 425 426 int 427 k5_json_object_set(k5_json_object obj, const char *key, k5_json_value val) 428 { 429 struct entry *ent, *ptr; 430 size_t new_alloc, i; 431 432 ent = object_search(obj, key); 433 if (ent != NULL) { 434 k5_json_release(ent->value); 435 if (val == NULL) { 436 /* Remove this key. */ 437 free(ent->key); 438 for (i = ent - obj->entries; i < obj->len - 1; i++) 439 obj->entries[i] = obj->entries[i + 1]; 440 obj->len--; 441 } else { 442 /* Overwrite this key's value with the new one. */ 443 ent->value = k5_json_retain(val); 444 } 445 return 0; 446 } 447 448 /* If didn't find a key the caller asked to remove, do nothing. */ 449 if (val == NULL) 450 return 0; 451 452 if (obj->len >= obj->allocated) { 453 /* Increase the number of slots by 50% (MIN_ALLOC_SLOT minimum). */ 454 new_alloc = obj->len + 1 + (obj->len >> 1); 455 if (new_alloc < MIN_ALLOC_SLOT) 456 new_alloc = MIN_ALLOC_SLOT; 457 ptr = realloc(obj->entries, new_alloc * sizeof(*obj->entries)); 458 if (ptr == NULL) 459 return ENOMEM; 460 obj->entries = ptr; 461 obj->allocated = new_alloc; 462 } 463 obj->entries[obj->len].key = strdup(key); 464 if (obj->entries[obj->len].key == NULL) 465 return ENOMEM; 466 obj->entries[obj->len].value = k5_json_retain(val); 467 obj->len++; 468 return 0; 469 } 470 471 void 472 k5_json_object_iterate(k5_json_object obj, k5_json_object_iterator_fn func, 473 void *arg) 474 { 475 size_t i; 476 477 for (i = 0; i < obj->len; i++) 478 func(arg, obj->entries[i].key, obj->entries[i].value); 479 } 480 481 /*** String type ***/ 482 483 static struct json_type_st string_type = { 484 K5_JSON_TID_STRING, "string", NULL 485 }; 486 487 int 488 k5_json_string_create(const char *cstring, k5_json_string *val_out) 489 { 490 return k5_json_string_create_len(cstring, strlen(cstring), val_out); 491 } 492 493 int 494 k5_json_string_create_len(const void *data, size_t len, 495 k5_json_string *val_out) 496 { 497 char *s; 498 499 *val_out = NULL; 500 s = alloc_value(&string_type, len + 1); 501 if (s == NULL) 502 return ENOMEM; 503 if (len > 0) 504 memcpy(s, data, len); 505 s[len] = '\0'; 506 *val_out = (k5_json_string)s; 507 return 0; 508 } 509 510 int 511 k5_json_string_create_base64(const void *data, size_t len, 512 k5_json_string *val_out) 513 { 514 char *base64; 515 int ret; 516 517 *val_out = NULL; 518 base64 = k5_base64_encode(data, len); 519 if (base64 == NULL) 520 return ENOMEM; 521 ret = k5_json_string_create(base64, val_out); 522 free(base64); 523 return ret; 524 } 525 526 const char * 527 k5_json_string_utf8(k5_json_string string) 528 { 529 return (const char *)string; 530 } 531 532 int 533 k5_json_string_unbase64(k5_json_string string, unsigned char **data_out, 534 size_t *len_out) 535 { 536 unsigned char *data; 537 size_t len; 538 539 *data_out = NULL; 540 *len_out = 0; 541 data = k5_base64_decode((const char *)string, &len); 542 if (data == NULL) 543 return (len == 0) ? ENOMEM : EINVAL; 544 *data_out = data; 545 *len_out = len; 546 return 0; 547 } 548 549 /*** Number type ***/ 550 551 static struct json_type_st number_type = { 552 K5_JSON_TID_NUMBER, "number", NULL 553 }; 554 555 int 556 k5_json_number_create(long long number, k5_json_number *val_out) 557 { 558 k5_json_number n; 559 560 *val_out = NULL; 561 n = alloc_value(&number_type, sizeof(long long)); 562 if (n == NULL) 563 return ENOMEM; 564 *((long long *)n) = number; 565 *val_out = n; 566 return 0; 567 } 568 569 long long 570 k5_json_number_value(k5_json_number number) 571 { 572 return *(long long *)number; 573 } 574 575 /*** JSON encoding ***/ 576 577 static const char quotemap_json[] = "\"\\/bfnrt"; 578 static const char quotemap_c[] = "\"\\/\b\f\n\r\t"; 579 static const char needs_quote[] = "\\\"\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17" 580 "\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37"; 581 582 static int encode_value(struct k5buf *buf, k5_json_value val); 583 584 static void 585 encode_string(struct k5buf *buf, const char *str) 586 { 587 size_t n; 588 const char *p; 589 590 k5_buf_add(buf, "\""); 591 while (*str != '\0') { 592 n = strcspn(str, needs_quote); 593 k5_buf_add_len(buf, str, n); 594 str += n; 595 if (*str == '\0') 596 break; 597 k5_buf_add(buf, "\\"); 598 p = strchr(quotemap_c, *str); 599 if (p != NULL) 600 k5_buf_add_len(buf, quotemap_json + (p - quotemap_c), 1); 601 else 602 k5_buf_add_fmt(buf, "u00%02X", (unsigned int)*str); 603 str++; 604 } 605 k5_buf_add(buf, "\""); 606 } 607 608 struct obj_ctx { 609 struct k5buf *buf; 610 int ret; 611 int first; 612 }; 613 614 static void 615 encode_obj_entry(void *ctx, const char *key, k5_json_value value) 616 { 617 struct obj_ctx *j = ctx; 618 619 if (j->ret) 620 return; 621 if (j->first) 622 j->first = 0; 623 else 624 k5_buf_add(j->buf, ","); 625 encode_string(j->buf, key); 626 k5_buf_add(j->buf, ":"); 627 j->ret = encode_value(j->buf, value); 628 } 629 630 static int 631 encode_value(struct k5buf *buf, k5_json_value val) 632 { 633 k5_json_tid type; 634 int ret; 635 size_t i, len; 636 struct obj_ctx ctx; 637 638 if (val == NULL) 639 return EINVAL; 640 641 type = k5_json_get_tid(val); 642 switch (type) { 643 case K5_JSON_TID_ARRAY: 644 k5_buf_add(buf, "["); 645 len = k5_json_array_length(val); 646 for (i = 0; i < len; i++) { 647 if (i != 0) 648 k5_buf_add(buf, ","); 649 ret = encode_value(buf, k5_json_array_get(val, i)); 650 if (ret) 651 return ret; 652 } 653 k5_buf_add(buf, "]"); 654 return 0; 655 656 case K5_JSON_TID_OBJECT: 657 k5_buf_add(buf, "{"); 658 ctx.buf = buf; 659 ctx.ret = 0; 660 ctx.first = 1; 661 k5_json_object_iterate(val, encode_obj_entry, &ctx); 662 k5_buf_add(buf, "}"); 663 return ctx.ret; 664 665 case K5_JSON_TID_STRING: 666 encode_string(buf, k5_json_string_utf8(val)); 667 return 0; 668 669 case K5_JSON_TID_NUMBER: 670 k5_buf_add_fmt(buf, "%lld", k5_json_number_value(val)); 671 return 0; 672 673 case K5_JSON_TID_NULL: 674 k5_buf_add(buf, "null"); 675 return 0; 676 677 case K5_JSON_TID_BOOL: 678 k5_buf_add(buf, k5_json_bool_value(val) ? "true" : "false"); 679 return 0; 680 681 default: 682 return EINVAL; 683 } 684 } 685 686 int 687 k5_json_encode(k5_json_value val, char **json_out) 688 { 689 struct k5buf buf; 690 int ret; 691 692 *json_out = NULL; 693 k5_buf_init_dynamic(&buf); 694 ret = encode_value(&buf, val); 695 if (ret) { 696 k5_buf_free(&buf); 697 return ret; 698 } 699 *json_out = k5_buf_cstring(&buf); 700 return (*json_out == NULL) ? ENOMEM : 0; 701 } 702 703 /*** JSON decoding ***/ 704 705 struct decode_ctx { 706 const unsigned char *p; 707 size_t depth; 708 }; 709 710 static int parse_value(struct decode_ctx *ctx, k5_json_value *val_out); 711 712 /* Consume whitespace. Return 0 if there is anything left to parse after the 713 * whitespace, -1 if not. */ 714 static int 715 white_spaces(struct decode_ctx *ctx) 716 { 717 unsigned char c; 718 719 for (; *ctx->p != '\0'; ctx->p++) { 720 c = *ctx->p; 721 if (c != ' ' && c != '\t' && c != '\r' && c != '\n') 722 return 0; 723 } 724 return -1; 725 } 726 727 /* Return true if c is a decimal digit. */ 728 static inline int 729 is_digit(unsigned char c) 730 { 731 return ('0' <= c && c <= '9'); 732 } 733 734 /* Return true if c is a hexadecimal digit (per RFC 5234 HEXDIG). */ 735 static inline int 736 is_hex_digit(unsigned char c) 737 { 738 return is_digit(c) || ('A' <= c && c <= 'F'); 739 } 740 741 /* Return the numeric value of a hex digit; aborts if c is not a hex digit. */ 742 static inline unsigned int 743 hexval(unsigned char c) 744 { 745 if (is_digit(c)) 746 return c - '0'; 747 else if ('A' <= c && c <= 'F') 748 return c - 'A' + 10; 749 abort(); 750 } 751 752 /* Parse a JSON number (which must be an integer in the signed 64-bit range; we 753 * do not allow floating-point numbers). */ 754 static int 755 parse_number(struct decode_ctx *ctx, k5_json_number *val_out) 756 { 757 const unsigned long long umax = ~0ULL, smax = (1ULL << 63) - 1; 758 unsigned long long number = 0; 759 int neg = 1; 760 761 *val_out = NULL; 762 763 if (*ctx->p == '-') { 764 neg = -1; 765 ctx->p++; 766 } 767 768 if (!is_digit(*ctx->p)) 769 return EINVAL; 770 771 /* Read the number into an unsigned 64-bit container, ensuring that we 772 * don't overflow it. */ 773 while (is_digit(*ctx->p)) { 774 if (number + 1 > umax / 10) 775 return EOVERFLOW; 776 number = (number * 10) + (*ctx->p - '0'); 777 ctx->p++; 778 } 779 780 /* Make sure the unsigned 64-bit value fits in the signed 64-bit range. */ 781 if (number > smax + 1 || (number > smax && neg == 1)) 782 return EOVERFLOW; 783 784 return k5_json_number_create(number * neg, val_out); 785 } 786 787 /* Parse a JSON string (which must not quote Unicode code points above 256). */ 788 static int 789 parse_string(struct decode_ctx *ctx, char **str_out) 790 { 791 const unsigned char *p, *start, *end = NULL; 792 const char *q; 793 char *buf, *pos; 794 unsigned int code; 795 796 *str_out = NULL; 797 798 /* Find the start and end of the string. */ 799 if (*ctx->p != '"') 800 return EINVAL; 801 start = ++ctx->p; 802 for (; *ctx->p != '\0'; ctx->p++) { 803 if (*ctx->p == '\\') { 804 ctx->p++; 805 if (*ctx->p == '\0') 806 return EINVAL; 807 } else if (*ctx->p == '"') { 808 end = ctx->p++; 809 break; 810 } 811 } 812 if (end == NULL) 813 return EINVAL; 814 815 pos = buf = malloc(end - start + 1); 816 if (buf == NULL) 817 return ENOMEM; 818 for (p = start; p < end;) { 819 if (*p == '\\') { 820 p++; 821 if (*p == 'u' && is_hex_digit(p[1]) && is_hex_digit(p[2]) && 822 is_hex_digit(p[3]) && is_hex_digit(p[4])) { 823 code = (hexval(p[1]) << 12) | (hexval(p[2]) << 8) | 824 (hexval(p[3]) << 4) | hexval(p[4]); 825 if (code <= 0xff) { 826 *pos++ = code; 827 } else { 828 /* Code points above 0xff don't need to be quoted, so we 829 * don't implement translating those into UTF-8. */ 830 free(buf); 831 return EINVAL; 832 } 833 p += 5; 834 } else { 835 q = strchr(quotemap_json, *p); 836 if (q != NULL) { 837 *pos++ = quotemap_c[q - quotemap_json]; 838 } else { 839 free(buf); 840 return EINVAL; 841 } 842 p++; 843 } 844 } else { 845 *pos++ = *p++; 846 } 847 } 848 *pos = '\0'; 849 *str_out = buf; 850 return 0; 851 } 852 853 /* Parse an object association and place it into obj. */ 854 static int 855 parse_object_association(k5_json_object obj, struct decode_ctx *ctx) 856 { 857 char *key = NULL; 858 k5_json_value val; 859 int ret; 860 861 /* Parse the key and value. */ 862 ret = parse_string(ctx, &key); 863 if (ret) 864 return ret; 865 if (white_spaces(ctx)) 866 goto invalid; 867 if (*ctx->p != ':') 868 goto invalid; 869 ctx->p++; 870 if (white_spaces(ctx)) 871 goto invalid; 872 ret = parse_value(ctx, &val); 873 if (ret) { 874 free(key); 875 return ret; 876 } 877 878 /* Add the key and value to obj. */ 879 ret = k5_json_object_set(obj, key, val); 880 free(key); 881 k5_json_release(val); 882 return ret; 883 884 invalid: 885 free(key); 886 return EINVAL; 887 } 888 889 /* Parse a JSON object. */ 890 static int 891 parse_object(struct decode_ctx *ctx, k5_json_object *val_out) 892 { 893 k5_json_object obj = NULL; 894 int ret; 895 896 *val_out = NULL; 897 898 /* Parse past the opening brace. */ 899 if (*ctx->p != '{') 900 return EINVAL; 901 ctx->p++; 902 if (white_spaces(ctx)) 903 return EINVAL; 904 905 ret = k5_json_object_create(&obj); 906 if (ret) 907 return ret; 908 909 /* Pairs associations until we reach the terminating brace. */ 910 if (*ctx->p != '}') { 911 while (1) { 912 ret = parse_object_association(obj, ctx); 913 if (ret) { 914 k5_json_release(obj); 915 return ret; 916 } 917 if (white_spaces(ctx)) 918 goto invalid; 919 if (*ctx->p == '}') 920 break; 921 if (*ctx->p != ',') 922 goto invalid; 923 ctx->p++; 924 if (white_spaces(ctx)) 925 goto invalid; 926 } 927 } 928 ctx->p++; 929 *val_out = obj; 930 return 0; 931 932 invalid: 933 k5_json_release(obj); 934 return EINVAL; 935 } 936 937 /* Parse an value and place it into array. */ 938 static int 939 parse_array_item(k5_json_array array, struct decode_ctx *ctx) 940 { 941 k5_json_value val; 942 int ret; 943 944 ret = parse_value(ctx, &val); 945 if (ret) 946 return ret; 947 ret = k5_json_array_add(array, val); 948 k5_json_release(val); 949 return ret; 950 } 951 952 /* Parse a JSON array. */ 953 static int 954 parse_array(struct decode_ctx *ctx, k5_json_array *val_out) 955 { 956 k5_json_array array = NULL; 957 int ret; 958 959 *val_out = NULL; 960 961 /* Parse past the opening bracket. */ 962 if (*ctx->p != '[') 963 return EINVAL; 964 ctx->p++; 965 if (white_spaces(ctx)) 966 return EINVAL; 967 968 ret = k5_json_array_create(&array); 969 if (ret) 970 return ret; 971 972 /* Pairs values until we reach the terminating bracket. */ 973 if (*ctx->p != ']') { 974 while (1) { 975 ret = parse_array_item(array, ctx); 976 if (ret) { 977 k5_json_release(array); 978 return ret; 979 } 980 if (white_spaces(ctx)) 981 goto invalid; 982 if (*ctx->p == ']') 983 break; 984 if (*ctx->p != ',') 985 goto invalid; 986 ctx->p++; 987 if (white_spaces(ctx)) 988 goto invalid; 989 } 990 } 991 ctx->p++; 992 *val_out = array; 993 return 0; 994 995 invalid: 996 k5_json_release(array); 997 return EINVAL; 998 } 999 1000 /* Parse a JSON value of any type. */ 1001 static int 1002 parse_value(struct decode_ctx *ctx, k5_json_value *val_out) 1003 { 1004 k5_json_null null; 1005 k5_json_bool bval; 1006 k5_json_number num; 1007 k5_json_string str; 1008 k5_json_object obj; 1009 k5_json_array array; 1010 char *cstring; 1011 int ret; 1012 1013 *val_out = NULL; 1014 1015 if (white_spaces(ctx)) 1016 return EINVAL; 1017 1018 if (*ctx->p == '"') { 1019 ret = parse_string(ctx, &cstring); 1020 if (ret) 1021 return ret; 1022 ret = k5_json_string_create(cstring, &str); 1023 free(cstring); 1024 if (ret) 1025 return ret; 1026 *val_out = str; 1027 } else if (*ctx->p == '{') { 1028 if (ctx->depth-- == 1) 1029 return EINVAL; 1030 ret = parse_object(ctx, &obj); 1031 if (ret) 1032 return ret; 1033 ctx->depth++; 1034 *val_out = obj; 1035 } else if (*ctx->p == '[') { 1036 if (ctx->depth-- == 1) 1037 return EINVAL; 1038 ret = parse_array(ctx, &array); 1039 ctx->depth++; 1040 *val_out = array; 1041 } else if (is_digit(*ctx->p) || *ctx->p == '-') { 1042 ret = parse_number(ctx, &num); 1043 if (ret) 1044 return ret; 1045 *val_out = num; 1046 } else if (strncmp((char *)ctx->p, "null", 4) == 0) { 1047 ctx->p += 4; 1048 ret = k5_json_null_create(&null); 1049 if (ret) 1050 return ret; 1051 *val_out = null; 1052 } else if (strncmp((char *)ctx->p, "true", 4) == 0) { 1053 ctx->p += 4; 1054 ret = k5_json_bool_create(1, &bval); 1055 if (ret) 1056 return ret; 1057 *val_out = bval; 1058 } else if (strncmp((char *)ctx->p, "false", 5) == 0) { 1059 ctx->p += 5; 1060 ret = k5_json_bool_create(0, &bval); 1061 if (ret) 1062 return ret; 1063 *val_out = bval; 1064 } else { 1065 return EINVAL; 1066 } 1067 1068 return 0; 1069 } 1070 1071 int 1072 k5_json_decode(const char *string, k5_json_value *val_out) 1073 { 1074 struct decode_ctx ctx; 1075 k5_json_value val; 1076 int ret; 1077 1078 *val_out = NULL; 1079 ctx.p = (unsigned char *)string; 1080 ctx.depth = MAX_DECODE_DEPTH; 1081 ret = parse_value(&ctx, &val); 1082 if (ret) 1083 return ret; 1084 if (white_spaces(&ctx) == 0) { 1085 k5_json_release(val); 1086 return EINVAL; 1087 } 1088 *val_out = val; 1089 return 0; 1090 } 1091