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
ucl_emitter_print_int_msgpack(struct ucl_emitter_context * ctx,int64_t val)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
ucl_emitter_print_double_msgpack(struct ucl_emitter_context * ctx,double val)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
ucl_emitter_print_bool_msgpack(struct ucl_emitter_context * ctx,bool val)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
ucl_emitter_print_string_msgpack(struct ucl_emitter_context * ctx,const char * s,size_t len)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
ucl_emitter_print_binary_string_msgpack(struct ucl_emitter_context * ctx,const char * s,size_t len)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
ucl_emitter_print_null_msgpack(struct ucl_emitter_context * ctx)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
ucl_emitter_print_key_msgpack(bool print_key,struct ucl_emitter_context * ctx,const ucl_object_t * obj)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
ucl_emitter_print_array_msgpack(struct ucl_emitter_context * ctx,size_t len)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
ucl_emitter_print_object_msgpack(struct ucl_emitter_context * ctx,size_t len)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 *
ucl_msgpack_get_parser_from_type(unsigned char t)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 *
ucl_msgpack_get_container(struct ucl_parser * parser,struct ucl_msgpack_parser * obj_parser,uint64_t len)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
ucl_msgpack_is_container_finished(struct ucl_stack * container)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
ucl_msgpack_insert_object(struct ucl_parser * parser,const unsigned char * key,size_t keylen,ucl_object_t * obj)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 *
ucl_msgpack_get_next_container(struct ucl_parser * parser)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
ucl_msgpack_consume(struct ucl_parser * parser)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
ucl_parse_msgpack(struct ucl_parser * parser)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
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)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
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)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
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)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
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)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
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)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
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)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
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)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
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)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