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