1 /* 2 * Copyright (c) 2015, Vsevolod Stakhov 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25 26 #ifdef HAVE_CONFIG_H 27 #include "config.h" 28 #endif 29 30 #include "ucl.h" 31 #include "ucl_internal.h" 32 33 #ifdef HAVE_ENDIAN_H 34 #include <endian.h> 35 #elif defined(HAVE_SYS_ENDIAN_H) 36 #include <sys/endian.h> 37 #elif defined(HAVE_MACHINE_ENDIAN_H) 38 #include <machine/endian.h> 39 #endif 40 41 #if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) 42 #if __BYTE_ORDER == __LITTLE_ENDIAN 43 #define __LITTLE_ENDIAN__ 44 #elif __BYTE_ORDER == __BIG_ENDIAN 45 #define __BIG_ENDIAN__ 46 #elif _WIN32 47 #define __LITTLE_ENDIAN__ 48 #endif 49 #endif 50 51 #define SWAP_LE_BE16(val) ((uint16_t) ( \ 52 (uint16_t) ((uint16_t) (val) >> 8) | \ 53 (uint16_t) ((uint16_t) (val) << 8))) 54 55 #if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 3) 56 # define SWAP_LE_BE32(val) ((uint32_t)__builtin_bswap32 ((uint32_t)(val))) 57 # define SWAP_LE_BE64(val) ((uint64_t)__builtin_bswap64 ((uint64_t)(val))) 58 #else 59 #define SWAP_LE_BE32(val) ((uint32_t)( \ 60 (((uint32_t)(val) & (uint32_t)0x000000ffU) << 24) | \ 61 (((uint32_t)(val) & (uint32_t)0x0000ff00U) << 8) | \ 62 (((uint32_t)(val) & (uint32_t)0x00ff0000U) >> 8) | \ 63 (((uint32_t)(val) & (uint32_t)0xff000000U) >> 24))) 64 65 #define SWAP_LE_BE64(val) ((uint64_t)( \ 66 (((uint64_t)(val) & \ 67 (uint64_t)(0x00000000000000ffULL)) << 56) | \ 68 (((uint64_t)(val) & \ 69 (uint64_t)(0x000000000000ff00ULL)) << 40) | \ 70 (((uint64_t)(val) & \ 71 (uint64_t)(0x0000000000ff0000ULL)) << 24) | \ 72 (((uint64_t)(val) & \ 73 (uint64_t) (0x00000000ff000000ULL)) << 8) | \ 74 (((uint64_t)(val) & \ 75 (uint64_t)(0x000000ff00000000ULL)) >> 8) | \ 76 (((uint64_t)(val) & \ 77 (uint64_t)(0x0000ff0000000000ULL)) >> 24) | \ 78 (((uint64_t)(val) & \ 79 (uint64_t)(0x00ff000000000000ULL)) >> 40) | \ 80 (((uint64_t)(val) & \ 81 (uint64_t)(0xff00000000000000ULL)) >> 56))) 82 #endif 83 84 #ifdef __LITTLE_ENDIAN__ 85 #define TO_BE16 SWAP_LE_BE16 86 #define TO_BE32 SWAP_LE_BE32 87 #define TO_BE64 SWAP_LE_BE64 88 #define FROM_BE16 SWAP_LE_BE16 89 #define FROM_BE32 SWAP_LE_BE32 90 #define FROM_BE64 SWAP_LE_BE64 91 #else 92 #define TO_BE16(val) (uint16_t)(val) 93 #define TO_BE32(val) (uint32_t)(val) 94 #define TO_BE64(val) (uint64_t)(val) 95 #define FROM_BE16(val) (uint16_t)(val) 96 #define FROM_BE32(val) (uint32_t)(val) 97 #define FROM_BE64(val) (uint64_t)(val) 98 #endif 99 100 void 101 ucl_emitter_print_int_msgpack (struct ucl_emitter_context *ctx, int64_t val) 102 { 103 const struct ucl_emitter_functions *func = ctx->func; 104 unsigned char buf[sizeof(uint64_t) + 1]; 105 const unsigned char mask_positive = 0x7f, mask_negative = 0xe0, 106 uint8_ch = 0xcc, uint16_ch = 0xcd, uint32_ch = 0xce, uint64_ch = 0xcf, 107 int8_ch = 0xd0, int16_ch = 0xd1, int32_ch = 0xd2, int64_ch = 0xd3; 108 unsigned len; 109 110 if (val >= 0) { 111 if (val <= 0x7f) { 112 /* Fixed num 7 bits */ 113 len = 1; 114 buf[0] = mask_positive & val; 115 } 116 else if (val <= 0xff) { 117 len = 2; 118 buf[0] = uint8_ch; 119 buf[1] = val & 0xff; 120 } 121 else if (val <= 0xffff) { 122 uint16_t v = TO_BE16 (val); 123 124 len = 3; 125 buf[0] = uint16_ch; 126 memcpy (&buf[1], &v, sizeof (v)); 127 } 128 else if (val <= 0xffffffff) { 129 uint32_t v = TO_BE32 (val); 130 131 len = 5; 132 buf[0] = uint32_ch; 133 memcpy (&buf[1], &v, sizeof (v)); 134 } 135 else { 136 uint64_t v = TO_BE64 (val); 137 138 len = 9; 139 buf[0] = uint64_ch; 140 memcpy (&buf[1], &v, sizeof (v)); 141 } 142 } 143 else { 144 uint64_t uval; 145 /* Bithack abs */ 146 uval = ((val ^ (val >> 63)) - (val >> 63)); 147 148 if (val > -(1 << 5)) { 149 len = 1; 150 buf[0] = (mask_negative | uval) & 0xff; 151 } 152 else if (uval <= 0xff) { 153 len = 2; 154 buf[0] = int8_ch; 155 buf[1] = (unsigned char)val; 156 } 157 else if (uval <= 0xffff) { 158 uint16_t v = TO_BE16 (val); 159 160 len = 3; 161 buf[0] = int16_ch; 162 memcpy (&buf[1], &v, sizeof (v)); 163 } 164 else if (uval <= 0xffffffff) { 165 uint32_t v = TO_BE32 (val); 166 167 len = 5; 168 buf[0] = int32_ch; 169 memcpy (&buf[1], &v, sizeof (v)); 170 } 171 else { 172 uint64_t v = TO_BE64 (val); 173 174 len = 9; 175 buf[0] = int64_ch; 176 memcpy (&buf[1], &v, sizeof (v)); 177 } 178 } 179 180 func->ucl_emitter_append_len (buf, len, func->ud); 181 } 182 183 void 184 ucl_emitter_print_double_msgpack (struct ucl_emitter_context *ctx, double val) 185 { 186 const struct ucl_emitter_functions *func = ctx->func; 187 union { 188 double d; 189 uint64_t i; 190 } u; 191 const unsigned char dbl_ch = 0xcb; 192 unsigned char buf[sizeof(double) + 1]; 193 194 /* Convert to big endian */ 195 u.d = val; 196 u.i = TO_BE64 (u.i); 197 198 buf[0] = dbl_ch; 199 memcpy (&buf[1], &u.d, sizeof (double)); 200 func->ucl_emitter_append_len (buf, sizeof (buf), func->ud); 201 } 202 203 void 204 ucl_emitter_print_bool_msgpack (struct ucl_emitter_context *ctx, bool val) 205 { 206 const struct ucl_emitter_functions *func = ctx->func; 207 const unsigned char true_ch = 0xc3, false_ch = 0xc2; 208 209 func->ucl_emitter_append_character (val ? true_ch : false_ch, 1, func->ud); 210 } 211 212 void 213 ucl_emitter_print_string_msgpack (struct ucl_emitter_context *ctx, 214 const char *s, size_t len) 215 { 216 const struct ucl_emitter_functions *func = ctx->func; 217 const unsigned char fix_mask = 0xA0, l8_ch = 0xd9, l16_ch = 0xda, l32_ch = 0xdb; 218 unsigned char buf[5]; 219 unsigned blen; 220 221 if (len <= 0x1F) { 222 blen = 1; 223 buf[0] = (len | fix_mask) & 0xff; 224 } 225 else if (len <= 0xff) { 226 blen = 2; 227 buf[0] = l8_ch; 228 buf[1] = len & 0xff; 229 } 230 else if (len <= 0xffff) { 231 uint16_t bl = TO_BE16 (len); 232 233 blen = 3; 234 buf[0] = l16_ch; 235 memcpy (&buf[1], &bl, sizeof (bl)); 236 } 237 else { 238 uint32_t bl = TO_BE32 (len); 239 240 blen = 5; 241 buf[0] = l32_ch; 242 memcpy (&buf[1], &bl, sizeof (bl)); 243 } 244 245 func->ucl_emitter_append_len (buf, blen, func->ud); 246 func->ucl_emitter_append_len (s, len, func->ud); 247 } 248 249 void 250 ucl_emitter_print_binary_string_msgpack (struct ucl_emitter_context *ctx, 251 const char *s, size_t len) 252 { 253 const struct ucl_emitter_functions *func = ctx->func; 254 const unsigned char l8_ch = 0xc4, l16_ch = 0xc5, l32_ch = 0xc6; 255 unsigned char buf[5]; 256 unsigned blen; 257 258 if (len <= 0xff) { 259 blen = 2; 260 buf[0] = l8_ch; 261 buf[1] = len & 0xff; 262 } 263 else if (len <= 0xffff) { 264 uint16_t bl = TO_BE16 (len); 265 266 blen = 3; 267 buf[0] = l16_ch; 268 memcpy (&buf[1], &bl, sizeof (bl)); 269 } 270 else { 271 uint32_t bl = TO_BE32 (len); 272 273 blen = 5; 274 buf[0] = l32_ch; 275 memcpy (&buf[1], &bl, sizeof (bl)); 276 } 277 278 func->ucl_emitter_append_len (buf, blen, func->ud); 279 func->ucl_emitter_append_len (s, len, func->ud); 280 } 281 282 void 283 ucl_emitter_print_null_msgpack (struct ucl_emitter_context *ctx) 284 { 285 const struct ucl_emitter_functions *func = ctx->func; 286 const unsigned char nil = 0xc0; 287 288 func->ucl_emitter_append_character (nil, 1, func->ud); 289 } 290 291 void 292 ucl_emitter_print_key_msgpack (bool print_key, struct ucl_emitter_context *ctx, 293 const ucl_object_t *obj) 294 { 295 if (print_key) { 296 ucl_emitter_print_string_msgpack (ctx, obj->key, obj->keylen); 297 } 298 } 299 300 void 301 ucl_emitter_print_array_msgpack (struct ucl_emitter_context *ctx, size_t len) 302 { 303 const struct ucl_emitter_functions *func = ctx->func; 304 const unsigned char fix_mask = 0x90, l16_ch = 0xdc, l32_ch = 0xdd; 305 unsigned char buf[5]; 306 unsigned blen; 307 308 if (len <= 0xF) { 309 blen = 1; 310 buf[0] = (len | fix_mask) & 0xff; 311 } 312 else if (len <= 0xffff) { 313 uint16_t bl = TO_BE16 (len); 314 315 blen = 3; 316 buf[0] = l16_ch; 317 memcpy (&buf[1], &bl, sizeof (bl)); 318 } 319 else { 320 uint32_t bl = TO_BE32 (len); 321 322 blen = 5; 323 buf[0] = l32_ch; 324 memcpy (&buf[1], &bl, sizeof (bl)); 325 } 326 327 func->ucl_emitter_append_len (buf, blen, func->ud); 328 } 329 330 void 331 ucl_emitter_print_object_msgpack (struct ucl_emitter_context *ctx, size_t len) 332 { 333 const struct ucl_emitter_functions *func = ctx->func; 334 const unsigned char fix_mask = 0x80, l16_ch = 0xde, l32_ch = 0xdf; 335 unsigned char buf[5]; 336 unsigned blen; 337 338 if (len <= 0xF) { 339 blen = 1; 340 buf[0] = (len | fix_mask) & 0xff; 341 } 342 else if (len <= 0xffff) { 343 uint16_t bl = TO_BE16 (len); 344 345 blen = 3; 346 buf[0] = l16_ch; 347 memcpy (&buf[1], &bl, sizeof (bl)); 348 } 349 else { 350 uint32_t bl = TO_BE32 (len); 351 352 blen = 5; 353 buf[0] = l32_ch; 354 memcpy (&buf[1], &bl, sizeof (bl)); 355 } 356 357 func->ucl_emitter_append_len (buf, blen, func->ud); 358 } 359 360 361 enum ucl_msgpack_format { 362 msgpack_positive_fixint = 0, 363 msgpack_fixmap, 364 msgpack_fixarray, 365 msgpack_fixstr, 366 msgpack_nil, 367 msgpack_false, 368 msgpack_true, 369 msgpack_bin8, 370 msgpack_bin16, 371 msgpack_bin32, 372 msgpack_ext8, 373 msgpack_ext16, 374 msgpack_ext32, 375 msgpack_float32, 376 msgpack_float64, 377 msgpack_uint8, 378 msgpack_uint16, 379 msgpack_uint32, 380 msgpack_uint64, 381 msgpack_int8, 382 msgpack_int16, 383 msgpack_int32, 384 msgpack_int64, 385 msgpack_fixext1, 386 msgpack_fixext2, 387 msgpack_fixext4, 388 msgpack_fixext8, 389 msgpack_fixext16, 390 msgpack_str8, 391 msgpack_str16, 392 msgpack_str32, 393 msgpack_array16, 394 msgpack_array32, 395 msgpack_map16, 396 msgpack_map32, 397 msgpack_negative_fixint, 398 msgpack_invalid 399 }; 400 401 typedef ssize_t (*ucl_msgpack_parse_function)(struct ucl_parser *parser, 402 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 403 const unsigned char *pos, size_t remain); 404 405 static ssize_t ucl_msgpack_parse_map (struct ucl_parser *parser, 406 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 407 const unsigned char *pos, size_t remain); 408 static ssize_t ucl_msgpack_parse_array (struct ucl_parser *parser, 409 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 410 const unsigned char *pos, size_t remain); 411 static ssize_t ucl_msgpack_parse_string (struct ucl_parser *parser, 412 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 413 const unsigned char *pos, size_t remain); 414 static ssize_t ucl_msgpack_parse_int (struct ucl_parser *parser, 415 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 416 const unsigned char *pos, size_t remain); 417 static ssize_t ucl_msgpack_parse_float (struct ucl_parser *parser, 418 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 419 const unsigned char *pos, size_t remain); 420 static ssize_t ucl_msgpack_parse_bool (struct ucl_parser *parser, 421 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 422 const unsigned char *pos, size_t remain); 423 static ssize_t ucl_msgpack_parse_null (struct ucl_parser *parser, 424 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 425 const unsigned char *pos, size_t remain); 426 static ssize_t ucl_msgpack_parse_ignore (struct ucl_parser *parser, 427 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 428 const unsigned char *pos, size_t remain); 429 430 #define MSGPACK_FLAG_FIXED (1 << 0) 431 #define MSGPACK_FLAG_CONTAINER (1 << 1) 432 #define MSGPACK_FLAG_TYPEVALUE (1 << 2) 433 #define MSGPACK_FLAG_EXT (1 << 3) 434 #define MSGPACK_FLAG_ASSOC (1 << 4) 435 #define MSGPACK_FLAG_KEY (1 << 5) 436 #define MSGPACK_CONTAINER_BIT (1ULL << 62) 437 438 /* 439 * Search tree packed in array 440 */ 441 struct ucl_msgpack_parser { 442 uint8_t prefix; /* Prefix byte */ 443 uint8_t prefixlen; /* Length of prefix in bits */ 444 uint8_t fmt; /* The desired format */ 445 uint8_t len; /* Length of the object 446 (either length bytes 447 or length of value in case 448 of fixed objects */ 449 uint8_t flags; /* Flags of the specified type */ 450 ucl_msgpack_parse_function func; /* Parser function */ 451 } parsers[] = { 452 { 453 0xa0, 454 3, 455 msgpack_fixstr, 456 0, 457 MSGPACK_FLAG_FIXED|MSGPACK_FLAG_KEY, 458 ucl_msgpack_parse_string 459 }, 460 { 461 0x0, 462 1, 463 msgpack_positive_fixint, 464 0, 465 MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE, 466 ucl_msgpack_parse_int 467 }, 468 { 469 0xe0, 470 3, 471 msgpack_negative_fixint, 472 0, 473 MSGPACK_FLAG_FIXED|MSGPACK_FLAG_TYPEVALUE, 474 ucl_msgpack_parse_int 475 }, 476 { 477 0x80, 478 4, 479 msgpack_fixmap, 480 0, 481 MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC, 482 ucl_msgpack_parse_map 483 }, 484 { 485 0x90, 486 4, 487 msgpack_fixarray, 488 0, 489 MSGPACK_FLAG_FIXED|MSGPACK_FLAG_CONTAINER, 490 ucl_msgpack_parse_array 491 }, 492 { 493 0xd9, 494 8, 495 msgpack_str8, 496 1, 497 MSGPACK_FLAG_KEY, 498 ucl_msgpack_parse_string 499 }, 500 { 501 0xc4, 502 8, 503 msgpack_bin8, 504 1, 505 MSGPACK_FLAG_KEY, 506 ucl_msgpack_parse_string 507 }, 508 { 509 0xcf, 510 8, 511 msgpack_uint64, 512 8, 513 MSGPACK_FLAG_FIXED, 514 ucl_msgpack_parse_int 515 }, 516 { 517 0xd3, 518 8, 519 msgpack_int64, 520 8, 521 MSGPACK_FLAG_FIXED, 522 ucl_msgpack_parse_int 523 }, 524 { 525 0xce, 526 8, 527 msgpack_uint32, 528 4, 529 MSGPACK_FLAG_FIXED, 530 ucl_msgpack_parse_int 531 }, 532 { 533 0xd2, 534 8, 535 msgpack_int32, 536 4, 537 MSGPACK_FLAG_FIXED, 538 ucl_msgpack_parse_int 539 }, 540 { 541 0xcb, 542 8, 543 msgpack_float64, 544 8, 545 MSGPACK_FLAG_FIXED, 546 ucl_msgpack_parse_float 547 }, 548 { 549 0xca, 550 8, 551 msgpack_float32, 552 4, 553 MSGPACK_FLAG_FIXED, 554 ucl_msgpack_parse_float 555 }, 556 { 557 0xc2, 558 8, 559 msgpack_false, 560 1, 561 MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, 562 ucl_msgpack_parse_bool 563 }, 564 { 565 0xc3, 566 8, 567 msgpack_true, 568 1, 569 MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, 570 ucl_msgpack_parse_bool 571 }, 572 { 573 0xcc, 574 8, 575 msgpack_uint8, 576 1, 577 MSGPACK_FLAG_FIXED, 578 ucl_msgpack_parse_int 579 }, 580 { 581 0xcd, 582 8, 583 msgpack_uint16, 584 2, 585 MSGPACK_FLAG_FIXED, 586 ucl_msgpack_parse_int 587 }, 588 { 589 0xd0, 590 8, 591 msgpack_int8, 592 1, 593 MSGPACK_FLAG_FIXED, 594 ucl_msgpack_parse_int 595 }, 596 { 597 0xd1, 598 8, 599 msgpack_int16, 600 2, 601 MSGPACK_FLAG_FIXED, 602 ucl_msgpack_parse_int 603 }, 604 { 605 0xc0, 606 8, 607 msgpack_nil, 608 0, 609 MSGPACK_FLAG_FIXED | MSGPACK_FLAG_TYPEVALUE, 610 ucl_msgpack_parse_null 611 }, 612 { 613 0xda, 614 8, 615 msgpack_str16, 616 2, 617 MSGPACK_FLAG_KEY, 618 ucl_msgpack_parse_string 619 }, 620 { 621 0xdb, 622 8, 623 msgpack_str32, 624 4, 625 MSGPACK_FLAG_KEY, 626 ucl_msgpack_parse_string 627 }, 628 { 629 0xc5, 630 8, 631 msgpack_bin16, 632 2, 633 MSGPACK_FLAG_KEY, 634 ucl_msgpack_parse_string 635 }, 636 { 637 0xc6, 638 8, 639 msgpack_bin32, 640 4, 641 MSGPACK_FLAG_KEY, 642 ucl_msgpack_parse_string 643 }, 644 { 645 0xdc, 646 8, 647 msgpack_array16, 648 2, 649 MSGPACK_FLAG_CONTAINER, 650 ucl_msgpack_parse_array 651 }, 652 { 653 0xdd, 654 8, 655 msgpack_array32, 656 4, 657 MSGPACK_FLAG_CONTAINER, 658 ucl_msgpack_parse_array 659 }, 660 { 661 0xde, 662 8, 663 msgpack_map16, 664 2, 665 MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC, 666 ucl_msgpack_parse_map 667 }, 668 { 669 0xdf, 670 8, 671 msgpack_map32, 672 4, 673 MSGPACK_FLAG_CONTAINER|MSGPACK_FLAG_ASSOC, 674 ucl_msgpack_parse_map 675 }, 676 { 677 0xc7, 678 8, 679 msgpack_ext8, 680 1, 681 MSGPACK_FLAG_EXT, 682 ucl_msgpack_parse_ignore 683 }, 684 { 685 0xc8, 686 8, 687 msgpack_ext16, 688 2, 689 MSGPACK_FLAG_EXT, 690 ucl_msgpack_parse_ignore 691 }, 692 { 693 0xc9, 694 8, 695 msgpack_ext32, 696 4, 697 MSGPACK_FLAG_EXT, 698 ucl_msgpack_parse_ignore 699 }, 700 { 701 0xd4, 702 8, 703 msgpack_fixext1, 704 1, 705 MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, 706 ucl_msgpack_parse_ignore 707 }, 708 { 709 0xd5, 710 8, 711 msgpack_fixext2, 712 2, 713 MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, 714 ucl_msgpack_parse_ignore 715 }, 716 { 717 0xd6, 718 8, 719 msgpack_fixext4, 720 4, 721 MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, 722 ucl_msgpack_parse_ignore 723 }, 724 { 725 0xd7, 726 8, 727 msgpack_fixext8, 728 8, 729 MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, 730 ucl_msgpack_parse_ignore 731 }, 732 { 733 0xd8, 734 8, 735 msgpack_fixext16, 736 16, 737 MSGPACK_FLAG_FIXED | MSGPACK_FLAG_EXT, 738 ucl_msgpack_parse_ignore 739 } 740 }; 741 742 #undef MSGPACK_DEBUG_PARSER 743 744 static inline struct ucl_msgpack_parser * 745 ucl_msgpack_get_parser_from_type (unsigned char t) 746 { 747 unsigned int i, shift, mask; 748 749 for (i = 0; i < sizeof (parsers) / sizeof (parsers[0]); i ++) { 750 shift = CHAR_BIT - parsers[i].prefixlen; 751 mask = parsers[i].prefix >> shift; 752 753 if (mask == (t >> shift)) { 754 return &parsers[i]; 755 } 756 } 757 758 return NULL; 759 } 760 761 static inline struct ucl_stack * 762 ucl_msgpack_get_container (struct ucl_parser *parser, 763 struct ucl_msgpack_parser *obj_parser, uint64_t len) 764 { 765 struct ucl_stack *stack; 766 767 assert (obj_parser != NULL); 768 769 if (obj_parser->flags & MSGPACK_FLAG_CONTAINER) { 770 assert ((len & MSGPACK_CONTAINER_BIT) == 0); 771 /* 772 * Insert new container to the stack 773 */ 774 if (parser->stack == NULL) { 775 parser->stack = calloc (1, sizeof (struct ucl_stack)); 776 777 if (parser->stack == NULL) { 778 ucl_create_err (&parser->err, "no memory"); 779 return NULL; 780 } 781 } 782 else { 783 stack = calloc (1, sizeof (struct ucl_stack)); 784 785 if (stack == NULL) { 786 ucl_create_err (&parser->err, "no memory"); 787 return NULL; 788 } 789 790 stack->next = parser->stack; 791 parser->stack = stack; 792 } 793 794 parser->stack->level = len | MSGPACK_CONTAINER_BIT; 795 796 #ifdef MSGPACK_DEBUG_PARSER 797 stack = parser->stack; 798 while (stack) { 799 fprintf(stderr, "+"); 800 stack = stack->next; 801 } 802 803 fprintf(stderr, "%s -> %d\n", obj_parser->flags & MSGPACK_FLAG_ASSOC ? "object" : "array", (int)len); 804 #endif 805 } 806 else { 807 /* 808 * Get the current stack top 809 */ 810 if (parser->stack) { 811 return parser->stack; 812 } 813 else { 814 ucl_create_err (&parser->err, "bad top level object for msgpack"); 815 return NULL; 816 } 817 } 818 819 return parser->stack; 820 } 821 822 static bool 823 ucl_msgpack_is_container_finished (struct ucl_stack *container) 824 { 825 uint64_t level; 826 827 assert (container != NULL); 828 829 if (container->level & MSGPACK_CONTAINER_BIT) { 830 level = container->level & ~MSGPACK_CONTAINER_BIT; 831 832 if (level == 0) { 833 return true; 834 } 835 } 836 837 return false; 838 } 839 840 static bool 841 ucl_msgpack_insert_object (struct ucl_parser *parser, 842 const unsigned char *key, 843 size_t keylen, ucl_object_t *obj) 844 { 845 uint64_t level; 846 struct ucl_stack *container; 847 848 container = parser->stack; 849 assert (container != NULL); 850 assert (container->level > 0); 851 assert (obj != NULL); 852 assert (container->obj != NULL); 853 854 if (container->obj->type == UCL_ARRAY) { 855 ucl_array_append (container->obj, obj); 856 } 857 else if (container->obj->type == UCL_OBJECT) { 858 if (key == NULL || keylen == 0) { 859 ucl_create_err (&parser->err, "cannot insert object with no key"); 860 return false; 861 } 862 863 obj->key = key; 864 obj->keylen = keylen; 865 866 if (!(parser->flags & UCL_PARSER_ZEROCOPY)) { 867 ucl_copy_key_trash (obj); 868 } 869 870 ucl_parser_process_object_element (parser, obj); 871 } 872 else { 873 ucl_create_err (&parser->err, "bad container type"); 874 return false; 875 } 876 877 if (container->level & MSGPACK_CONTAINER_BIT) { 878 level = container->level & ~MSGPACK_CONTAINER_BIT; 879 container->level = (level - 1) | MSGPACK_CONTAINER_BIT; 880 } 881 882 return true; 883 } 884 885 static struct ucl_stack * 886 ucl_msgpack_get_next_container (struct ucl_parser *parser) 887 { 888 struct ucl_stack *cur = NULL; 889 uint64_t level; 890 891 cur = parser->stack; 892 893 if (cur == NULL) { 894 return NULL; 895 } 896 897 if (cur->level & MSGPACK_CONTAINER_BIT) { 898 level = cur->level & ~MSGPACK_CONTAINER_BIT; 899 900 if (level == 0) { 901 /* We need to switch to the previous container */ 902 parser->stack = cur->next; 903 parser->cur_obj = cur->obj; 904 free (cur); 905 906 #ifdef MSGPACK_DEBUG_PARSER 907 cur = parser->stack; 908 while (cur) { 909 fprintf(stderr, "-"); 910 cur = cur->next; 911 } 912 fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len); 913 #endif 914 915 return ucl_msgpack_get_next_container (parser); 916 } 917 } 918 919 /* 920 * For UCL containers we don't know length, so we just insert the whole 921 * message pack blob into the top level container 922 */ 923 924 assert (cur->obj != NULL); 925 926 return cur; 927 } 928 929 #define CONSUME_RET do { \ 930 if (ret != -1) { \ 931 p += ret; \ 932 remain -= ret; \ 933 obj_parser = NULL; \ 934 assert (remain >= 0); \ 935 } \ 936 else { \ 937 ucl_create_err (&parser->err, \ 938 "cannot parse type %d of len %u", \ 939 (int)obj_parser->fmt, \ 940 (unsigned)len); \ 941 return false; \ 942 } \ 943 } while(0) 944 945 #define GET_NEXT_STATE do { \ 946 container = ucl_msgpack_get_next_container (parser); \ 947 if (container == NULL) { \ 948 ucl_create_err (&parser->err, \ 949 "empty container"); \ 950 return false; \ 951 } \ 952 next_state = container->obj->type == UCL_OBJECT ? \ 953 read_assoc_key : read_array_value; \ 954 } while(0) 955 956 static bool 957 ucl_msgpack_consume (struct ucl_parser *parser) 958 { 959 const unsigned char *p, *end, *key = NULL; 960 struct ucl_stack *container; 961 enum e_msgpack_parser_state { 962 read_type, 963 start_assoc, 964 start_array, 965 read_assoc_key, 966 read_assoc_value, 967 finish_assoc_value, 968 read_array_value, 969 finish_array_value, 970 error_state 971 } state = read_type, next_state = error_state; 972 struct ucl_msgpack_parser *obj_parser; 973 uint64_t len; 974 ssize_t ret, remain, keylen = 0; 975 #ifdef MSGPACK_DEBUG_PARSER 976 uint64_t i; 977 enum e_msgpack_parser_state hist[256]; 978 #endif 979 980 p = parser->chunks->begin; 981 remain = parser->chunks->remain; 982 end = p + remain; 983 984 985 while (p < end) { 986 #ifdef MSGPACK_DEBUG_PARSER 987 hist[i++ % 256] = state; 988 #endif 989 switch (state) { 990 case read_type: 991 obj_parser = ucl_msgpack_get_parser_from_type (*p); 992 993 if (obj_parser == NULL) { 994 ucl_create_err (&parser->err, "unknown msgpack format: %x", 995 (unsigned int)*p); 996 997 return false; 998 } 999 /* Now check length sanity */ 1000 if (obj_parser->flags & MSGPACK_FLAG_FIXED) { 1001 if (obj_parser->len == 0) { 1002 /* We have an embedded size */ 1003 len = *p & ~obj_parser->prefix; 1004 } 1005 else { 1006 if (remain < obj_parser->len) { 1007 ucl_create_err (&parser->err, "not enough data remain to " 1008 "read object's length: %u remain, %u needed", 1009 (unsigned)remain, obj_parser->len); 1010 1011 return false; 1012 } 1013 1014 len = obj_parser->len; 1015 } 1016 1017 if (!(obj_parser->flags & MSGPACK_FLAG_TYPEVALUE)) { 1018 /* We must pass value as the second byte */ 1019 if (remain > 0) { 1020 p ++; 1021 remain --; 1022 } 1023 } 1024 else { 1025 /* Len is irrelevant now */ 1026 len = 0; 1027 } 1028 } 1029 else { 1030 /* Length is not embedded */ 1031 if (remain < obj_parser->len) { 1032 ucl_create_err (&parser->err, "not enough data remain to " 1033 "read object's length: %u remain, %u needed", 1034 (unsigned)remain, obj_parser->len); 1035 1036 return false; 1037 } 1038 1039 p ++; 1040 remain --; 1041 1042 switch (obj_parser->len) { 1043 case 1: 1044 len = *p; 1045 break; 1046 case 2: 1047 len = FROM_BE16 (*(uint16_t *)p); 1048 break; 1049 case 4: 1050 len = FROM_BE32 (*(uint32_t *)p); 1051 break; 1052 case 8: 1053 len = FROM_BE64 (*(uint64_t *)p); 1054 break; 1055 default: 1056 assert (0); 1057 break; 1058 } 1059 1060 p += obj_parser->len; 1061 remain -= obj_parser->len; 1062 } 1063 1064 if (obj_parser->flags & MSGPACK_FLAG_ASSOC) { 1065 /* We have just read the new associative map */ 1066 state = start_assoc; 1067 } 1068 else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER){ 1069 state = start_array; 1070 } 1071 else { 1072 state = next_state; 1073 } 1074 1075 break; 1076 case start_assoc: 1077 parser->cur_obj = ucl_object_new_full (UCL_OBJECT, 1078 parser->chunks->priority); 1079 /* Insert to the previous level container */ 1080 if (parser->stack && !ucl_msgpack_insert_object (parser, 1081 key, keylen, parser->cur_obj)) { 1082 return false; 1083 } 1084 /* Get new container */ 1085 container = ucl_msgpack_get_container (parser, obj_parser, len); 1086 1087 if (container == NULL) { 1088 return false; 1089 } 1090 1091 ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1092 p, remain); 1093 CONSUME_RET; 1094 key = NULL; 1095 keylen = 0; 1096 1097 if (len > 0) { 1098 state = read_type; 1099 next_state = read_assoc_key; 1100 } 1101 else { 1102 /* Empty object */ 1103 state = finish_assoc_value; 1104 } 1105 break; 1106 1107 case start_array: 1108 parser->cur_obj = ucl_object_new_full (UCL_ARRAY, 1109 parser->chunks->priority); 1110 /* Insert to the previous level container */ 1111 if (parser->stack && !ucl_msgpack_insert_object (parser, 1112 key, keylen, parser->cur_obj)) { 1113 return false; 1114 } 1115 /* Get new container */ 1116 container = ucl_msgpack_get_container (parser, obj_parser, len); 1117 1118 if (container == NULL) { 1119 return false; 1120 } 1121 1122 ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1123 p, remain); 1124 CONSUME_RET; 1125 1126 if (len > 0) { 1127 state = read_type; 1128 next_state = read_array_value; 1129 } 1130 else { 1131 /* Empty array */ 1132 state = finish_array_value; 1133 } 1134 break; 1135 1136 case read_array_value: 1137 /* 1138 * p is now at the value start, len now contains length read and 1139 * obj_parser contains the corresponding specific parser 1140 */ 1141 container = parser->stack; 1142 1143 if (container == NULL) { 1144 return false; 1145 } 1146 1147 ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1148 p, remain); 1149 CONSUME_RET; 1150 1151 1152 /* Insert value to the container and check if we have finished array */ 1153 if (!ucl_msgpack_insert_object (parser, NULL, 0, 1154 parser->cur_obj)) { 1155 return false; 1156 } 1157 1158 if (ucl_msgpack_is_container_finished (container)) { 1159 state = finish_array_value; 1160 } 1161 else { 1162 /* Read more elements */ 1163 state = read_type; 1164 next_state = read_array_value; 1165 } 1166 1167 break; 1168 1169 case read_assoc_key: 1170 /* 1171 * Keys must have string type for ucl msgpack 1172 */ 1173 if (!(obj_parser->flags & MSGPACK_FLAG_KEY)) { 1174 ucl_create_err (&parser->err, "bad type for key: %u, expected " 1175 "string", (unsigned)obj_parser->fmt); 1176 1177 return false; 1178 } 1179 1180 key = p; 1181 keylen = len; 1182 1183 if (keylen > remain || keylen == 0) { 1184 ucl_create_err (&parser->err, "too long or empty key"); 1185 return false; 1186 } 1187 1188 p += len; 1189 remain -= len; 1190 1191 state = read_type; 1192 next_state = read_assoc_value; 1193 break; 1194 1195 case read_assoc_value: 1196 /* 1197 * p is now at the value start, len now contains length read and 1198 * obj_parser contains the corresponding specific parser 1199 */ 1200 container = parser->stack; 1201 1202 if (container == NULL) { 1203 return false; 1204 } 1205 1206 ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1207 p, remain); 1208 CONSUME_RET; 1209 1210 assert (key != NULL && keylen > 0); 1211 1212 if (!ucl_msgpack_insert_object (parser, key, keylen, 1213 parser->cur_obj)) { 1214 return false; 1215 } 1216 1217 key = NULL; 1218 keylen = 0; 1219 1220 if (ucl_msgpack_is_container_finished (container)) { 1221 state = finish_assoc_value; 1222 } 1223 else { 1224 /* Read more elements */ 1225 state = read_type; 1226 next_state = read_assoc_key; 1227 } 1228 break; 1229 1230 case finish_array_value: 1231 case finish_assoc_value: 1232 GET_NEXT_STATE; 1233 state = read_type; 1234 break; 1235 1236 case error_state: 1237 ucl_create_err (&parser->err, "invalid state machine state"); 1238 1239 return false; 1240 } 1241 } 1242 1243 /* Check the finishing state */ 1244 switch (state) { 1245 case start_array: 1246 case start_assoc: 1247 /* Empty container at the end */ 1248 if (len != 0) { 1249 ucl_create_err (&parser->err, "invalid non-empty container at the end"); 1250 1251 return false; 1252 } 1253 1254 parser->cur_obj = ucl_object_new_full ( 1255 state == start_array ? UCL_ARRAY : UCL_OBJECT, 1256 parser->chunks->priority); 1257 /* Insert to the previous level container */ 1258 if (!ucl_msgpack_insert_object (parser, 1259 key, keylen, parser->cur_obj)) { 1260 return false; 1261 } 1262 /* Get new container */ 1263 container = ucl_msgpack_get_container (parser, obj_parser, len); 1264 1265 if (container == NULL) { 1266 return false; 1267 } 1268 1269 ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1270 p, remain); 1271 break; 1272 1273 case read_array_value: 1274 case read_assoc_value: 1275 if (len != 0) { 1276 ucl_create_err (&parser->err, "unfinished value at the end"); 1277 1278 return false; 1279 } 1280 1281 container = parser->stack; 1282 1283 if (container == NULL) { 1284 return false; 1285 } 1286 1287 ret = obj_parser->func (parser, container, len, obj_parser->fmt, 1288 p, remain); 1289 CONSUME_RET; 1290 1291 1292 /* Insert value to the container and check if we have finished array */ 1293 if (!ucl_msgpack_insert_object (parser, NULL, 0, 1294 parser->cur_obj)) { 1295 return false; 1296 } 1297 break; 1298 case finish_array_value: 1299 case finish_assoc_value: 1300 case read_type: 1301 /* Valid finishing state */ 1302 break; 1303 default: 1304 /* Invalid finishing state */ 1305 ucl_create_err (&parser->err, "invalid state machine finishing state: %d", 1306 state); 1307 1308 return false; 1309 } 1310 1311 /* Rewind to the top level container */ 1312 ucl_msgpack_get_next_container (parser); 1313 assert (parser->stack == NULL || 1314 (parser->stack->level & MSGPACK_CONTAINER_BIT) == 0); 1315 1316 return true; 1317 } 1318 1319 bool 1320 ucl_parse_msgpack (struct ucl_parser *parser) 1321 { 1322 ucl_object_t *container = NULL; 1323 const unsigned char *p; 1324 bool ret; 1325 1326 assert (parser != NULL); 1327 assert (parser->chunks != NULL); 1328 assert (parser->chunks->begin != NULL); 1329 assert (parser->chunks->remain != 0); 1330 1331 p = parser->chunks->begin; 1332 1333 if (parser->stack) { 1334 container = parser->stack->obj; 1335 } 1336 1337 /* 1338 * When we start parsing message pack chunk, we must ensure that we 1339 * have either a valid container or the top object inside message pack is 1340 * of container type 1341 */ 1342 if (container == NULL) { 1343 if ((*p & 0x80) != 0x80 && !(*p >= 0xdc && *p <= 0xdf)) { 1344 ucl_create_err (&parser->err, "bad top level object for msgpack"); 1345 return false; 1346 } 1347 } 1348 1349 ret = ucl_msgpack_consume (parser); 1350 1351 if (ret && parser->top_obj == NULL) { 1352 parser->top_obj = parser->cur_obj; 1353 } 1354 1355 return ret; 1356 } 1357 1358 static ssize_t 1359 ucl_msgpack_parse_map (struct ucl_parser *parser, 1360 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1361 const unsigned char *pos, size_t remain) 1362 { 1363 container->obj = parser->cur_obj; 1364 1365 return 0; 1366 } 1367 1368 static ssize_t 1369 ucl_msgpack_parse_array (struct ucl_parser *parser, 1370 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1371 const unsigned char *pos, size_t remain) 1372 { 1373 container->obj = parser->cur_obj; 1374 1375 return 0; 1376 } 1377 1378 static ssize_t 1379 ucl_msgpack_parse_string (struct ucl_parser *parser, 1380 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1381 const unsigned char *pos, size_t remain) 1382 { 1383 ucl_object_t *obj; 1384 1385 if (len > remain) { 1386 return -1; 1387 } 1388 1389 obj = ucl_object_new_full (UCL_STRING, parser->chunks->priority); 1390 obj->value.sv = pos; 1391 obj->len = len; 1392 1393 if (fmt >= msgpack_bin8 && fmt <= msgpack_bin32) { 1394 obj->flags |= UCL_OBJECT_BINARY; 1395 } 1396 1397 if (!(parser->flags & UCL_PARSER_ZEROCOPY)) { 1398 if (obj->flags & UCL_OBJECT_BINARY) { 1399 obj->trash_stack[UCL_TRASH_VALUE] = malloc (len); 1400 1401 if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) { 1402 memcpy (obj->trash_stack[UCL_TRASH_VALUE], pos, len); 1403 } 1404 } 1405 else { 1406 ucl_copy_value_trash (obj); 1407 } 1408 } 1409 1410 parser->cur_obj = obj; 1411 1412 return len; 1413 } 1414 1415 static ssize_t 1416 ucl_msgpack_parse_int (struct ucl_parser *parser, 1417 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1418 const unsigned char *pos, size_t remain) 1419 { 1420 ucl_object_t *obj; 1421 1422 if (len > remain) { 1423 return -1; 1424 } 1425 1426 obj = ucl_object_new_full (UCL_INT, parser->chunks->priority); 1427 1428 switch (fmt) { 1429 case msgpack_positive_fixint: 1430 obj->value.iv = (*pos & 0x7f); 1431 len = 1; 1432 break; 1433 case msgpack_negative_fixint: 1434 obj->value.iv = - (*pos & 0x1f); 1435 len = 1; 1436 break; 1437 case msgpack_uint8: 1438 obj->value.iv = (unsigned char)*pos; 1439 len = 1; 1440 break; 1441 case msgpack_int8: 1442 obj->value.iv = (signed char)*pos; 1443 len = 1; 1444 break; 1445 case msgpack_int16: 1446 obj->value.iv = FROM_BE16 (*(int16_t *)pos); 1447 len = 2; 1448 break; 1449 case msgpack_uint16: 1450 obj->value.iv = FROM_BE16 (*(uint16_t *)pos); 1451 len = 2; 1452 break; 1453 case msgpack_int32: 1454 obj->value.iv = FROM_BE32 (*(int32_t *)pos); 1455 len = 4; 1456 break; 1457 case msgpack_uint32: 1458 obj->value.iv = FROM_BE32 (*(uint32_t *)pos); 1459 len = 4; 1460 break; 1461 case msgpack_int64: 1462 obj->value.iv = FROM_BE64 (*(int64_t *)pos); 1463 len = 8; 1464 break; 1465 case msgpack_uint64: 1466 obj->value.iv = FROM_BE64 (*(uint64_t *)pos); 1467 len = 8; 1468 break; 1469 default: 1470 assert (0); 1471 break; 1472 } 1473 1474 parser->cur_obj = obj; 1475 1476 return len; 1477 } 1478 1479 static ssize_t 1480 ucl_msgpack_parse_float (struct ucl_parser *parser, 1481 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1482 const unsigned char *pos, size_t remain) 1483 { 1484 ucl_object_t *obj; 1485 union { 1486 uint32_t i; 1487 float f; 1488 } d; 1489 1490 if (len > remain) { 1491 return -1; 1492 } 1493 1494 obj = ucl_object_new_full (UCL_FLOAT, parser->chunks->priority); 1495 1496 switch (fmt) { 1497 case msgpack_float32: 1498 d.i = FROM_BE32 (*(uint32_t *)pos); 1499 /* XXX: can be slow */ 1500 obj->value.dv = d.f; 1501 len = 4; 1502 break; 1503 case msgpack_float64: 1504 obj->value.iv = FROM_BE64 (*(uint64_t *)pos); 1505 len = 8; 1506 break; 1507 default: 1508 assert (0); 1509 break; 1510 } 1511 1512 parser->cur_obj = obj; 1513 1514 return len; 1515 } 1516 1517 static ssize_t 1518 ucl_msgpack_parse_bool (struct ucl_parser *parser, 1519 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1520 const unsigned char *pos, size_t remain) 1521 { 1522 ucl_object_t *obj; 1523 1524 if (len > remain) { 1525 return -1; 1526 } 1527 1528 obj = ucl_object_new_full (UCL_BOOLEAN, parser->chunks->priority); 1529 1530 switch (fmt) { 1531 case msgpack_true: 1532 obj->value.iv = true; 1533 break; 1534 case msgpack_false: 1535 obj->value.iv = false; 1536 break; 1537 default: 1538 assert (0); 1539 break; 1540 } 1541 1542 parser->cur_obj = obj; 1543 1544 return 1; 1545 } 1546 1547 static ssize_t 1548 ucl_msgpack_parse_null (struct ucl_parser *parser, 1549 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1550 const unsigned char *pos, size_t remain) 1551 { 1552 ucl_object_t *obj; 1553 1554 if (len > remain) { 1555 return -1; 1556 } 1557 1558 obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority); 1559 parser->cur_obj = obj; 1560 1561 return 1; 1562 } 1563 1564 static ssize_t 1565 ucl_msgpack_parse_ignore (struct ucl_parser *parser, 1566 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt, 1567 const unsigned char *pos, size_t remain) 1568 { 1569 if (len > remain) { 1570 return -1; 1571 } 1572 1573 switch (fmt) { 1574 case msgpack_fixext1: 1575 len = 2; 1576 break; 1577 case msgpack_fixext2: 1578 len = 3; 1579 break; 1580 case msgpack_fixext4: 1581 len = 5; 1582 break; 1583 case msgpack_fixext8: 1584 len = 9; 1585 break; 1586 case msgpack_fixext16: 1587 len = 17; 1588 break; 1589 case msgpack_ext8: 1590 case msgpack_ext16: 1591 case msgpack_ext32: 1592 len = len + 1; 1593 break; 1594 default: 1595 ucl_create_err (&parser->err, "bad type: %x", (unsigned)fmt); 1596 return -1; 1597 } 1598 1599 return len; 1600 } 1601