1 /*
2 * This file has been copied from the zcbor library.
3 * Commit zcbor 0.7.0
4 */
5
6 /*
7 * Copyright (c) 2020 Nordic Semiconductor ASA
8 *
9 * SPDX-License-Identifier: Apache-2.0
10 */
11
12 #include <stdint.h>
13 #include <stdbool.h>
14 #include <stddef.h>
15 #include <string.h>
16 #include <zcbor_decode.h>
17 #include <zcbor_common.h>
18
19
20 /** Return value length from additional value.
21 */
additional_len(uint8_t additional)22 static uint_fast32_t additional_len(uint8_t additional)
23 {
24 if (ZCBOR_VALUE_IS_1_BYTE <= additional && additional <= ZCBOR_VALUE_IS_8_BYTES) {
25 /* 24 => 1
26 * 25 => 2
27 * 26 => 4
28 * 27 => 8
29 */
30 return 1U << (additional - ZCBOR_VALUE_IS_1_BYTE);
31 }
32 return 0;
33 }
34
35 /** Extract the major type, i.e. the first 3 bits of the header byte. */
36 #define MAJOR_TYPE(header_byte) ((zcbor_major_type_t)(((header_byte) >> 5) & 0x7))
37
38 /** Extract the additional info, i.e. the last 5 bits of the header byte. */
39 #define ADDITIONAL(header_byte) ((header_byte) & 0x1F)
40
41
42 #define FAIL_AND_DECR_IF(expr, err) \
43 do {\
44 if (expr) { \
45 (state->payload)--; \
46 ZCBOR_ERR(err); \
47 } \
48 } while(0)
49
initial_checks(zcbor_state_t * state)50 static bool initial_checks(zcbor_state_t *state)
51 {
52 ZCBOR_CHECK_ERROR();
53 ZCBOR_CHECK_PAYLOAD();
54 return true;
55 }
56
type_check(zcbor_state_t * state,zcbor_major_type_t exp_major_type)57 static bool type_check(zcbor_state_t *state, zcbor_major_type_t exp_major_type)
58 {
59 if (!initial_checks(state)) {
60 ZCBOR_FAIL();
61 }
62 zcbor_major_type_t major_type = MAJOR_TYPE(*state->payload);
63
64 if (major_type != exp_major_type) {
65 ZCBOR_ERR(ZCBOR_ERR_WRONG_TYPE);
66 }
67 return true;
68 }
69
70 #define INITIAL_CHECKS() \
71 do {\
72 if (!initial_checks(state)) { \
73 ZCBOR_FAIL(); \
74 } \
75 } while(0)
76
77 #define INITIAL_CHECKS_WITH_TYPE(exp_major_type) \
78 do {\
79 if (!type_check(state, exp_major_type)) { \
80 ZCBOR_FAIL(); \
81 } \
82 } while(0)
83
84 #define ERR_RESTORE(err) \
85 do { \
86 state->payload = state->payload_bak; \
87 state->elem_count++; \
88 ZCBOR_ERR(err); \
89 } while(0)
90
91 #define FAIL_RESTORE() \
92 do { \
93 state->payload = state->payload_bak; \
94 state->elem_count++; \
95 ZCBOR_FAIL(); \
96 } while(0)
97
98 /** Get a single value.
99 *
100 * @details @p ppayload must point to the header byte. This function will
101 * retrieve the value (either from within the additional info, or from
102 * the subsequent bytes) and return it in the result. The result can
103 * have arbitrary length.
104 *
105 * The function will also validate
106 * - Min/max constraints on the value.
107 * - That @p payload doesn't overrun past @p payload_end.
108 * - That @p elem_count has not been exhausted.
109 *
110 * @p ppayload and @p elem_count are updated if the function
111 * succeeds. If not, they are left unchanged.
112 *
113 * CBOR values are always big-endian, so this function converts from
114 * big to little-endian if necessary (@ref CONFIG_BIG_ENDIAN).
115 */
value_extract(zcbor_state_t * state,void * const result,uint_fast32_t result_len)116 static bool value_extract(zcbor_state_t *state,
117 void *const result, uint_fast32_t result_len)
118 {
119 zcbor_trace();
120 zcbor_assert_state(result_len != 0, "0-length result not supported.\r\n");
121 zcbor_assert_state(result != NULL, NULL);
122
123 INITIAL_CHECKS();
124 ZCBOR_ERR_IF((state->elem_count == 0), ZCBOR_ERR_LOW_ELEM_COUNT);
125
126 uint8_t *u8_result = (uint8_t *)result;
127 uint8_t additional = ADDITIONAL(*state->payload);
128
129 state->payload_bak = state->payload;
130 (state->payload)++;
131
132 memset(result, 0, result_len);
133 if (additional <= ZCBOR_VALUE_IN_HEADER) {
134 #ifdef CONFIG_BIG_ENDIAN
135 u8_result[result_len - 1] = additional;
136 #else
137 u8_result[0] = additional;
138 #endif /* CONFIG_BIG_ENDIAN */
139 } else {
140 uint_fast32_t len = additional_len(additional);
141
142 FAIL_AND_DECR_IF(len > result_len, ZCBOR_ERR_INT_SIZE);
143 FAIL_AND_DECR_IF(len == 0, ZCBOR_ERR_ADDITIONAL_INVAL); // additional_len() did not recognize the additional value.
144 FAIL_AND_DECR_IF((state->payload + len) > state->payload_end,
145 ZCBOR_ERR_NO_PAYLOAD);
146
147 #ifdef CONFIG_BIG_ENDIAN
148 memcpy(&u8_result[result_len - len], state->payload, len);
149 #else
150 for (uint_fast32_t i = 0; i < len; i++) {
151 u8_result[i] = (state->payload)[len - i - 1];
152 }
153 #endif /* CONFIG_BIG_ENDIAN */
154
155 (state->payload) += len;
156 }
157
158 (state->elem_count)--;
159 return true;
160 }
161
162
zcbor_int_decode(zcbor_state_t * state,void * result_int,size_t int_size)163 bool zcbor_int_decode(zcbor_state_t *state, void *result_int, size_t int_size)
164 {
165 INITIAL_CHECKS();
166 zcbor_major_type_t major_type = MAJOR_TYPE(*state->payload);
167 uint8_t *result_uint8 = (uint8_t *)result_int;
168 int8_t *result_int8 = (int8_t *)result_int;
169
170 if (major_type != ZCBOR_MAJOR_TYPE_PINT
171 && major_type != ZCBOR_MAJOR_TYPE_NINT) {
172 /* Value to be read doesn't have the right type. */
173 ZCBOR_ERR(ZCBOR_ERR_WRONG_TYPE);
174 }
175
176 if (!value_extract(state, result_int, int_size)) {
177 ZCBOR_FAIL();
178 }
179
180 #ifdef CONFIG_BIG_ENDIAN
181 if (result_int8[0] < 0) {
182 #else
183 if (result_int8[int_size - 1] < 0) {
184 #endif
185 /* Value is too large to fit in a signed integer. */
186 ERR_RESTORE(ZCBOR_ERR_INT_SIZE);
187 }
188
189 if (major_type == ZCBOR_MAJOR_TYPE_NINT) {
190 /* Convert from CBOR's representation by flipping all bits. */
191 for (int i = 0; i < int_size; i++) {
192 result_uint8[i] = (uint8_t)~result_uint8[i];
193 }
194 }
195
196 return true;
197 }
198
199
200 bool zcbor_int32_decode(zcbor_state_t *state, int32_t *result)
201 {
202 return zcbor_int_decode(state, result, sizeof(*result));
203 }
204
205
206 bool zcbor_int64_decode(zcbor_state_t *state, int64_t *result)
207 {
208 return zcbor_int_decode(state, result, sizeof(*result));
209 }
210
211
212 bool zcbor_uint32_decode(zcbor_state_t *state, uint32_t *result)
213 {
214 INITIAL_CHECKS_WITH_TYPE(ZCBOR_MAJOR_TYPE_PINT);
215
216 if (!value_extract(state, result, sizeof(*result))) {
217 ZCBOR_FAIL();
218 }
219 return true;
220 }
221
222
223 bool zcbor_int32_expect_union(zcbor_state_t *state, int32_t result)
224 {
225 if (!zcbor_union_elem_code(state)) {
226 ZCBOR_FAIL();
227 }
228 return zcbor_int32_expect(state, result);
229 }
230
231
232 bool zcbor_int64_expect_union(zcbor_state_t *state, int64_t result)
233 {
234 if (!zcbor_union_elem_code(state)) {
235 ZCBOR_FAIL();
236 }
237 return zcbor_int64_expect(state, result);
238 }
239
240
241 bool zcbor_uint32_expect_union(zcbor_state_t *state, uint32_t result)
242 {
243 if (!zcbor_union_elem_code(state)) {
244 ZCBOR_FAIL();
245 }
246 return zcbor_uint32_expect(state, result);
247 }
248
249
250 bool zcbor_uint64_expect_union(zcbor_state_t *state, uint64_t result)
251 {
252 if (!zcbor_union_elem_code(state)) {
253 ZCBOR_FAIL();
254 }
255 return zcbor_uint64_expect(state, result);
256 }
257
258
259 bool zcbor_int32_expect(zcbor_state_t *state, int32_t result)
260 {
261 return zcbor_int64_expect(state, result);
262 }
263
264
265 bool zcbor_int64_expect(zcbor_state_t *state, int64_t result)
266 {
267 int64_t value;
268
269 if (!zcbor_int64_decode(state, &value)) {
270 ZCBOR_FAIL();
271 }
272
273 if (value != result) {
274 zcbor_print("%" PRIi64 " != %" PRIi64 "\r\n", value, result);
275 ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
276 }
277 return true;
278 }
279
280
281 bool zcbor_uint64_decode(zcbor_state_t *state, uint64_t *result)
282 {
283 INITIAL_CHECKS_WITH_TYPE(ZCBOR_MAJOR_TYPE_PINT);
284
285 if (!value_extract(state, result, sizeof(*result))) {
286 ZCBOR_FAIL();
287 }
288 return true;
289 }
290
291
292 #ifdef ZCBOR_SUPPORTS_SIZE_T
293 bool zcbor_size_decode(zcbor_state_t *state, size_t *result)
294 {
295 return value_extract(state, result, sizeof(size_t));
296 }
297 #endif
298
299
300 bool zcbor_uint32_expect(zcbor_state_t *state, uint32_t result)
301 {
302 return zcbor_uint64_expect(state, result);
303 }
304
305
306 bool zcbor_uint64_expect(zcbor_state_t *state, uint64_t result)
307 {
308 uint64_t value;
309
310 if (!zcbor_uint64_decode(state, &value)) {
311 ZCBOR_FAIL();
312 }
313 if (value != result) {
314 zcbor_print("%" PRIu64 " != %" PRIu64 "\r\n", value, result);
315 ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
316 }
317 return true;
318 }
319
320
321 #ifdef ZCBOR_SUPPORTS_SIZE_T
322 bool zcbor_size_expect(zcbor_state_t *state, size_t result)
323 {
324 return zcbor_uint64_expect(state, result);
325 }
326 #endif
327
328
329 static bool str_start_decode(zcbor_state_t *state,
330 struct zcbor_string *result, zcbor_major_type_t exp_major_type)
331 {
332 INITIAL_CHECKS_WITH_TYPE(exp_major_type);
333
334 if (!value_extract(state, &result->len, sizeof(result->len))) {
335 ZCBOR_FAIL();
336 }
337
338 result->value = state->payload;
339 return true;
340 }
341
342
343 static bool str_overflow_check(zcbor_state_t *state, struct zcbor_string *result)
344 {
345 if (result->len > (state->payload_end - state->payload)) {
346 zcbor_print("error: 0x%zu > 0x%zu\r\n",
347 result->len,
348 (state->payload_end - state->payload));
349 ERR_RESTORE(ZCBOR_ERR_NO_PAYLOAD);
350 }
351 return true;
352 }
353
354
355 bool zcbor_bstr_start_decode(zcbor_state_t *state, struct zcbor_string *result)
356 {
357 struct zcbor_string dummy;
358 if (result == NULL) {
359 result = &dummy;
360 }
361
362 if(!str_start_decode(state, result, ZCBOR_MAJOR_TYPE_BSTR)) {
363 ZCBOR_FAIL();
364 }
365
366 if (!str_overflow_check(state, result)) {
367 ZCBOR_FAIL();
368 }
369
370 if (!zcbor_new_backup(state, ZCBOR_MAX_ELEM_COUNT)) {
371 FAIL_RESTORE();
372 }
373
374 state->payload_end = result->value + result->len;
375 return true;
376 }
377
378
379 bool zcbor_bstr_end_decode(zcbor_state_t *state)
380 {
381 ZCBOR_ERR_IF(state->payload != state->payload_end, ZCBOR_ERR_PAYLOAD_NOT_CONSUMED);
382
383 if (!zcbor_process_backup(state,
384 ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME | ZCBOR_FLAG_TRANSFER_PAYLOAD,
385 ZCBOR_MAX_ELEM_COUNT)) {
386 ZCBOR_FAIL();
387 }
388
389 return true;
390 }
391
392
393 static void partition_fragment(const zcbor_state_t *state,
394 struct zcbor_string_fragment *result)
395 {
396 result->fragment.len = MIN(result->fragment.len,
397 (size_t)state->payload_end - (size_t)state->payload);
398 }
399
400
401 static bool start_decode_fragment(zcbor_state_t *state,
402 struct zcbor_string_fragment *result,
403 zcbor_major_type_t exp_major_type)
404 {
405 if(!str_start_decode(state, &result->fragment, exp_major_type)) {
406 ZCBOR_FAIL();
407 }
408
409 result->offset = 0;
410 result->total_len = result->fragment.len;
411 partition_fragment(state, result);
412 state->payload_end = state->payload + result->fragment.len;
413
414 return true;
415 }
416
417 bool zcbor_bstr_start_decode_fragment(zcbor_state_t *state,
418 struct zcbor_string_fragment *result)
419 {
420 if (!start_decode_fragment(state, result, ZCBOR_MAJOR_TYPE_BSTR)) {
421 ZCBOR_FAIL();
422 }
423 if (!zcbor_new_backup(state, ZCBOR_MAX_ELEM_COUNT)) {
424 FAIL_RESTORE();
425 }
426 return true;
427 }
428
429
430 void zcbor_next_fragment(zcbor_state_t *state,
431 struct zcbor_string_fragment *prev_fragment,
432 struct zcbor_string_fragment *result)
433 {
434 memcpy(result, prev_fragment, sizeof(*result));
435 result->fragment.value = state->payload_mut;
436 result->offset += prev_fragment->fragment.len;
437 result->fragment.len = result->total_len - result->offset;
438
439 partition_fragment(state, result);
440 zcbor_print("New fragment length %zu\r\n", result->fragment.len);
441
442 state->payload += result->fragment.len;
443 }
444
445
446 void zcbor_bstr_next_fragment(zcbor_state_t *state,
447 struct zcbor_string_fragment *prev_fragment,
448 struct zcbor_string_fragment *result)
449 {
450 memcpy(result, prev_fragment, sizeof(*result));
451 result->fragment.value = state->payload_mut;
452 result->offset += prev_fragment->fragment.len;
453 result->fragment.len = result->total_len - result->offset;
454
455 partition_fragment(state, result);
456 zcbor_print("fragment length %zu\r\n", result->fragment.len);
457 state->payload_end = state->payload + result->fragment.len;
458 }
459
460
461 bool zcbor_is_last_fragment(const struct zcbor_string_fragment *fragment)
462 {
463 return (fragment->total_len == (fragment->offset + fragment->fragment.len));
464 }
465
466
467 static bool str_decode(zcbor_state_t *state, struct zcbor_string *result,
468 zcbor_major_type_t exp_major_type)
469 {
470 if (!str_start_decode(state, result, exp_major_type)) {
471 ZCBOR_FAIL();
472 }
473
474 if (!str_overflow_check(state, result)) {
475 ZCBOR_FAIL();
476 }
477
478 state->payload += result->len;
479 return true;
480 }
481
482
483 static bool str_decode_fragment(zcbor_state_t *state, struct zcbor_string_fragment *result,
484 zcbor_major_type_t exp_major_type)
485 {
486 if (!start_decode_fragment(state, result, exp_major_type)) {
487 ZCBOR_FAIL();
488 }
489
490 (state->payload) += result->fragment.len;
491 return true;
492 }
493
494
495 static bool str_expect(zcbor_state_t *state, struct zcbor_string *result,
496 zcbor_major_type_t exp_major_type)
497 {
498 struct zcbor_string tmp_result;
499
500 if (!str_decode(state, &tmp_result, exp_major_type)) {
501 ZCBOR_FAIL();
502 }
503 if ((tmp_result.len != result->len)
504 || memcmp(result->value, tmp_result.value, tmp_result.len)) {
505 ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
506 }
507 return true;
508 }
509
510
511 bool zcbor_bstr_decode(zcbor_state_t *state, struct zcbor_string *result)
512 {
513 return str_decode(state, result, ZCBOR_MAJOR_TYPE_BSTR);
514 }
515
516
517 bool zcbor_bstr_decode_fragment(zcbor_state_t *state, struct zcbor_string_fragment *result)
518 {
519 return str_decode_fragment(state, result, ZCBOR_MAJOR_TYPE_BSTR);
520 }
521
522
523 bool zcbor_bstr_expect(zcbor_state_t *state, struct zcbor_string *result)
524 {
525 return str_expect(state, result, ZCBOR_MAJOR_TYPE_BSTR);
526 }
527
528
529 bool zcbor_tstr_decode(zcbor_state_t *state, struct zcbor_string *result)
530 {
531 return str_decode(state, result, ZCBOR_MAJOR_TYPE_TSTR);
532 }
533
534
535 bool zcbor_tstr_decode_fragment(zcbor_state_t *state, struct zcbor_string_fragment *result)
536 {
537 return str_decode_fragment(state, result, ZCBOR_MAJOR_TYPE_TSTR);
538 }
539
540
541 bool zcbor_tstr_expect(zcbor_state_t *state, struct zcbor_string *result)
542 {
543 return str_expect(state, result, ZCBOR_MAJOR_TYPE_TSTR);
544 }
545
546
547 static bool list_map_start_decode(zcbor_state_t *state,
548 zcbor_major_type_t exp_major_type)
549 {
550 uint_fast32_t new_elem_count;
551 bool indefinite_length_array = false;
552
553 INITIAL_CHECKS_WITH_TYPE(exp_major_type);
554
555 if (ADDITIONAL(*state->payload) == ZCBOR_VALUE_IS_INDEFINITE_LENGTH) {
556 /* Indefinite length array. */
557 new_elem_count = ZCBOR_LARGE_ELEM_COUNT;
558 ZCBOR_ERR_IF(state->elem_count == 0, ZCBOR_ERR_LOW_ELEM_COUNT);
559 indefinite_length_array = true;
560 state->payload++;
561 state->elem_count--;
562 } else {
563 if (!value_extract(state, &new_elem_count, sizeof(new_elem_count))) {
564 ZCBOR_FAIL();
565 }
566 }
567
568 if (!zcbor_new_backup(state, new_elem_count)) {
569 FAIL_RESTORE();
570 }
571
572 state->indefinite_length_array = indefinite_length_array;
573
574 return true;
575 }
576
577
578 bool zcbor_list_start_decode(zcbor_state_t *state)
579 {
580 return list_map_start_decode(state, ZCBOR_MAJOR_TYPE_LIST);
581 }
582
583
584 bool zcbor_map_start_decode(zcbor_state_t *state)
585 {
586 bool ret = list_map_start_decode(state, ZCBOR_MAJOR_TYPE_MAP);
587
588 if (ret && !state->indefinite_length_array) {
589 if (state->elem_count >= (ZCBOR_MAX_ELEM_COUNT / 2)) {
590 /* The new elem_count is too large. */
591 ERR_RESTORE(ZCBOR_ERR_INT_SIZE);
592 }
593 state->elem_count *= 2;
594 }
595 return ret;
596 }
597
598
599 static bool array_end_expect(zcbor_state_t *state)
600 {
601 INITIAL_CHECKS();
602 ZCBOR_ERR_IF(*state->payload != 0xFF, ZCBOR_ERR_WRONG_TYPE);
603
604 state->payload++;
605 return true;
606 }
607
608
609 static bool list_map_end_decode(zcbor_state_t *state)
610 {
611 uint_fast32_t max_elem_count = 0;
612
613 if (state->indefinite_length_array) {
614 if (!array_end_expect(state)) {
615 ZCBOR_FAIL();
616 }
617 max_elem_count = ZCBOR_MAX_ELEM_COUNT;
618 state->indefinite_length_array = false;
619 }
620 if (!zcbor_process_backup(state,
621 ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME | ZCBOR_FLAG_TRANSFER_PAYLOAD,
622 max_elem_count)) {
623 ZCBOR_FAIL();
624 }
625
626 return true;
627 }
628
629
630 bool zcbor_list_end_decode(zcbor_state_t *state)
631 {
632 return list_map_end_decode(state);
633 }
634
635
636 bool zcbor_map_end_decode(zcbor_state_t *state)
637 {
638 return list_map_end_decode(state);
639 }
640
641
642 bool zcbor_list_map_end_force_decode(zcbor_state_t *state)
643 {
644 if (!zcbor_process_backup(state,
645 ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME | ZCBOR_FLAG_TRANSFER_PAYLOAD,
646 ZCBOR_MAX_ELEM_COUNT)) {
647 ZCBOR_FAIL();
648 }
649
650 return true;
651 }
652
653
654 static bool primx_expect(zcbor_state_t *state, uint8_t result)
655 {
656 uint32_t value;
657
658 INITIAL_CHECKS_WITH_TYPE(ZCBOR_MAJOR_TYPE_PRIM);
659
660 if (!value_extract(state, &value, sizeof(value))) {
661 ZCBOR_FAIL();
662 }
663
664 if (value != result) {
665 ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
666 }
667 return true;
668 }
669
670
671 bool zcbor_nil_expect(zcbor_state_t *state, void *unused)
672 {
673 if (!primx_expect(state, 22)) {
674 ZCBOR_FAIL();
675 }
676 return true;
677 }
678
679
680 bool zcbor_undefined_expect(zcbor_state_t *state, void *unused)
681 {
682 if (!primx_expect(state, 23)) {
683 ZCBOR_FAIL();
684 }
685 return true;
686 }
687
688
689 bool zcbor_bool_decode(zcbor_state_t *state, bool *result)
690 {
691 if (zcbor_bool_expect(state, false)) {
692 *result = false;
693 } else if (zcbor_bool_expect(state, true)) {
694 *result = true;
695 } else {
696 ZCBOR_FAIL();
697 }
698
699 zcbor_print("boolval: %u\r\n", *result);
700 return true;
701 }
702
703
704 bool zcbor_bool_expect(zcbor_state_t *state, bool result)
705 {
706 if (!primx_expect(state, (uint8_t)(!!result) + ZCBOR_BOOL_TO_PRIM)) {
707 ZCBOR_FAIL();
708 }
709 return true;
710 }
711
712
713 bool zcbor_float32_decode(zcbor_state_t *state, float *result)
714 {
715 INITIAL_CHECKS_WITH_TYPE(ZCBOR_MAJOR_TYPE_PRIM);
716 ZCBOR_ERR_IF(ADDITIONAL(*state->payload) != ZCBOR_VALUE_IS_4_BYTES, ZCBOR_ERR_FLOAT_SIZE);
717
718 if (!value_extract(state, result, sizeof(*result))) {
719 ZCBOR_FAIL();
720 }
721
722 return true;
723 }
724
725
726 bool zcbor_float32_expect(zcbor_state_t *state, float result)
727 {
728 float value;
729
730 if (!zcbor_float32_decode(state, &value)) {
731 ZCBOR_FAIL();
732 }
733 if (value != result) {
734 ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
735 }
736 return true;
737 }
738
739
740 bool zcbor_float64_decode(zcbor_state_t *state, double *result)
741 {
742 INITIAL_CHECKS_WITH_TYPE(ZCBOR_MAJOR_TYPE_PRIM);
743 ZCBOR_ERR_IF(ADDITIONAL(*state->payload) != ZCBOR_VALUE_IS_8_BYTES, ZCBOR_ERR_FLOAT_SIZE);
744
745 if (!value_extract(state, result, sizeof(*result))) {
746 ZCBOR_FAIL();
747 }
748
749 return true;
750 }
751
752
753 bool zcbor_float64_expect(zcbor_state_t *state, double result)
754 {
755 double value;
756
757 if (!zcbor_float64_decode(state, &value)) {
758 ZCBOR_FAIL();
759 }
760 if (value != result) {
761 ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
762 }
763 return true;
764 }
765
766
767 bool zcbor_float_decode(zcbor_state_t *state, double *result)
768 {
769 float float_result;
770
771 if (zcbor_float32_decode(state, &float_result)) {
772 *result = (double)float_result;
773 } else if (!zcbor_float64_decode(state, result)) {
774 ZCBOR_FAIL();
775 }
776
777 return true;
778 }
779
780
781 bool zcbor_float_expect(zcbor_state_t *state, double result)
782 {
783 if (zcbor_float32_expect(state, (float)result)) {
784 /* Do nothing */
785 } else if (!zcbor_float64_expect(state, result)) {
786 ZCBOR_FAIL();
787 }
788
789 return true;
790 }
791
792
793 bool zcbor_any_skip(zcbor_state_t *state, void *result)
794 {
795 zcbor_assert_state(result == NULL,
796 "'any' type cannot be returned, only skipped.\r\n");
797
798 INITIAL_CHECKS();
799 zcbor_major_type_t major_type = MAJOR_TYPE(*state->payload);
800 uint8_t additional = ADDITIONAL(*state->payload);
801 uint_fast32_t value;
802 uint_fast32_t num_decode;
803 uint_fast32_t temp_elem_count;
804 uint_fast32_t elem_count_bak = state->elem_count;
805 uint8_t const *payload_bak = state->payload;
806 uint64_t tag_dummy;
807
808 payload_bak = state->payload;
809
810 if (!zcbor_multi_decode(0, ZCBOR_LARGE_ELEM_COUNT, &num_decode,
811 (zcbor_decoder_t *)zcbor_tag_decode, state,
812 (void *)&tag_dummy, 0)) {
813 state->elem_count = elem_count_bak;
814 state->payload = payload_bak;
815 ZCBOR_FAIL();
816 }
817
818 if ((major_type == ZCBOR_MAJOR_TYPE_MAP) || (major_type == ZCBOR_MAJOR_TYPE_LIST)) {
819 if (additional == ZCBOR_VALUE_IS_INDEFINITE_LENGTH) {
820 ZCBOR_ERR_IF(state->elem_count == 0, ZCBOR_ERR_LOW_ELEM_COUNT);
821 state->payload++;
822 state->elem_count--;
823 temp_elem_count = state->elem_count;
824 payload_bak = state->payload;
825 state->elem_count = ZCBOR_LARGE_ELEM_COUNT;
826 if (!zcbor_multi_decode(0, ZCBOR_LARGE_ELEM_COUNT, &num_decode,
827 (zcbor_decoder_t *)zcbor_any_skip, state,
828 NULL, 0)
829 || (state->payload >= state->payload_end)
830 || !(*(state->payload++) == 0xFF)) {
831 state->elem_count = elem_count_bak;
832 state->payload = payload_bak;
833 ZCBOR_FAIL();
834 }
835 state->elem_count = temp_elem_count;
836 return true;
837 }
838 }
839
840 if (!value_extract(state, &value, sizeof(value))) {
841 /* Can happen because of elem_count (or payload_end) */
842 ZCBOR_FAIL();
843 }
844
845 switch (major_type) {
846 case ZCBOR_MAJOR_TYPE_BSTR:
847 case ZCBOR_MAJOR_TYPE_TSTR:
848 /* 'value' is the length of the BSTR or TSTR */
849 if (value > (state->payload_end - state->payload)) {
850 ZCBOR_ERR(ZCBOR_ERR_NO_PAYLOAD);
851 }
852 (state->payload) += value;
853 break;
854 case ZCBOR_MAJOR_TYPE_MAP:
855 value *= 2; /* Because all members have a key. */
856 /* Fallthrough */
857 case ZCBOR_MAJOR_TYPE_LIST:
858 temp_elem_count = state->elem_count;
859 state->elem_count = value;
860 if (!zcbor_multi_decode(value, value, &num_decode,
861 (zcbor_decoder_t *)zcbor_any_skip, state,
862 NULL, 0)) {
863 state->elem_count = elem_count_bak;
864 state->payload = payload_bak;
865 ZCBOR_FAIL();
866 }
867 state->elem_count = temp_elem_count;
868 break;
869 default:
870 /* Do nothing */
871 break;
872 }
873
874 return true;
875 }
876
877
878 bool zcbor_tag_decode(zcbor_state_t *state, uint32_t *result)
879 {
880 INITIAL_CHECKS_WITH_TYPE(ZCBOR_MAJOR_TYPE_TAG);
881
882 if (!value_extract(state, result, sizeof(*result))) {
883 ZCBOR_FAIL();
884 }
885 state->elem_count++;
886 return true;
887 }
888
889
890 bool zcbor_tag_expect(zcbor_state_t *state, uint32_t result)
891 {
892 uint32_t tag_val;
893
894 if (!zcbor_tag_decode(state, &tag_val)) {
895 ZCBOR_FAIL();
896 }
897 if (tag_val != result) {
898 ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
899 }
900 return true;
901 }
902
903
904 bool zcbor_multi_decode(uint_fast32_t min_decode,
905 uint_fast32_t max_decode,
906 uint_fast32_t *num_decode,
907 zcbor_decoder_t decoder,
908 zcbor_state_t *state,
909 void *result,
910 uint_fast32_t result_len)
911 {
912 ZCBOR_CHECK_ERROR();
913 for (uint_fast32_t i = 0; i < max_decode; i++) {
914 uint8_t const *payload_bak = state->payload;
915 uint_fast32_t elem_count_bak = state->elem_count;
916
917 if (!decoder(state,
918 (uint8_t *)result + i*result_len)) {
919 *num_decode = i;
920 state->payload = payload_bak;
921 state->elem_count = elem_count_bak;
922 ZCBOR_ERR_IF(i < min_decode, ZCBOR_ERR_ITERATIONS);
923 zcbor_print("Found %" PRIuFAST32 " elements.\r\n", i);
924 return true;
925 }
926 }
927 zcbor_print("Found %" PRIuFAST32 " elements.\r\n", max_decode);
928 *num_decode = max_decode;
929 return true;
930 }
931
932
933 bool zcbor_present_decode(uint_fast32_t *present,
934 zcbor_decoder_t decoder,
935 zcbor_state_t *state,
936 void *result)
937 {
938 uint_fast32_t num_decode;
939 bool retval = zcbor_multi_decode(0, 1, &num_decode, decoder, state, result, 0);
940
941 zcbor_assert_state(retval, "zcbor_multi_decode should not fail with these parameters.\r\n");
942
943 *present = num_decode;
944 return retval;
945 }
946
947
948 void zcbor_new_decode_state(zcbor_state_t *state_array, uint_fast32_t n_states,
949 const uint8_t *payload, size_t payload_len, uint_fast32_t elem_count)
950 {
951 zcbor_new_state(state_array, n_states, payload, payload_len, elem_count);
952 }
953