xref: /freebsd/contrib/libucl/src/ucl_msgpack.c (revision 048488c0c4e47aa2aac9709b18d7da14b06f78cd)
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