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
ucl_emitter_print_int_msgpack(struct ucl_emitter_context * ctx,int64_t val)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 <= UINT8_MAX) {
117 len = 2;
118 buf[0] = uint8_ch;
119 buf[1] = val & 0xff;
120 }
121 else if (val <= UINT16_MAX) {
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 <= UINT32_MAX) {
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 <= INT8_MAX) {
153 uint8_t v = (uint8_t)val;
154 len = 2;
155 buf[0] = int8_ch;
156 buf[1] = v;
157 }
158 else if (uval <= INT16_MAX) {
159 uint16_t v = TO_BE16 (val);
160
161 len = 3;
162 buf[0] = int16_ch;
163 memcpy (&buf[1], &v, sizeof (v));
164 }
165 else if (uval <= INT32_MAX) {
166 uint32_t v = TO_BE32 (val);
167
168 len = 5;
169 buf[0] = int32_ch;
170 memcpy (&buf[1], &v, sizeof (v));
171 }
172 else {
173 uint64_t v = TO_BE64 (val);
174
175 len = 9;
176 buf[0] = int64_ch;
177 memcpy (&buf[1], &v, sizeof (v));
178 }
179 }
180
181 func->ucl_emitter_append_len (buf, len, func->ud);
182 }
183
184 void
ucl_emitter_print_double_msgpack(struct ucl_emitter_context * ctx,double val)185 ucl_emitter_print_double_msgpack (struct ucl_emitter_context *ctx, double val)
186 {
187 const struct ucl_emitter_functions *func = ctx->func;
188 union {
189 double d;
190 uint64_t i;
191 } u;
192 const unsigned char dbl_ch = 0xcb;
193 unsigned char buf[sizeof(double) + 1];
194
195 /* Convert to big endian */
196 u.d = val;
197 u.i = TO_BE64 (u.i);
198
199 buf[0] = dbl_ch;
200 memcpy (&buf[1], &u.d, sizeof (double));
201 func->ucl_emitter_append_len (buf, sizeof (buf), func->ud);
202 }
203
204 void
ucl_emitter_print_bool_msgpack(struct ucl_emitter_context * ctx,bool val)205 ucl_emitter_print_bool_msgpack (struct ucl_emitter_context *ctx, bool val)
206 {
207 const struct ucl_emitter_functions *func = ctx->func;
208 const unsigned char true_ch = 0xc3, false_ch = 0xc2;
209
210 func->ucl_emitter_append_character (val ? true_ch : false_ch, 1, func->ud);
211 }
212
213 void
ucl_emitter_print_string_msgpack(struct ucl_emitter_context * ctx,const char * s,size_t len)214 ucl_emitter_print_string_msgpack (struct ucl_emitter_context *ctx,
215 const char *s, size_t len)
216 {
217 const struct ucl_emitter_functions *func = ctx->func;
218 const unsigned char fix_mask = 0xA0, l8_ch = 0xd9, l16_ch = 0xda, l32_ch = 0xdb;
219 unsigned char buf[5];
220 unsigned blen;
221
222 if (len <= 0x1F) {
223 blen = 1;
224 buf[0] = (len | fix_mask) & 0xff;
225 }
226 else if (len <= 0xff) {
227 blen = 2;
228 buf[0] = l8_ch;
229 buf[1] = len & 0xff;
230 }
231 else if (len <= 0xffff) {
232 uint16_t bl = TO_BE16 (len);
233
234 blen = 3;
235 buf[0] = l16_ch;
236 memcpy (&buf[1], &bl, sizeof (bl));
237 }
238 else {
239 uint32_t bl = TO_BE32 (len);
240
241 blen = 5;
242 buf[0] = l32_ch;
243 memcpy (&buf[1], &bl, sizeof (bl));
244 }
245
246 func->ucl_emitter_append_len (buf, blen, func->ud);
247 func->ucl_emitter_append_len (s, len, func->ud);
248 }
249
250 void
ucl_emitter_print_binary_string_msgpack(struct ucl_emitter_context * ctx,const char * s,size_t len)251 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 ucl_emitter_print_null_msgpack (struct ucl_emitter_context *ctx)
285 {
286 const struct ucl_emitter_functions *func = ctx->func;
287 const unsigned char nil = 0xc0;
288
289 func->ucl_emitter_append_character (nil, 1, func->ud);
290 }
291
292 void
ucl_emitter_print_key_msgpack(bool print_key,struct ucl_emitter_context * ctx,const ucl_object_t * obj)293 ucl_emitter_print_key_msgpack (bool print_key, struct ucl_emitter_context *ctx,
294 const ucl_object_t *obj)
295 {
296 if (print_key) {
297 ucl_emitter_print_string_msgpack (ctx, obj->key, obj->keylen);
298 }
299 }
300
301 void
ucl_emitter_print_array_msgpack(struct ucl_emitter_context * ctx,size_t len)302 ucl_emitter_print_array_msgpack (struct ucl_emitter_context *ctx, size_t len)
303 {
304 const struct ucl_emitter_functions *func = ctx->func;
305 const unsigned char fix_mask = 0x90, l16_ch = 0xdc, l32_ch = 0xdd;
306 unsigned char buf[5];
307 unsigned blen;
308
309 if (len <= 0xF) {
310 blen = 1;
311 buf[0] = (len | fix_mask) & 0xff;
312 }
313 else if (len <= 0xffff) {
314 uint16_t bl = TO_BE16 (len);
315
316 blen = 3;
317 buf[0] = l16_ch;
318 memcpy (&buf[1], &bl, sizeof (bl));
319 }
320 else {
321 uint32_t bl = TO_BE32 (len);
322
323 blen = 5;
324 buf[0] = l32_ch;
325 memcpy (&buf[1], &bl, sizeof (bl));
326 }
327
328 func->ucl_emitter_append_len (buf, blen, func->ud);
329 }
330
331 void
ucl_emitter_print_object_msgpack(struct ucl_emitter_context * ctx,size_t len)332 ucl_emitter_print_object_msgpack (struct ucl_emitter_context *ctx, size_t len)
333 {
334 const struct ucl_emitter_functions *func = ctx->func;
335 const unsigned char fix_mask = 0x80, l16_ch = 0xde, l32_ch = 0xdf;
336 unsigned char buf[5];
337 unsigned blen;
338
339 if (len <= 0xF) {
340 blen = 1;
341 buf[0] = (len | fix_mask) & 0xff;
342 }
343 else if (len <= 0xffff) {
344 uint16_t bl = TO_BE16 (len);
345
346 blen = 3;
347 buf[0] = l16_ch;
348 memcpy (&buf[1], &bl, sizeof (bl));
349 }
350 else {
351 uint32_t bl = TO_BE32 (len);
352
353 blen = 5;
354 buf[0] = l32_ch;
355 memcpy (&buf[1], &bl, sizeof (bl));
356 }
357
358 func->ucl_emitter_append_len (buf, blen, func->ud);
359 }
360
361
362 enum ucl_msgpack_format {
363 msgpack_positive_fixint = 0,
364 msgpack_fixmap,
365 msgpack_fixarray,
366 msgpack_fixstr,
367 msgpack_nil,
368 msgpack_false,
369 msgpack_true,
370 msgpack_bin8,
371 msgpack_bin16,
372 msgpack_bin32,
373 msgpack_ext8,
374 msgpack_ext16,
375 msgpack_ext32,
376 msgpack_float32,
377 msgpack_float64,
378 msgpack_uint8,
379 msgpack_uint16,
380 msgpack_uint32,
381 msgpack_uint64,
382 msgpack_int8,
383 msgpack_int16,
384 msgpack_int32,
385 msgpack_int64,
386 msgpack_fixext1,
387 msgpack_fixext2,
388 msgpack_fixext4,
389 msgpack_fixext8,
390 msgpack_fixext16,
391 msgpack_str8,
392 msgpack_str16,
393 msgpack_str32,
394 msgpack_array16,
395 msgpack_array32,
396 msgpack_map16,
397 msgpack_map32,
398 msgpack_negative_fixint,
399 msgpack_invalid
400 };
401
402 typedef ssize_t (*ucl_msgpack_parse_function)(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
406 static ssize_t ucl_msgpack_parse_map (struct ucl_parser *parser,
407 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
408 const unsigned char *pos, size_t remain);
409 static ssize_t ucl_msgpack_parse_array (struct ucl_parser *parser,
410 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
411 const unsigned char *pos, size_t remain);
412 static ssize_t ucl_msgpack_parse_string (struct ucl_parser *parser,
413 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
414 const unsigned char *pos, size_t remain);
415 static ssize_t ucl_msgpack_parse_int (struct ucl_parser *parser,
416 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
417 const unsigned char *pos, size_t remain);
418 static ssize_t ucl_msgpack_parse_float (struct ucl_parser *parser,
419 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
420 const unsigned char *pos, size_t remain);
421 static ssize_t ucl_msgpack_parse_bool (struct ucl_parser *parser,
422 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
423 const unsigned char *pos, size_t remain);
424 static ssize_t ucl_msgpack_parse_null (struct ucl_parser *parser,
425 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
426 const unsigned char *pos, size_t remain);
427 static ssize_t ucl_msgpack_parse_ignore (struct ucl_parser *parser,
428 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
429 const unsigned char *pos, size_t remain);
430
431 #define MSGPACK_FLAG_FIXED (1 << 0)
432 #define MSGPACK_FLAG_CONTAINER (1 << 1)
433 #define MSGPACK_FLAG_TYPEVALUE (1 << 2)
434 #define MSGPACK_FLAG_EXT (1 << 3)
435 #define MSGPACK_FLAG_ASSOC (1 << 4)
436 #define MSGPACK_FLAG_KEY (1 << 5)
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 *
ucl_msgpack_get_parser_from_type(unsigned char t)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 == (((unsigned int)t) >> shift)) {
754 return &parsers[i];
755 }
756 }
757
758 return NULL;
759 }
760
761 static inline struct ucl_stack *
ucl_msgpack_get_container(struct ucl_parser * parser,struct ucl_msgpack_parser * obj_parser,uint64_t len)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 /*
771 * Insert new container to the stack
772 */
773 if (parser->stack == NULL) {
774 parser->stack = calloc (1, sizeof (struct ucl_stack));
775
776 if (parser->stack == NULL) {
777 ucl_create_err (&parser->err, "no memory");
778 return NULL;
779 }
780
781 parser->stack->chunk = parser->chunks;
782 }
783 else {
784 stack = calloc (1, sizeof (struct ucl_stack));
785
786 if (stack == NULL) {
787 ucl_create_err (&parser->err, "no memory");
788 return NULL;
789 }
790
791 stack->chunk = parser->chunks;
792 stack->next = parser->stack;
793 parser->stack = stack;
794 }
795
796 parser->stack->e.len = len;
797
798 #ifdef MSGPACK_DEBUG_PARSER
799 stack = parser->stack;
800 while (stack) {
801 fprintf(stderr, "+");
802 stack = stack->next;
803 }
804
805 fprintf(stderr, "%s -> %d\n", obj_parser->flags & MSGPACK_FLAG_ASSOC ? "object" : "array", (int)len);
806 #endif
807 }
808 else {
809 /*
810 * Get the current stack top
811 */
812 if (parser->stack) {
813 return parser->stack;
814 }
815 else {
816 ucl_create_err (&parser->err, "bad top level object for msgpack");
817 return NULL;
818 }
819 }
820
821 return parser->stack;
822 }
823
824 static bool
ucl_msgpack_is_container_finished(struct ucl_stack * container)825 ucl_msgpack_is_container_finished (struct ucl_stack *container)
826 {
827 assert (container != NULL);
828
829
830 if (container->e.len == 0) {
831 return true;
832 }
833
834 return false;
835 }
836
837 static bool
ucl_msgpack_insert_object(struct ucl_parser * parser,const unsigned char * key,size_t keylen,ucl_object_t * obj)838 ucl_msgpack_insert_object (struct ucl_parser *parser,
839 const unsigned char *key,
840 size_t keylen, ucl_object_t *obj)
841 {
842 struct ucl_stack *container;
843
844 container = parser->stack;
845 assert (container != NULL);
846 assert (container->e.len > 0);
847 assert (obj != NULL);
848 assert (container->obj != NULL);
849
850 if (container->obj->type == UCL_ARRAY) {
851 ucl_array_append (container->obj, obj);
852 }
853 else if (container->obj->type == UCL_OBJECT) {
854 if (key == NULL || keylen == 0) {
855 ucl_create_err (&parser->err, "cannot insert object with no key");
856 return false;
857 }
858
859 obj->key = key;
860 obj->keylen = keylen;
861
862 if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
863 ucl_copy_key_trash (obj);
864 }
865
866 ucl_parser_process_object_element (parser, obj);
867 }
868 else {
869 ucl_create_err (&parser->err, "bad container type");
870 return false;
871 }
872
873 container->e.len--;
874
875 return true;
876 }
877
878 static struct ucl_stack *
ucl_msgpack_get_next_container(struct ucl_parser * parser)879 ucl_msgpack_get_next_container (struct ucl_parser *parser)
880 {
881 struct ucl_stack *cur = NULL;
882 uint64_t len;
883
884 cur = parser->stack;
885
886 if (cur == NULL) {
887 return NULL;
888 }
889
890 len = cur->e.len;
891
892 if (len == 0) {
893 /* We need to switch to the previous container */
894 parser->stack = cur->next;
895 parser->cur_obj = cur->obj;
896 free (cur);
897
898 #ifdef MSGPACK_DEBUG_PARSER
899 cur = parser->stack;
900 while (cur) {
901 fprintf(stderr, "-");
902 cur = cur->next;
903 }
904 fprintf(stderr, "-%s -> %d\n", parser->cur_obj->type == UCL_OBJECT ? "object" : "array", (int)parser->cur_obj->len);
905 #endif
906
907 return ucl_msgpack_get_next_container (parser);
908 }
909
910 /*
911 * For UCL containers we don't know length, so we just insert the whole
912 * message pack blob into the top level container
913 */
914
915 assert (cur->obj != NULL);
916
917 return cur;
918 }
919
920 #define CONSUME_RET do { \
921 if (ret != -1) { \
922 p += ret; \
923 remain -= ret; \
924 obj_parser = NULL; \
925 assert (remain >= 0); \
926 } \
927 else { \
928 ucl_create_err (&parser->err, \
929 "cannot parse type %d of len %u", \
930 (int)obj_parser->fmt, \
931 (unsigned)len); \
932 return false; \
933 } \
934 } while(0)
935
936 #define GET_NEXT_STATE do { \
937 container = ucl_msgpack_get_next_container (parser); \
938 if (container == NULL) { \
939 ucl_create_err (&parser->err, \
940 "empty container"); \
941 return false; \
942 } \
943 next_state = container->obj->type == UCL_OBJECT ? \
944 read_assoc_key : read_array_value; \
945 } while(0)
946
947 static bool
ucl_msgpack_consume(struct ucl_parser * parser)948 ucl_msgpack_consume (struct ucl_parser *parser)
949 {
950 const unsigned char *p, *end, *key = NULL;
951 struct ucl_stack *container;
952 enum e_msgpack_parser_state {
953 read_type,
954 start_assoc,
955 start_array,
956 read_assoc_key,
957 read_assoc_value,
958 finish_assoc_value,
959 read_array_value,
960 finish_array_value,
961 error_state
962 } state = read_type, next_state = error_state;
963 struct ucl_msgpack_parser *obj_parser = NULL;
964 uint64_t len = 0;
965 ssize_t ret, remain, keylen = 0;
966 #ifdef MSGPACK_DEBUG_PARSER
967 uint64_t i;
968 enum e_msgpack_parser_state hist[256];
969 #endif
970
971 p = parser->chunks->begin;
972 remain = parser->chunks->remain;
973 end = p + remain;
974
975
976 while (p < end) {
977 #ifdef MSGPACK_DEBUG_PARSER
978 hist[i++ % 256] = state;
979 #endif
980 switch (state) {
981 case read_type:
982 obj_parser = ucl_msgpack_get_parser_from_type (*p);
983
984 if (obj_parser == NULL) {
985 ucl_create_err (&parser->err, "unknown msgpack format: %x",
986 (unsigned int)*p);
987
988 return false;
989 }
990 /* Now check length sanity */
991 if (obj_parser->flags & MSGPACK_FLAG_FIXED) {
992 if (obj_parser->len == 0) {
993 /* We have an embedded size */
994 len = *p & ~obj_parser->prefix;
995 }
996 else {
997 if (remain < obj_parser->len) {
998 ucl_create_err (&parser->err, "not enough data remain to "
999 "read object's length: %u remain, %u needed",
1000 (unsigned)remain, obj_parser->len);
1001
1002 return false;
1003 }
1004
1005 len = obj_parser->len;
1006 }
1007
1008 if (!(obj_parser->flags & MSGPACK_FLAG_TYPEVALUE)) {
1009 /* We must pass value as the second byte */
1010 if (remain > 0) {
1011 p ++;
1012 remain --;
1013 }
1014 }
1015 else {
1016 /* Len is irrelevant now */
1017 len = 0;
1018 }
1019 }
1020 else {
1021 /* Length is not embedded */
1022 remain --;
1023
1024 if (remain < obj_parser->len) {
1025 ucl_create_err (&parser->err, "not enough data remain to "
1026 "read object's length: %u remain, %u needed",
1027 (unsigned)remain, obj_parser->len);
1028
1029 return false;
1030 }
1031
1032 p ++;
1033
1034 switch (obj_parser->len) {
1035 case 1:
1036 len = *p;
1037 break;
1038 case 2:
1039 len = FROM_BE16 (*(uint16_t *)p);
1040 break;
1041 case 4:
1042 len = FROM_BE32 (*(uint32_t *)p);
1043 break;
1044 case 8:
1045 len = FROM_BE64 (*(uint64_t *)p);
1046 break;
1047 default:
1048 ucl_create_err (&parser->err, "invalid length of the length field: %u",
1049 (unsigned)obj_parser->len);
1050
1051 return false;
1052 }
1053
1054 p += obj_parser->len;
1055 remain -= obj_parser->len;
1056 }
1057
1058 if (obj_parser->flags & MSGPACK_FLAG_ASSOC) {
1059 /* We have just read the new associative map */
1060 state = start_assoc;
1061 }
1062 else if (obj_parser->flags & MSGPACK_FLAG_CONTAINER){
1063 state = start_array;
1064 }
1065 else {
1066 state = next_state;
1067 }
1068
1069 break;
1070 case start_assoc:
1071 parser->cur_obj = ucl_object_new_full (UCL_OBJECT,
1072 parser->chunks->priority);
1073 /* Insert to the previous level container */
1074 if (parser->stack && !ucl_msgpack_insert_object (parser,
1075 key, keylen, parser->cur_obj)) {
1076 return false;
1077 }
1078 /* Get new container */
1079 container = ucl_msgpack_get_container (parser, obj_parser, len);
1080
1081 if (container == NULL) {
1082 return false;
1083 }
1084
1085 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1086 p, remain);
1087 CONSUME_RET;
1088 key = NULL;
1089 keylen = 0;
1090
1091 if (len > 0) {
1092 state = read_type;
1093 next_state = read_assoc_key;
1094 }
1095 else {
1096 /* Empty object */
1097 state = finish_assoc_value;
1098 }
1099 break;
1100
1101 case start_array:
1102 parser->cur_obj = ucl_object_new_full (UCL_ARRAY,
1103 parser->chunks->priority);
1104 /* Insert to the previous level container */
1105 if (parser->stack && !ucl_msgpack_insert_object (parser,
1106 key, keylen, parser->cur_obj)) {
1107 return false;
1108 }
1109 /* Get new container */
1110 container = ucl_msgpack_get_container (parser, obj_parser, len);
1111
1112 if (container == NULL) {
1113 return false;
1114 }
1115
1116 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1117 p, remain);
1118 CONSUME_RET;
1119
1120 if (len > 0) {
1121 state = read_type;
1122 next_state = read_array_value;
1123 }
1124 else {
1125 /* Empty array */
1126 state = finish_array_value;
1127 }
1128 break;
1129
1130 case read_array_value:
1131 /*
1132 * p is now at the value start, len now contains length read and
1133 * obj_parser contains the corresponding specific parser
1134 */
1135 container = parser->stack;
1136
1137 if (parser->stack == NULL) {
1138 ucl_create_err (&parser->err,
1139 "read assoc value when no container represented");
1140 return false;
1141 }
1142
1143 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1144 p, remain);
1145 CONSUME_RET;
1146
1147
1148 /* Insert value to the container and check if we have finished array */
1149 if (!ucl_msgpack_insert_object (parser, NULL, 0,
1150 parser->cur_obj)) {
1151 return false;
1152 }
1153
1154 if (ucl_msgpack_is_container_finished (container)) {
1155 state = finish_array_value;
1156 }
1157 else {
1158 /* Read more elements */
1159 state = read_type;
1160 next_state = read_array_value;
1161 }
1162
1163 break;
1164
1165 case read_assoc_key:
1166 /*
1167 * Keys must have string type for ucl msgpack
1168 */
1169 if (!(obj_parser->flags & MSGPACK_FLAG_KEY)) {
1170 ucl_create_err (&parser->err, "bad type for key: %u, expected "
1171 "string", (unsigned)obj_parser->fmt);
1172
1173 return false;
1174 }
1175
1176 key = p;
1177 keylen = len;
1178
1179 if (keylen > remain || keylen == 0) {
1180 ucl_create_err (&parser->err, "too long or empty key");
1181 return false;
1182 }
1183
1184 p += len;
1185 remain -= len;
1186
1187 state = read_type;
1188 next_state = read_assoc_value;
1189 break;
1190
1191 case read_assoc_value:
1192 /*
1193 * p is now at the value start, len now contains length read and
1194 * obj_parser contains the corresponding specific parser
1195 */
1196 container = parser->stack;
1197
1198 if (container == NULL) {
1199 ucl_create_err (&parser->err,
1200 "read assoc value when no container represented");
1201 return false;
1202 }
1203
1204 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1205 p, remain);
1206 CONSUME_RET;
1207
1208 assert (key != NULL && keylen > 0);
1209
1210 if (!ucl_msgpack_insert_object (parser, key, keylen,
1211 parser->cur_obj)) {
1212
1213 return false;
1214 }
1215
1216 key = NULL;
1217 keylen = 0;
1218
1219 if (ucl_msgpack_is_container_finished (container)) {
1220 state = finish_assoc_value;
1221 }
1222 else {
1223 /* Read more elements */
1224 state = read_type;
1225 next_state = read_assoc_key;
1226 }
1227 break;
1228
1229 case finish_array_value:
1230 case finish_assoc_value:
1231 GET_NEXT_STATE;
1232 state = read_type;
1233 break;
1234
1235 case error_state:
1236 ucl_create_err (&parser->err, "invalid state machine state");
1237
1238 return false;
1239 }
1240 }
1241
1242 /* Check the finishing state */
1243 switch (state) {
1244 case start_array:
1245 case start_assoc:
1246 /* Empty container at the end */
1247 if (len != 0) {
1248 ucl_create_err (&parser->err,
1249 "invalid non-empty container at the end; len=%zu",
1250 (size_t)len);
1251
1252 return false;
1253 }
1254
1255 parser->cur_obj = ucl_object_new_full (
1256 state == start_array ? UCL_ARRAY : UCL_OBJECT,
1257 parser->chunks->priority);
1258
1259 if (parser->stack == NULL) {
1260 ucl_create_err (&parser->err,
1261 "read assoc value when no container represented");
1262 return false;
1263 }
1264 /* Insert to the previous level container */
1265 if (!ucl_msgpack_insert_object (parser,
1266 key, keylen, parser->cur_obj)) {
1267 return false;
1268 }
1269 /* Get new container */
1270 container = ucl_msgpack_get_container (parser, obj_parser, len);
1271
1272 if (container == NULL) {
1273 return false;
1274 }
1275
1276 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1277 p, remain);
1278 break;
1279
1280 case read_array_value:
1281 case read_assoc_value:
1282 if (len != 0) {
1283 ucl_create_err (&parser->err, "unfinished value at the end");
1284
1285 return false;
1286 }
1287
1288 container = parser->stack;
1289
1290 if (parser->stack == NULL) {
1291 ucl_create_err (&parser->err,
1292 "read assoc value when no container represented");
1293 return false;
1294 }
1295
1296 ret = obj_parser->func (parser, container, len, obj_parser->fmt,
1297 p, remain);
1298 CONSUME_RET;
1299
1300
1301 /* Insert value to the container and check if we have finished array */
1302 if (!ucl_msgpack_insert_object (parser, NULL, 0,
1303 parser->cur_obj)) {
1304 return false;
1305 }
1306 break;
1307 case finish_array_value:
1308 case finish_assoc_value:
1309 case read_type:
1310 /* Valid finishing state */
1311 break;
1312 default:
1313 /* Invalid finishing state */
1314 ucl_create_err (&parser->err, "invalid state machine finishing state: %d",
1315 state);
1316
1317 return false;
1318 }
1319
1320 /* Rewind to the top level container */
1321 ucl_msgpack_get_next_container (parser);
1322
1323 if (parser->stack != NULL) {
1324 ucl_create_err (&parser->err, "incomplete container");
1325
1326 return false;
1327 }
1328
1329 return true;
1330 }
1331
1332 bool
ucl_parse_msgpack(struct ucl_parser * parser)1333 ucl_parse_msgpack (struct ucl_parser *parser)
1334 {
1335 ucl_object_t *container = NULL;
1336 const unsigned char *p;
1337 bool ret;
1338
1339 assert (parser != NULL);
1340 assert (parser->chunks != NULL);
1341 assert (parser->chunks->begin != NULL);
1342 assert (parser->chunks->remain != 0);
1343
1344 p = parser->chunks->begin;
1345
1346 if (parser->stack) {
1347 container = parser->stack->obj;
1348 }
1349
1350 /*
1351 * When we start parsing message pack chunk, we must ensure that we
1352 * have either a valid container or the top object inside message pack is
1353 * of container type
1354 */
1355 if (container == NULL) {
1356 if ((*p & 0x80) != 0x80 && !(*p >= 0xdc && *p <= 0xdf)) {
1357 ucl_create_err (&parser->err, "bad top level object for msgpack");
1358 return false;
1359 }
1360 }
1361
1362 ret = ucl_msgpack_consume (parser);
1363
1364 if (ret && parser->top_obj == NULL) {
1365 parser->top_obj = parser->cur_obj;
1366 }
1367
1368 return ret;
1369 }
1370
1371 static ssize_t
ucl_msgpack_parse_map(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)1372 ucl_msgpack_parse_map (struct ucl_parser *parser,
1373 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1374 const unsigned char *pos, size_t remain)
1375 {
1376 container->obj = parser->cur_obj;
1377
1378 return 0;
1379 }
1380
1381 static ssize_t
ucl_msgpack_parse_array(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)1382 ucl_msgpack_parse_array (struct ucl_parser *parser,
1383 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1384 const unsigned char *pos, size_t remain)
1385 {
1386 container->obj = parser->cur_obj;
1387
1388 return 0;
1389 }
1390
1391 static ssize_t
ucl_msgpack_parse_string(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)1392 ucl_msgpack_parse_string (struct ucl_parser *parser,
1393 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1394 const unsigned char *pos, size_t remain)
1395 {
1396 ucl_object_t *obj;
1397
1398 if (len > remain) {
1399 return -1;
1400 }
1401
1402 obj = ucl_object_new_full (UCL_STRING, parser->chunks->priority);
1403 obj->value.sv = pos;
1404 obj->len = len;
1405
1406 if (fmt >= msgpack_bin8 && fmt <= msgpack_bin32) {
1407 obj->flags |= UCL_OBJECT_BINARY;
1408 }
1409
1410 if (!(parser->flags & UCL_PARSER_ZEROCOPY)) {
1411 if (obj->flags & UCL_OBJECT_BINARY) {
1412 obj->trash_stack[UCL_TRASH_VALUE] = malloc (len);
1413
1414 if (obj->trash_stack[UCL_TRASH_VALUE] != NULL) {
1415 memcpy (obj->trash_stack[UCL_TRASH_VALUE], pos, len);
1416 }
1417 }
1418 else {
1419 ucl_copy_value_trash (obj);
1420 }
1421 }
1422
1423 parser->cur_obj = obj;
1424
1425 return len;
1426 }
1427
1428 static ssize_t
ucl_msgpack_parse_int(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)1429 ucl_msgpack_parse_int (struct ucl_parser *parser,
1430 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1431 const unsigned char *pos, size_t remain)
1432 {
1433 ucl_object_t *obj;
1434 int8_t iv8;
1435 int16_t iv16;
1436 int32_t iv32;
1437 int64_t iv64;
1438 uint16_t uiv16;
1439 uint32_t uiv32;
1440 uint64_t uiv64;
1441
1442
1443 if (len > remain) {
1444 return -1;
1445 }
1446
1447 obj = ucl_object_new_full (UCL_INT, parser->chunks->priority);
1448
1449 switch (fmt) {
1450 case msgpack_positive_fixint:
1451 obj->value.iv = (*pos & 0x7f);
1452 len = 1;
1453 break;
1454 case msgpack_negative_fixint:
1455 obj->value.iv = - (*pos & 0x1f);
1456 len = 1;
1457 break;
1458 case msgpack_uint8:
1459 obj->value.iv = (unsigned char)*pos;
1460 len = 1;
1461 break;
1462 case msgpack_int8:
1463 memcpy (&iv8, pos, sizeof (iv8));
1464 obj->value.iv = iv8;
1465 len = 1;
1466 break;
1467 case msgpack_int16:
1468 memcpy (&iv16, pos, sizeof (iv16));
1469 iv16 = FROM_BE16 (iv16);
1470 obj->value.iv = iv16;
1471 len = 2;
1472 break;
1473 case msgpack_uint16:
1474 memcpy (&uiv16, pos, sizeof (uiv16));
1475 uiv16 = FROM_BE16 (uiv16);
1476 obj->value.iv = uiv16;
1477 len = 2;
1478 break;
1479 case msgpack_int32:
1480 memcpy (&iv32, pos, sizeof (iv32));
1481 iv32 = FROM_BE32 (iv32);
1482 obj->value.iv = iv32;
1483 len = 4;
1484 break;
1485 case msgpack_uint32:
1486 memcpy(&uiv32, pos, sizeof(uiv32));
1487 uiv32 = FROM_BE32(uiv32);
1488 obj->value.iv = uiv32;
1489 len = 4;
1490 break;
1491 case msgpack_int64:
1492 memcpy (&iv64, pos, sizeof (iv64));
1493 iv64 = FROM_BE64 (iv64);
1494 obj->value.iv = iv64;
1495 len = 8;
1496 break;
1497 case msgpack_uint64:
1498 memcpy(&uiv64, pos, sizeof(uiv64));
1499 uiv64 = FROM_BE64(uiv64);
1500 obj->value.iv = uiv64;
1501 len = 8;
1502 break;
1503 default:
1504 assert (0);
1505 break;
1506 }
1507
1508 parser->cur_obj = obj;
1509
1510 return len;
1511 }
1512
1513 static ssize_t
ucl_msgpack_parse_float(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)1514 ucl_msgpack_parse_float (struct ucl_parser *parser,
1515 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1516 const unsigned char *pos, size_t remain)
1517 {
1518 ucl_object_t *obj;
1519 union {
1520 uint32_t i;
1521 float f;
1522 } d;
1523 uint64_t uiv64;
1524
1525 if (len > remain) {
1526 return -1;
1527 }
1528
1529 obj = ucl_object_new_full (UCL_FLOAT, parser->chunks->priority);
1530
1531 switch (fmt) {
1532 case msgpack_float32:
1533 memcpy(&d.i, pos, sizeof(d.i));
1534 d.i = FROM_BE32(d.i);
1535 /* XXX: can be slow */
1536 obj->value.dv = d.f;
1537 len = 4;
1538 break;
1539 case msgpack_float64:
1540 memcpy(&uiv64, pos, sizeof(uiv64));
1541 uiv64 = FROM_BE64(uiv64);
1542 obj->value.iv = uiv64;
1543 len = 8;
1544 break;
1545 default:
1546 assert (0);
1547 break;
1548 }
1549
1550 parser->cur_obj = obj;
1551
1552 return len;
1553 }
1554
1555 static ssize_t
ucl_msgpack_parse_bool(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)1556 ucl_msgpack_parse_bool (struct ucl_parser *parser,
1557 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1558 const unsigned char *pos, size_t remain)
1559 {
1560 ucl_object_t *obj;
1561
1562 if (len > remain) {
1563 return -1;
1564 }
1565
1566 obj = ucl_object_new_full (UCL_BOOLEAN, parser->chunks->priority);
1567
1568 switch (fmt) {
1569 case msgpack_true:
1570 obj->value.iv = true;
1571 break;
1572 case msgpack_false:
1573 obj->value.iv = false;
1574 break;
1575 default:
1576 assert (0);
1577 break;
1578 }
1579
1580 parser->cur_obj = obj;
1581
1582 return 1;
1583 }
1584
1585 static ssize_t
ucl_msgpack_parse_null(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)1586 ucl_msgpack_parse_null (struct ucl_parser *parser,
1587 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1588 const unsigned char *pos, size_t remain)
1589 {
1590 ucl_object_t *obj;
1591
1592 if (len > remain) {
1593 return -1;
1594 }
1595
1596 obj = ucl_object_new_full (UCL_NULL, parser->chunks->priority);
1597 parser->cur_obj = obj;
1598
1599 return 1;
1600 }
1601
1602 static ssize_t
ucl_msgpack_parse_ignore(struct ucl_parser * parser,struct ucl_stack * container,size_t len,enum ucl_msgpack_format fmt,const unsigned char * pos,size_t remain)1603 ucl_msgpack_parse_ignore (struct ucl_parser *parser,
1604 struct ucl_stack *container, size_t len, enum ucl_msgpack_format fmt,
1605 const unsigned char *pos, size_t remain)
1606 {
1607 if (len > remain) {
1608 return -1;
1609 }
1610
1611 switch (fmt) {
1612 case msgpack_fixext1:
1613 len = 2;
1614 break;
1615 case msgpack_fixext2:
1616 len = 3;
1617 break;
1618 case msgpack_fixext4:
1619 len = 5;
1620 break;
1621 case msgpack_fixext8:
1622 len = 9;
1623 break;
1624 case msgpack_fixext16:
1625 len = 17;
1626 break;
1627 case msgpack_ext8:
1628 case msgpack_ext16:
1629 case msgpack_ext32:
1630 len = len + 1;
1631 break;
1632 default:
1633 ucl_create_err (&parser->err, "bad type: %x", (unsigned)fmt);
1634 return -1;
1635 }
1636
1637 return len;
1638 }
1639