Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2020 Nordic Semiconductor ASA
3 : : *
4 : : * SPDX-License-Identifier: Apache-2.0
5 : : */
6 : :
7 : : #include <stdint.h>
8 : : #include <stdbool.h>
9 : : #include <stddef.h>
10 : : #include <string.h>
11 : : #include <inttypes.h>
12 : : #include "zcbor_decode.h"
13 : : #include "zcbor_common.h"
14 : : #include "zcbor_print.h"
15 : :
16 : :
17 : : /** Return value length from additional value.
18 : : */
19 : 156 : static size_t additional_len(uint8_t additional)
20 : : {
21 [ + + ]: 156 : if (additional <= ZCBOR_VALUE_IN_HEADER) {
22 : : return 0;
23 [ + - ]: 87 : } else if (ZCBOR_VALUE_IS_1_BYTE <= additional && additional <= ZCBOR_VALUE_IS_8_BYTES) {
24 : : /* 24 => 1
25 : : * 25 => 2
26 : : * 26 => 4
27 : : * 27 => 8
28 : : */
29 : 87 : return 1U << (additional - ZCBOR_VALUE_IS_1_BYTE);
30 : : }
31 : : return 0xF;
32 : : }
33 : :
34 : :
35 : 421 : static bool initial_checks(zcbor_state_t *state)
36 : : {
37 : 421 : ZCBOR_CHECK_ERROR();
38 [ + + ]: 421 : ZCBOR_CHECK_PAYLOAD();
39 : : return true;
40 : : }
41 : :
42 : :
43 : 238 : static bool type_check(zcbor_state_t *state, zcbor_major_type_t exp_major_type)
44 : : {
45 [ + + ]: 238 : if (!initial_checks(state)) {
46 : 165 : ZCBOR_FAIL();
47 : : }
48 : 165 : zcbor_major_type_t major_type = ZCBOR_MAJOR_TYPE(*state->payload);
49 : :
50 [ + + ]: 165 : if (major_type != exp_major_type) {
51 : 35 : ZCBOR_ERR(ZCBOR_ERR_WRONG_TYPE);
52 : : }
53 : : return true;
54 : : }
55 : :
56 : :
57 : : #define INITIAL_CHECKS() \
58 : : do {\
59 : : if (!initial_checks(state)) { \
60 : : ZCBOR_FAIL(); \
61 : : } \
62 : : } while(0)
63 : :
64 : : #define INITIAL_CHECKS_WITH_TYPE(exp_major_type) \
65 : : do {\
66 : : if (!type_check(state, exp_major_type)) { \
67 : : ZCBOR_FAIL(); \
68 : : } \
69 : : } while(0)
70 : :
71 : 48 : static void err_restore(zcbor_state_t *state, int err)
72 : : {
73 : 48 : state->payload = state->payload_bak;
74 : 48 : state->elem_count++;
75 : 48 : zcbor_error(state, err);
76 : 48 : }
77 : :
78 : : #define ERR_RESTORE(err) \
79 : : do { \
80 : : err_restore(state, err); \
81 : : ZCBOR_FAIL(); \
82 : : } while(0)
83 : :
84 : : #define FAIL_RESTORE() \
85 : : do { \
86 : : state->payload = state->payload_bak; \
87 : : state->elem_count++; \
88 : : ZCBOR_FAIL(); \
89 : : } while(0)
90 : :
91 : : #define PRINT_FUNC() zcbor_log("%s ", __func__);
92 : :
93 : :
94 : 87 : static void endian_copy(uint8_t *dst, const uint8_t *src, size_t src_len)
95 : : {
96 : : #ifdef ZCBOR_BIG_ENDIAN
97 : : memcpy(dst, src, src_len);
98 : : #else
99 [ + + ]: 182 : for (size_t i = 0; i < src_len; i++) {
100 : 95 : dst[i] = src[src_len - 1 - i];
101 : : }
102 : : #endif /* ZCBOR_BIG_ENDIAN */
103 : 87 : }
104 : :
105 : :
106 : : /** Get a single value.
107 : : *
108 : : * @details @p ppayload must point to the header byte. This function will
109 : : * retrieve the value (either from within the additional info, or from
110 : : * the subsequent bytes) and return it in the result. The result can
111 : : * have arbitrary length.
112 : : *
113 : : * The function will also validate
114 : : * - Min/max constraints on the value.
115 : : * - That @p payload doesn't overrun past @p payload_end.
116 : : * - That @p elem_count has not been exhausted.
117 : : *
118 : : * @p ppayload and @p elem_count are updated if the function
119 : : * succeeds. If not, they are left unchanged.
120 : : *
121 : : * CBOR values are always big-endian, so this function converts from
122 : : * big to little-endian if necessary (@ref ZCBOR_BIG_ENDIAN).
123 : : */
124 : 156 : static bool value_extract(zcbor_state_t *state,
125 : : void *const result, size_t result_len)
126 : : {
127 : 156 : zcbor_trace(state, "value_extract");
128 : 156 : zcbor_assert_state(result_len != 0, "0-length result not supported.\r\n");
129 : 156 : zcbor_assert_state(result_len <= 8, "result sizes above 8 bytes not supported.\r\n");
130 : 156 : zcbor_assert_state(result != NULL, "result cannot be NULL.\r\n");
131 : :
132 [ + - ]: 156 : INITIAL_CHECKS();
133 [ - + ]: 156 : ZCBOR_ERR_IF((state->elem_count == 0), ZCBOR_ERR_LOW_ELEM_COUNT);
134 : :
135 : 156 : uint8_t additional = ZCBOR_ADDITIONAL(*state->payload);
136 : 156 : size_t len = additional_len(additional);
137 : 156 : uint8_t *result_offs = (uint8_t *)result + ZCBOR_ECPY_OFFS(result_len, MAX(1, len));
138 : :
139 [ - + ]: 156 : ZCBOR_ERR_IF(additional > ZCBOR_VALUE_IS_8_BYTES, ZCBOR_ERR_ADDITIONAL_INVAL);
140 [ - + ]: 156 : ZCBOR_ERR_IF(len > result_len, ZCBOR_ERR_INT_SIZE);
141 [ - + ]: 156 : ZCBOR_ERR_IF((state->payload + len + 1) > state->payload_end,
142 : : ZCBOR_ERR_NO_PAYLOAD);
143 : :
144 [ + + ]: 156 : memset(result, 0, result_len);
145 : :
146 [ + + ]: 156 : if (len == 0) {
147 : 69 : *result_offs = additional;
148 : : } else {
149 : 87 : endian_copy(result_offs, state->payload + 1, len);
150 : :
151 [ + - + - ]: 87 : if (ZCBOR_ENFORCE_CANONICAL(state)) {
152 [ - + ]: 87 : ZCBOR_ERR_IF((zcbor_header_len_ptr(result, result_len) != (len + 1)),
153 : : ZCBOR_ERR_INVALID_VALUE_ENCODING);
154 : : }
155 : : }
156 : :
157 : 156 : state->payload_bak = state->payload;
158 : 156 : (state->payload) += len + 1;
159 : 156 : (state->elem_count)--;
160 : 156 : return true;
161 : : }
162 : :
163 : :
164 : 27 : bool zcbor_int_decode(zcbor_state_t *state, void *result, size_t result_size)
165 : : {
166 : 27 : PRINT_FUNC();
167 [ + - ]: 27 : INITIAL_CHECKS();
168 : 27 : zcbor_major_type_t major_type = ZCBOR_MAJOR_TYPE(*state->payload);
169 : 27 : uint8_t *result_uint8 = (uint8_t *)result;
170 : 27 : int8_t *result_int8 = (int8_t *)result;
171 : :
172 [ + + ]: 27 : if (major_type != ZCBOR_MAJOR_TYPE_PINT
173 : : && major_type != ZCBOR_MAJOR_TYPE_NINT) {
174 : : /* Value to be read doesn't have the right type. */
175 : 1 : ZCBOR_ERR(ZCBOR_ERR_WRONG_TYPE);
176 : : }
177 : :
178 [ + - ]: 26 : if (!value_extract(state, result, result_size)) {
179 : 26 : ZCBOR_FAIL();
180 : : }
181 : :
182 : : #ifdef ZCBOR_BIG_ENDIAN
183 : : if (result_int8[0] < 0) {
184 : : #else
185 [ - + ]: 26 : if (result_int8[result_size - 1] < 0) {
186 : : #endif
187 : : /* Value is too large to fit in a signed integer. */
188 : 0 : ERR_RESTORE(ZCBOR_ERR_INT_SIZE);
189 : : }
190 : :
191 [ + + ]: 26 : if (major_type == ZCBOR_MAJOR_TYPE_NINT) {
192 : : /* Convert from CBOR's representation by flipping all bits. */
193 [ + + ]: 100 : for (unsigned int i = 0; i < result_size; i++) {
194 : 80 : result_uint8[i] = (uint8_t)~result_uint8[i];
195 : : }
196 : : }
197 : :
198 : : return true;
199 : : }
200 : :
201 : :
202 : 27 : bool zcbor_int32_decode(zcbor_state_t *state, int32_t *result)
203 : : {
204 : 27 : PRINT_FUNC();
205 : 27 : return zcbor_int_decode(state, result, sizeof(*result));
206 : : }
207 : :
208 : :
209 : 0 : bool zcbor_int64_decode(zcbor_state_t *state, int64_t *result)
210 : : {
211 : 0 : PRINT_FUNC();
212 : 0 : return zcbor_int_decode(state, result, sizeof(*result));
213 : : }
214 : :
215 : :
216 : 162 : bool zcbor_uint_decode(zcbor_state_t *state, void *result, size_t result_size)
217 : : {
218 : 162 : PRINT_FUNC();
219 [ + + ]: 162 : INITIAL_CHECKS_WITH_TYPE(ZCBOR_MAJOR_TYPE_PINT);
220 : :
221 [ - + ]: 66 : if (!value_extract(state, result, result_size)) {
222 : 0 : zcbor_log("uint with size %zu failed.\r\n", result_size);
223 : 0 : ZCBOR_FAIL();
224 : : }
225 : : return true;
226 : : }
227 : :
228 : :
229 : 0 : bool zcbor_uint32_decode(zcbor_state_t *state, uint32_t *result)
230 : : {
231 : 0 : PRINT_FUNC();
232 : 0 : return zcbor_uint_decode(state, result, sizeof(*result));
233 : : }
234 : :
235 : :
236 : 0 : bool zcbor_int32_expect_union(zcbor_state_t *state, int32_t result)
237 : : {
238 : 0 : PRINT_FUNC();
239 [ # # ]: 0 : if (!zcbor_union_elem_code(state)) {
240 : 0 : ZCBOR_FAIL();
241 : : }
242 : 0 : return zcbor_int32_expect(state, result);
243 : : }
244 : :
245 : :
246 : 0 : bool zcbor_int64_expect_union(zcbor_state_t *state, int64_t result)
247 : : {
248 : 0 : PRINT_FUNC();
249 [ # # ]: 0 : if (!zcbor_union_elem_code(state)) {
250 : 0 : ZCBOR_FAIL();
251 : : }
252 : 0 : return zcbor_int64_expect(state, result);
253 : : }
254 : :
255 : :
256 : 0 : bool zcbor_uint32_expect_union(zcbor_state_t *state, uint32_t result)
257 : : {
258 : 0 : PRINT_FUNC();
259 [ # # ]: 0 : if (!zcbor_union_elem_code(state)) {
260 : 0 : ZCBOR_FAIL();
261 : : }
262 : 0 : return zcbor_uint32_expect(state, result);
263 : : }
264 : :
265 : :
266 : 0 : bool zcbor_uint64_expect_union(zcbor_state_t *state, uint64_t result)
267 : : {
268 : 0 : PRINT_FUNC();
269 [ # # ]: 0 : if (!zcbor_union_elem_code(state)) {
270 : 0 : ZCBOR_FAIL();
271 : : }
272 : 0 : return zcbor_uint64_expect(state, result);
273 : : }
274 : :
275 : :
276 : 0 : bool zcbor_int32_expect(zcbor_state_t *state, int32_t expected)
277 : : {
278 : 0 : PRINT_FUNC();
279 : 0 : return zcbor_int64_expect(state, expected);
280 : : }
281 : :
282 : :
283 : 0 : bool zcbor_int32_pexpect(zcbor_state_t *state, int32_t *expected)
284 : : {
285 : 0 : PRINT_FUNC();
286 : 0 : return zcbor_int32_expect(state, *expected);
287 : : }
288 : :
289 : :
290 : 0 : bool zcbor_int64_expect(zcbor_state_t *state, int64_t expected)
291 : : {
292 : 0 : PRINT_FUNC();
293 : 0 : int64_t actual;
294 : :
295 [ # # ]: 0 : if (!zcbor_int64_decode(state, &actual)) {
296 : 0 : ZCBOR_FAIL();
297 : : }
298 : :
299 [ # # ]: 0 : if (actual != expected) {
300 : 0 : zcbor_log("%" PRIi64 " != %" PRIi64 "\r\n", actual, expected);
301 : 0 : ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
302 : : }
303 : : return true;
304 : : }
305 : :
306 : :
307 : 0 : bool zcbor_int64_pexpect(zcbor_state_t *state, int64_t *expected)
308 : : {
309 : 0 : PRINT_FUNC();
310 : 0 : return zcbor_int64_expect(state, *expected);
311 : : }
312 : :
313 : :
314 : 162 : bool zcbor_uint64_decode(zcbor_state_t *state, uint64_t *result)
315 : : {
316 : 162 : PRINT_FUNC();
317 : 162 : return zcbor_uint_decode(state, result, sizeof(*result));
318 : : }
319 : :
320 : :
321 : : #ifdef ZCBOR_SUPPORTS_SIZE_T
322 : 0 : bool zcbor_size_decode(zcbor_state_t *state, size_t *result)
323 : : {
324 : 0 : PRINT_FUNC();
325 : 0 : return zcbor_uint_decode(state, result, sizeof(*result));
326 : : }
327 : : #endif
328 : :
329 : :
330 : 162 : bool zcbor_uint32_expect(zcbor_state_t *state, uint32_t expected)
331 : : {
332 : 162 : PRINT_FUNC();
333 : 162 : return zcbor_uint64_expect(state, expected);
334 : : }
335 : :
336 : :
337 : 0 : bool zcbor_uint32_pexpect(zcbor_state_t *state, uint32_t *expected)
338 : : {
339 : 0 : PRINT_FUNC();
340 : 0 : return zcbor_uint32_expect(state, *expected);
341 : : }
342 : :
343 : :
344 : 162 : bool zcbor_uint64_expect(zcbor_state_t *state, uint64_t expected)
345 : : {
346 : 162 : PRINT_FUNC();
347 : 162 : uint64_t actual;
348 : :
349 [ + + ]: 162 : if (!zcbor_uint64_decode(state, &actual)) {
350 : 66 : ZCBOR_FAIL();
351 : : }
352 [ + + ]: 66 : if (actual != expected) {
353 : 48 : zcbor_log("%" PRIu64 " != %" PRIu64 "\r\n", actual, expected);
354 : 48 : ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
355 : : }
356 : : return true;
357 : : }
358 : :
359 : :
360 : 0 : bool zcbor_uint64_pexpect(zcbor_state_t *state, uint64_t *expected)
361 : : {
362 : 0 : PRINT_FUNC();
363 : 0 : return zcbor_uint64_expect(state, *expected);
364 : : }
365 : :
366 : :
367 : : #ifdef ZCBOR_SUPPORTS_SIZE_T
368 : 0 : bool zcbor_size_expect(zcbor_state_t *state, size_t expected)
369 : : {
370 : 0 : PRINT_FUNC();
371 : 0 : return zcbor_uint64_expect(state, expected);
372 : : }
373 : :
374 : :
375 : 0 : bool zcbor_size_pexpect(zcbor_state_t *state, size_t *expected)
376 : : {
377 : 0 : PRINT_FUNC();
378 : 0 : return zcbor_size_expect(state, *expected);
379 : : }
380 : : #endif
381 : :
382 : :
383 : 43 : static bool str_start_decode(zcbor_state_t *state,
384 : : struct zcbor_string *result, zcbor_major_type_t exp_major_type)
385 : : {
386 [ + + ]: 43 : INITIAL_CHECKS_WITH_TYPE(exp_major_type);
387 : :
388 [ + - ]: 34 : if (!value_extract(state, &result->len, sizeof(result->len))) {
389 : 34 : ZCBOR_FAIL();
390 : : }
391 : :
392 : 34 : result->value = state->payload;
393 : 34 : return true;
394 : : }
395 : :
396 : 43 : static bool str_start_decode_with_overflow_check(zcbor_state_t *state,
397 : : struct zcbor_string *result, zcbor_major_type_t exp_major_type)
398 : : {
399 : 43 : bool res = str_start_decode(state, result, exp_major_type);
400 : :
401 [ + + ]: 43 : if (!res) {
402 : 34 : ZCBOR_FAIL();
403 : : }
404 : :
405 : : /* Casting to size_t is safe since str_start_decode() checks that
406 : : * payload_end is bigger that payload. */
407 [ - + ]: 34 : if (result->len > (size_t)(state->payload_end - state->payload)) {
408 : : zcbor_log("error: 0x%zu > 0x%zu\r\n",
409 : : result->len,
410 : 0 : (state->payload_end - state->payload));
411 : 0 : ERR_RESTORE(ZCBOR_ERR_NO_PAYLOAD);
412 : : }
413 : :
414 : : return true;
415 : : }
416 : :
417 : :
418 : 0 : bool zcbor_bstr_start_decode(zcbor_state_t *state, struct zcbor_string *result)
419 : : {
420 : 0 : PRINT_FUNC();
421 : 0 : struct zcbor_string dummy;
422 [ # # ]: 0 : if (result == NULL) {
423 : 0 : result = &dummy;
424 : : }
425 : :
426 [ # # ]: 0 : if(!str_start_decode_with_overflow_check(state, result, ZCBOR_MAJOR_TYPE_BSTR)) {
427 : 0 : ZCBOR_FAIL();
428 : : }
429 : :
430 [ # # ]: 0 : if (!zcbor_new_backup(state, ZCBOR_MAX_ELEM_COUNT)) {
431 : 0 : FAIL_RESTORE();
432 : : }
433 : :
434 : 0 : state->payload_end = result->value + result->len;
435 : 0 : return true;
436 : : }
437 : :
438 : :
439 : 0 : bool zcbor_bstr_end_decode(zcbor_state_t *state)
440 : : {
441 [ # # ]: 0 : ZCBOR_ERR_IF(state->payload != state->payload_end, ZCBOR_ERR_PAYLOAD_NOT_CONSUMED);
442 : :
443 [ # # ]: 0 : if (!zcbor_process_backup(state,
444 : : ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME | ZCBOR_FLAG_KEEP_PAYLOAD,
445 : : ZCBOR_MAX_ELEM_COUNT)) {
446 : 0 : ZCBOR_FAIL();
447 : : }
448 : :
449 : : return true;
450 : : }
451 : :
452 : :
453 : 0 : static void partition_fragment(const zcbor_state_t *state,
454 : : struct zcbor_string_fragment *result)
455 : : {
456 : 0 : result->fragment.len = MIN(result->fragment.len,
457 : : (size_t)state->payload_end - (size_t)state->payload);
458 : 0 : }
459 : :
460 : :
461 : 0 : static bool start_decode_fragment(zcbor_state_t *state,
462 : : struct zcbor_string_fragment *result,
463 : : zcbor_major_type_t exp_major_type)
464 : : {
465 : 0 : PRINT_FUNC();
466 [ # # ]: 0 : if(!str_start_decode(state, &result->fragment, exp_major_type)) {
467 : 0 : ZCBOR_FAIL();
468 : : }
469 : :
470 : 0 : result->offset = 0;
471 : 0 : result->total_len = result->fragment.len;
472 : 0 : partition_fragment(state, result);
473 : 0 : state->payload_end = state->payload + result->fragment.len;
474 : :
475 : 0 : return true;
476 : : }
477 : :
478 : 0 : bool zcbor_bstr_start_decode_fragment(zcbor_state_t *state,
479 : : struct zcbor_string_fragment *result)
480 : : {
481 : 0 : PRINT_FUNC();
482 [ # # ]: 0 : if (!start_decode_fragment(state, result, ZCBOR_MAJOR_TYPE_BSTR)) {
483 : 0 : ZCBOR_FAIL();
484 : : }
485 [ # # ]: 0 : if (!zcbor_new_backup(state, ZCBOR_MAX_ELEM_COUNT)) {
486 : 0 : FAIL_RESTORE();
487 : : }
488 : : return true;
489 : : }
490 : :
491 : :
492 : 0 : void zcbor_next_fragment(zcbor_state_t *state,
493 : : struct zcbor_string_fragment *prev_fragment,
494 : : struct zcbor_string_fragment *result)
495 : : {
496 : 0 : memcpy(result, prev_fragment, sizeof(*result));
497 : 0 : result->fragment.value = state->payload_mut;
498 : 0 : result->offset += prev_fragment->fragment.len;
499 : 0 : result->fragment.len = result->total_len - result->offset;
500 : :
501 : 0 : partition_fragment(state, result);
502 : 0 : zcbor_log("New fragment length %zu\r\n", result->fragment.len);
503 : :
504 : 0 : state->payload += result->fragment.len;
505 : 0 : }
506 : :
507 : :
508 : 0 : void zcbor_bstr_next_fragment(zcbor_state_t *state,
509 : : struct zcbor_string_fragment *prev_fragment,
510 : : struct zcbor_string_fragment *result)
511 : : {
512 : 0 : memcpy(result, prev_fragment, sizeof(*result));
513 : 0 : result->fragment.value = state->payload_mut;
514 : 0 : result->offset += prev_fragment->fragment.len;
515 : 0 : result->fragment.len = result->total_len - result->offset;
516 : :
517 : 0 : partition_fragment(state, result);
518 : 0 : zcbor_log("fragment length %zu\r\n", result->fragment.len);
519 : 0 : state->payload_end = state->payload + result->fragment.len;
520 : 0 : }
521 : :
522 : :
523 : 0 : bool zcbor_is_last_fragment(const struct zcbor_string_fragment *fragment)
524 : : {
525 : 0 : return (fragment->total_len == (fragment->offset + fragment->fragment.len));
526 : : }
527 : :
528 : :
529 : 43 : static bool str_decode(zcbor_state_t *state, struct zcbor_string *result,
530 : : zcbor_major_type_t exp_major_type)
531 : : {
532 [ + + ]: 43 : if (!str_start_decode_with_overflow_check(state, result, exp_major_type)) {
533 : 34 : ZCBOR_FAIL();
534 : : }
535 : :
536 : 34 : state->payload += result->len;
537 : 34 : return true;
538 : : }
539 : :
540 : :
541 : 0 : static bool str_decode_fragment(zcbor_state_t *state, struct zcbor_string_fragment *result,
542 : : zcbor_major_type_t exp_major_type)
543 : : {
544 [ # # ]: 0 : if (!start_decode_fragment(state, result, exp_major_type)) {
545 : 0 : ZCBOR_FAIL();
546 : : }
547 : :
548 : 0 : (state->payload) += result->fragment.len;
549 : 0 : return true;
550 : : }
551 : :
552 : :
553 : 0 : static bool str_expect(zcbor_state_t *state, struct zcbor_string *result,
554 : : zcbor_major_type_t exp_major_type)
555 : : {
556 : 0 : struct zcbor_string tmp_result;
557 : :
558 [ # # ]: 0 : if (!str_decode(state, &tmp_result, exp_major_type)) {
559 : 0 : ZCBOR_FAIL();
560 : : }
561 [ # # ]: 0 : if (!zcbor_compare_strings(&tmp_result, result)) {
562 : 0 : ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
563 : : }
564 : : return true;
565 : : }
566 : :
567 : :
568 : 43 : bool zcbor_bstr_decode(zcbor_state_t *state, struct zcbor_string *result)
569 : : {
570 : 43 : PRINT_FUNC();
571 : 43 : return str_decode(state, result, ZCBOR_MAJOR_TYPE_BSTR);
572 : : }
573 : :
574 : :
575 : 0 : bool zcbor_bstr_decode_fragment(zcbor_state_t *state, struct zcbor_string_fragment *result)
576 : : {
577 : 0 : PRINT_FUNC();
578 : 0 : return str_decode_fragment(state, result, ZCBOR_MAJOR_TYPE_BSTR);
579 : : }
580 : :
581 : :
582 : 0 : bool zcbor_bstr_expect(zcbor_state_t *state, struct zcbor_string *expected)
583 : : {
584 : 0 : PRINT_FUNC();
585 : 0 : return str_expect(state, expected, ZCBOR_MAJOR_TYPE_BSTR);
586 : : }
587 : :
588 : :
589 : 0 : bool zcbor_tstr_decode(zcbor_state_t *state, struct zcbor_string *result)
590 : : {
591 : 0 : PRINT_FUNC();
592 : 0 : return str_decode(state, result, ZCBOR_MAJOR_TYPE_TSTR);
593 : : }
594 : :
595 : :
596 : 0 : bool zcbor_tstr_decode_fragment(zcbor_state_t *state, struct zcbor_string_fragment *result)
597 : : {
598 : 0 : PRINT_FUNC();
599 : 0 : return str_decode_fragment(state, result, ZCBOR_MAJOR_TYPE_TSTR);
600 : : }
601 : :
602 : :
603 : 0 : bool zcbor_tstr_expect(zcbor_state_t *state, struct zcbor_string *expected)
604 : : {
605 : 0 : PRINT_FUNC();
606 : 0 : return str_expect(state, expected, ZCBOR_MAJOR_TYPE_TSTR);
607 : : }
608 : :
609 : :
610 : 0 : bool zcbor_bstr_expect_ptr(zcbor_state_t *state, char const *ptr, size_t len)
611 : : {
612 : 0 : PRINT_FUNC();
613 : 0 : struct zcbor_string zs = { .value = (const uint8_t *)ptr, .len = len };
614 : :
615 : 0 : return zcbor_bstr_expect(state, &zs);
616 : : }
617 : :
618 : :
619 : 0 : bool zcbor_tstr_expect_ptr(zcbor_state_t *state, char const *ptr, size_t len)
620 : : {
621 : 0 : PRINT_FUNC();
622 : 0 : struct zcbor_string zs = { .value = (const uint8_t *)ptr, .len = len };
623 : :
624 : 0 : return zcbor_tstr_expect(state, &zs);
625 : : }
626 : :
627 : :
628 : 0 : bool zcbor_bstr_expect_term(zcbor_state_t *state, char const *string, size_t maxlen)
629 : : {
630 : 0 : PRINT_FUNC();
631 : 0 : return zcbor_bstr_expect_ptr(state, string, strnlen(string, maxlen));
632 : : }
633 : :
634 : :
635 : 0 : bool zcbor_tstr_expect_term(zcbor_state_t *state, char const *string, size_t maxlen)
636 : : {
637 : 0 : PRINT_FUNC();
638 : 0 : return zcbor_tstr_expect_ptr(state, string, strnlen(string, maxlen));
639 : : }
640 : :
641 : :
642 : 33 : static bool list_map_start_decode(zcbor_state_t *state,
643 : : zcbor_major_type_t exp_major_type)
644 : : {
645 : 33 : size_t new_elem_count;
646 : 33 : bool indefinite_length_array = false;
647 : :
648 [ + + ]: 33 : INITIAL_CHECKS_WITH_TYPE(exp_major_type);
649 : :
650 [ - + ]: 30 : if (ZCBOR_ADDITIONAL(*state->payload) == ZCBOR_VALUE_IS_INDEFINITE_LENGTH) {
651 : : /* Indefinite length array. */
652 [ # # # # ]: 0 : ZCBOR_ERR_IF(ZCBOR_ENFORCE_CANONICAL(state),
653 : : ZCBOR_ERR_INVALID_VALUE_ENCODING);
654 : 0 : new_elem_count = ZCBOR_LARGE_ELEM_COUNT;
655 [ # # ]: 0 : ZCBOR_ERR_IF(state->elem_count == 0, ZCBOR_ERR_LOW_ELEM_COUNT);
656 : 0 : indefinite_length_array = true;
657 : 0 : state->payload_bak = state->payload++;
658 : 0 : state->elem_count--;
659 : : } else {
660 [ + - ]: 30 : if (!value_extract(state, &new_elem_count, sizeof(new_elem_count))) {
661 : 30 : ZCBOR_FAIL();
662 : : }
663 : : }
664 : :
665 [ - + ]: 30 : if (!zcbor_new_backup(state, new_elem_count)) {
666 : 0 : FAIL_RESTORE();
667 : : }
668 : :
669 : 30 : state->decode_state.indefinite_length_array = indefinite_length_array;
670 : :
671 : 30 : return true;
672 : : }
673 : :
674 : :
675 : 15 : bool zcbor_list_start_decode(zcbor_state_t *state)
676 : : {
677 : 15 : PRINT_FUNC();
678 : 15 : return list_map_start_decode(state, ZCBOR_MAJOR_TYPE_LIST);
679 : : }
680 : :
681 : :
682 : 18 : bool zcbor_map_start_decode(zcbor_state_t *state)
683 : : {
684 : 18 : PRINT_FUNC();
685 : 18 : bool ret = list_map_start_decode(state, ZCBOR_MAJOR_TYPE_MAP);
686 : :
687 [ + - + - ]: 18 : if (ret && !state->decode_state.indefinite_length_array) {
688 [ - + ]: 18 : if (state->elem_count >= (ZCBOR_MAX_ELEM_COUNT / 2)) {
689 : : /* The new elem_count is too large. */
690 : 0 : ERR_RESTORE(ZCBOR_ERR_INT_SIZE);
691 : : }
692 : 18 : state->elem_count *= 2;
693 : : }
694 : : return ret;
695 : : }
696 : :
697 : :
698 : 0 : bool zcbor_array_at_end(zcbor_state_t *state)
699 : : {
700 : 0 : const bool indefinite_length_array = state->decode_state.indefinite_length_array;
701 : :
702 [ # # ]: 0 : return ((!indefinite_length_array && (state->elem_count == 0))
703 [ # # # # ]: 0 : || (indefinite_length_array
704 [ # # ]: 0 : && (state->payload < state->payload_end)
705 [ # # ]: 0 : && (*state->payload == 0xFF)));
706 : : }
707 : :
708 : :
709 : : static size_t update_map_elem_count(zcbor_state_t *state, size_t elem_count);
710 : : #ifdef ZCBOR_MAP_SMART_SEARCH
711 : : static bool allocate_map_flags(zcbor_state_t *state, size_t elem_count);
712 : : #endif
713 : :
714 : :
715 : 0 : bool zcbor_unordered_map_start_decode(zcbor_state_t *state)
716 : : {
717 : 0 : PRINT_FUNC();
718 [ # # ]: 0 : ZCBOR_FAIL_IF(!zcbor_map_start_decode(state));
719 : :
720 : : #ifdef ZCBOR_MAP_SMART_SEARCH
721 : : state->decode_state.map_search_elem_state
722 : : += zcbor_flags_to_bytes(state->decode_state.map_elem_count);
723 : : #else
724 : 0 : state->decode_state.map_elems_processed = 0;
725 : : #endif
726 : 0 : state->decode_state.map_elem_count = 0;
727 : 0 : state->decode_state.counting_map_elems = state->decode_state.indefinite_length_array;
728 : :
729 [ # # ]: 0 : if (!state->decode_state.counting_map_elems) {
730 : 0 : size_t old_flags = update_map_elem_count(state, state->elem_count);
731 : : #ifdef ZCBOR_MAP_SMART_SEARCH
732 : : ZCBOR_FAIL_IF(!allocate_map_flags(state, old_flags));
733 : : #endif
734 : : (void)old_flags;
735 : : }
736 : :
737 : : return true;
738 : : }
739 : :
740 : :
741 : : /** Return the max (starting) elem_count of the current container.
742 : : *
743 : : * Should only be used for unordered maps (started with @ref zcbor_unordered_map_start_decode)
744 : : */
745 : 0 : static size_t zcbor_current_max_elem_count(zcbor_state_t *state)
746 : : {
747 : 0 : return (state->decode_state.indefinite_length_array ? \
748 [ # # ]: 0 : ZCBOR_LARGE_ELEM_COUNT : state->decode_state.map_elem_count * 2);
749 : : }
750 : :
751 : :
752 : 0 : static bool map_restart(zcbor_state_t *state)
753 : : {
754 [ # # ]: 0 : if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_KEEP_DECODE_STATE,
755 : : ZCBOR_MAX_ELEM_COUNT)) {
756 : 0 : ZCBOR_FAIL();
757 : : }
758 : :
759 : 0 : state->elem_count = zcbor_current_max_elem_count(state);
760 : 0 : return true;
761 : : }
762 : :
763 : :
764 : : __attribute__((used))
765 : 0 : static size_t get_current_index(zcbor_state_t *state, uint32_t index_offset)
766 : : {
767 : : /* Subtract mode because for GET, you want the index you are pointing to, while for SET,
768 : : * you want the one you just processed. This only comes into play when elem_count is even. */
769 : 0 : return ((zcbor_current_max_elem_count(state) - state->elem_count - index_offset) / 2);
770 : : }
771 : :
772 : :
773 : : #ifdef ZCBOR_MAP_SMART_SEARCH
774 : : #define FLAG_MODE_GET_CURRENT 0
775 : : #define FLAG_MODE_CLEAR_CURRENT 1
776 : : #define FLAG_MODE_CLEAR_UNUSED 2
777 : :
778 : : static bool manipulate_flags(zcbor_state_t *state, uint32_t mode)
779 : : {
780 : : const size_t last_index = (state->decode_state.map_elem_count - 1);
781 : : size_t index = (mode == FLAG_MODE_CLEAR_UNUSED) ? last_index : get_current_index(state, mode);
782 : :
783 : : ZCBOR_ERR_IF((index >= state->decode_state.map_elem_count),
784 : : ZCBOR_ERR_MAP_FLAGS_NOT_AVAILABLE);
785 : : uint8_t *flag_byte = &state->decode_state.map_search_elem_state[index >> 3];
786 : : uint8_t flag_mask = (uint8_t)(1 << (index & 7));
787 : :
788 : : switch(mode) {
789 : : case FLAG_MODE_GET_CURRENT:
790 : : return (!!(*flag_byte & flag_mask));
791 : : case FLAG_MODE_CLEAR_CURRENT:
792 : : *flag_byte &= ~flag_mask;
793 : : return true;
794 : : case FLAG_MODE_CLEAR_UNUSED:
795 : : *flag_byte &= (uint8_t)((flag_mask << 1) - 1);
796 : : return true;
797 : : }
798 : : return false;
799 : : }
800 : :
801 : :
802 : : static bool should_try_key(zcbor_state_t *state)
803 : : {
804 : : return manipulate_flags(state, FLAG_MODE_GET_CURRENT);
805 : : }
806 : :
807 : :
808 : : bool zcbor_elem_processed(zcbor_state_t *state)
809 : : {
810 : : return manipulate_flags(state, FLAG_MODE_CLEAR_CURRENT);
811 : : }
812 : :
813 : :
814 : : static bool allocate_map_flags(zcbor_state_t *state, size_t old_flags)
815 : : {
816 : : size_t new_bytes = zcbor_flags_to_bytes(state->decode_state.map_elem_count);
817 : : size_t old_bytes = zcbor_flags_to_bytes(old_flags);
818 : : size_t extra_bytes = new_bytes - old_bytes;
819 : :
820 : : ZCBOR_ERR_IF(!state->constant_state, ZCBOR_ERR_CONSTANT_STATE_MISSING);
821 : : const uint8_t *flags_end = state->constant_state->map_search_elem_state_end;
822 : :
823 : : if (extra_bytes) {
824 : : if ((state->decode_state.map_search_elem_state + new_bytes) > flags_end) {
825 : : state->decode_state.map_elem_count
826 : : = 8 * (size_t)(flags_end - state->decode_state.map_search_elem_state);
827 : : ZCBOR_ERR(ZCBOR_ERR_MAP_FLAGS_NOT_AVAILABLE);
828 : : }
829 : :
830 : : memset(&state->decode_state.map_search_elem_state[new_bytes - extra_bytes], 0xFF, extra_bytes);
831 : : }
832 : : return true;
833 : : }
834 : : #else
835 : :
836 : 0 : static bool should_try_key(zcbor_state_t *state)
837 : : {
838 : 0 : return (state->decode_state.map_elems_processed < state->decode_state.map_elem_count);
839 : : }
840 : :
841 : :
842 : 0 : bool zcbor_elem_processed(zcbor_state_t *state)
843 : : {
844 [ # # ]: 0 : if (should_try_key(state)) {
845 : 0 : state->decode_state.map_elems_processed++;
846 : : }
847 : 0 : return true;
848 : : }
849 : : #endif
850 : :
851 : :
852 : 0 : static size_t update_map_elem_count(zcbor_state_t *state, size_t elem_count)
853 : : {
854 : 0 : size_t old_map_elem_count = state->decode_state.map_elem_count;
855 : :
856 : 0 : state->decode_state.map_elem_count = MAX(old_map_elem_count, elem_count / 2);
857 : 0 : return old_map_elem_count;
858 : : }
859 : :
860 : :
861 : 0 : static bool handle_map_end(zcbor_state_t *state)
862 : : {
863 : 0 : state->decode_state.counting_map_elems = false;
864 : 0 : return map_restart(state);
865 : : }
866 : :
867 : :
868 : 0 : static bool try_key(zcbor_state_t *state, void *key_result, zcbor_decoder_t key_decoder)
869 : : {
870 : 0 : uint8_t const *payload_bak2 = state->payload;
871 : 0 : size_t elem_count_bak = state->elem_count;
872 : :
873 [ # # ]: 0 : if (!key_decoder(state, (uint8_t *)key_result)) {
874 : 0 : state->payload = payload_bak2;
875 : 0 : state->elem_count = elem_count_bak;
876 : 0 : return false;
877 : : }
878 : :
879 : : zcbor_log("Found element at index %zu.\n", get_current_index(state, 1));
880 : : return true;
881 : : }
882 : :
883 : :
884 : 0 : bool zcbor_unordered_map_search(zcbor_decoder_t key_decoder, zcbor_state_t *state, void *key_result)
885 : : {
886 : 0 : PRINT_FUNC();
887 : : /* elem_count cannot be odd since the map consists of key-value-pairs.
888 : : * This might mean that this function was called while pointing at a value (instead
889 : : * of a key). */
890 [ # # ]: 0 : ZCBOR_ERR_IF(state->elem_count & 1, ZCBOR_ERR_MAP_MISALIGNED);
891 : :
892 : 0 : uint8_t const *payload_bak = state->payload;
893 : 0 : size_t elem_count = state->elem_count;
894 : :
895 : : /* Loop once through all the elements of the map. */
896 : 0 : do {
897 [ # # ]: 0 : if (zcbor_array_at_end(state)) {
898 [ # # ]: 0 : if (!handle_map_end(state)) {
899 : 0 : goto error;
900 : : }
901 : 0 : continue; /* This continue is needed so the loop stops both if elem_count is
902 : : * at the very start or the very end of the map. */
903 : : }
904 : :
905 [ # # ]: 0 : if (state->decode_state.counting_map_elems) {
906 : 0 : size_t m_elem_count = ZCBOR_LARGE_ELEM_COUNT - state->elem_count + 2;
907 : 0 : size_t old_flags = update_map_elem_count(state, m_elem_count);
908 : : #ifdef ZCBOR_MAP_SMART_SEARCH
909 : : ZCBOR_FAIL_IF(!allocate_map_flags(state, old_flags));
910 : : #endif
911 : 0 : (void)old_flags;
912 : : }
913 : :
914 [ # # # # ]: 0 : if (should_try_key(state) && try_key(state, key_result, key_decoder)) {
915 [ # # # # ]: 0 : if (!ZCBOR_MANUALLY_PROCESS_ELEM(state)) {
916 [ # # ]: 0 : ZCBOR_FAIL_IF(!zcbor_elem_processed(state));
917 : : }
918 : 0 : return true;
919 : : }
920 : :
921 : : /* Skip over both the key and the value. */
922 [ # # # # ]: 0 : if (!zcbor_any_skip(state, NULL) || !zcbor_any_skip(state, NULL)) {
923 : 0 : goto error;
924 : : }
925 [ # # ]: 0 : } while (state->elem_count != elem_count);
926 : :
927 : 0 : zcbor_error(state, ZCBOR_ERR_ELEM_NOT_FOUND);
928 : 0 : error:
929 : 0 : state->payload = payload_bak;
930 : 0 : state->elem_count = elem_count;
931 : 0 : ZCBOR_FAIL();
932 : : }
933 : :
934 : :
935 : 0 : bool zcbor_search_key_bstr_ptr(zcbor_state_t *state, char const *ptr, size_t len)
936 : : {
937 : 0 : struct zcbor_string zs = { .value = (const uint8_t *)ptr, .len = len };
938 : :
939 : 0 : return zcbor_unordered_map_search((zcbor_decoder_t *)zcbor_bstr_expect, state, &zs);
940 : : }
941 : :
942 : :
943 : 0 : bool zcbor_search_key_tstr_ptr(zcbor_state_t *state, char const *ptr, size_t len)
944 : : {
945 : 0 : struct zcbor_string zs = { .value = (const uint8_t *)ptr, .len = len };
946 : :
947 : 0 : return zcbor_unordered_map_search((zcbor_decoder_t *)zcbor_tstr_expect, state, &zs);
948 : : }
949 : :
950 : :
951 : 0 : bool zcbor_search_key_bstr_term(zcbor_state_t *state, char const *str, size_t maxlen)
952 : : {
953 : 0 : return zcbor_search_key_bstr_ptr(state, str, strnlen(str, maxlen));
954 : : }
955 : :
956 : :
957 : 0 : bool zcbor_search_key_tstr_term(zcbor_state_t *state, char const *str, size_t maxlen)
958 : : {
959 : 0 : return zcbor_search_key_tstr_ptr(state, str, strnlen(str, maxlen));
960 : : }
961 : :
962 : :
963 : 0 : static bool array_end_expect(zcbor_state_t *state)
964 : : {
965 [ # # ]: 0 : INITIAL_CHECKS();
966 [ # # ]: 0 : ZCBOR_ERR_IF(*state->payload != 0xFF, ZCBOR_ERR_WRONG_TYPE);
967 : :
968 : 0 : state->payload++;
969 : 0 : return true;
970 : : }
971 : :
972 : :
973 : 30 : static bool list_map_end_decode(zcbor_state_t *state)
974 : : {
975 : 30 : size_t max_elem_count = 0;
976 : :
977 [ - + ]: 30 : if (state->decode_state.indefinite_length_array) {
978 [ # # ]: 0 : if (!array_end_expect(state)) {
979 : 0 : ZCBOR_FAIL();
980 : : }
981 : 0 : max_elem_count = ZCBOR_MAX_ELEM_COUNT;
982 : 0 : state->decode_state.indefinite_length_array = false;
983 : : }
984 [ - + ]: 30 : if (!zcbor_process_backup(state,
985 : : ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME | ZCBOR_FLAG_KEEP_PAYLOAD,
986 : : max_elem_count)) {
987 : 0 : ZCBOR_FAIL();
988 : : }
989 : :
990 : : return true;
991 : : }
992 : :
993 : :
994 : 12 : bool zcbor_list_end_decode(zcbor_state_t *state)
995 : : {
996 : 12 : PRINT_FUNC();
997 : 12 : return list_map_end_decode(state);
998 : : }
999 : :
1000 : :
1001 : 18 : bool zcbor_map_end_decode(zcbor_state_t *state)
1002 : : {
1003 : 18 : PRINT_FUNC();
1004 : 18 : return list_map_end_decode(state);
1005 : : }
1006 : :
1007 : :
1008 : 0 : bool zcbor_unordered_map_end_decode(zcbor_state_t *state)
1009 : : {
1010 : : /* Checking zcbor_array_at_end() ensures that check is valid.
1011 : : * In case the map is at the end, but state->decode_state.counting_map_elems isn't updated.*/
1012 [ # # # # ]: 0 : ZCBOR_ERR_IF(!zcbor_array_at_end(state) && state->decode_state.counting_map_elems,
1013 : : ZCBOR_ERR_ELEMS_NOT_PROCESSED);
1014 : :
1015 [ # # ]: 0 : if (state->decode_state.map_elem_count > 0) {
1016 : : #ifdef ZCBOR_MAP_SMART_SEARCH
1017 : : manipulate_flags(state, FLAG_MODE_CLEAR_UNUSED);
1018 : :
1019 : : for (size_t i = 0; i < zcbor_flags_to_bytes(state->decode_state.map_elem_count); i++) {
1020 : : if (state->decode_state.map_search_elem_state[i] != 0) {
1021 : : zcbor_log("unprocessed element(s) in map: [%zu] = 0x%02x\n",
1022 : : i, state->decode_state.map_search_elem_state[i]);
1023 : : ZCBOR_ERR(ZCBOR_ERR_ELEMS_NOT_PROCESSED);
1024 : : }
1025 : : }
1026 : : #else
1027 [ # # ]: 0 : ZCBOR_ERR_IF(should_try_key(state), ZCBOR_ERR_ELEMS_NOT_PROCESSED);
1028 : : #endif
1029 : : }
1030 [ # # ]: 0 : while (!zcbor_array_at_end(state)) {
1031 : 0 : zcbor_any_skip(state, NULL);
1032 : : }
1033 : 0 : return zcbor_map_end_decode(state);
1034 : : }
1035 : :
1036 : :
1037 : 0 : bool zcbor_list_map_end_force_decode(zcbor_state_t *state)
1038 : : {
1039 [ # # ]: 0 : if (!zcbor_process_backup(state,
1040 : : ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME | ZCBOR_FLAG_KEEP_PAYLOAD,
1041 : : ZCBOR_MAX_ELEM_COUNT)) {
1042 : 0 : ZCBOR_FAIL();
1043 : : }
1044 : :
1045 : : return true;
1046 : : }
1047 : :
1048 : :
1049 : 0 : bool zcbor_simple_decode(zcbor_state_t *state, uint8_t *result)
1050 : : {
1051 : 0 : PRINT_FUNC();
1052 : 0 : PRINT_FUNC();
1053 [ # # ]: 0 : INITIAL_CHECKS_WITH_TYPE(ZCBOR_MAJOR_TYPE_SIMPLE);
1054 : :
1055 : : /* Simple values must be 0-23 (additional is 0-23) or 24-255 (additional is 24).
1056 : : * Other additional values are not considered simple values. */
1057 [ # # ]: 0 : ZCBOR_ERR_IF(ZCBOR_ADDITIONAL(*state->payload) > 24, ZCBOR_ERR_WRONG_TYPE);
1058 : :
1059 [ # # ]: 0 : if (!value_extract(state, result, sizeof(*result))) {
1060 : 0 : ZCBOR_FAIL();
1061 : : }
1062 : : return true;
1063 : : }
1064 : :
1065 : :
1066 : 0 : bool zcbor_simple_expect(zcbor_state_t *state, uint8_t expected)
1067 : : {
1068 : 0 : PRINT_FUNC();
1069 : 0 : uint8_t actual;
1070 : :
1071 [ # # ]: 0 : if (!zcbor_simple_decode(state, &actual)) {
1072 : 0 : ZCBOR_FAIL();
1073 : : }
1074 : :
1075 [ # # ]: 0 : if (actual != expected) {
1076 : 0 : zcbor_log("simple value %u != %u\r\n", actual, expected);
1077 : 0 : ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
1078 : : }
1079 : :
1080 : : return true;
1081 : : }
1082 : :
1083 : :
1084 : 0 : bool zcbor_simple_pexpect(zcbor_state_t *state, uint8_t *expected)
1085 : : {
1086 : 0 : PRINT_FUNC();
1087 : 0 : return zcbor_simple_expect(state, *expected);
1088 : : }
1089 : :
1090 : :
1091 : 0 : bool zcbor_nil_expect(zcbor_state_t *state, void *unused)
1092 : : {
1093 : 0 : PRINT_FUNC();
1094 : 0 : (void)unused;
1095 : 0 : return zcbor_simple_expect(state, 22);
1096 : : }
1097 : :
1098 : :
1099 : 0 : bool zcbor_undefined_expect(zcbor_state_t *state, void *unused)
1100 : : {
1101 : 0 : PRINT_FUNC();
1102 : 0 : (void)unused;
1103 : 0 : return zcbor_simple_expect(state, 23);
1104 : : }
1105 : :
1106 : :
1107 : 0 : bool zcbor_bool_decode(zcbor_state_t *state, bool *result)
1108 : : {
1109 : 0 : PRINT_FUNC();
1110 : 0 : uint8_t value;
1111 : :
1112 [ # # ]: 0 : if (!zcbor_simple_decode(state, &value)) {
1113 : 0 : ZCBOR_FAIL();
1114 : : }
1115 : 0 : value -= ZCBOR_BOOL_TO_SIMPLE;
1116 [ # # ]: 0 : if (value > 1) {
1117 : 0 : ERR_RESTORE(ZCBOR_ERR_WRONG_TYPE);
1118 : : }
1119 : 0 : *result = value;
1120 : :
1121 : 0 : zcbor_log("boolval: %u\r\n", *result);
1122 : 0 : return true;
1123 : : }
1124 : :
1125 : :
1126 : 0 : bool zcbor_bool_expect(zcbor_state_t *state, bool expected)
1127 : : {
1128 : 0 : PRINT_FUNC();
1129 [ # # ]: 0 : return zcbor_simple_expect(state, (uint8_t)(!!expected) + ZCBOR_BOOL_TO_SIMPLE);
1130 : : }
1131 : :
1132 : :
1133 : 0 : bool zcbor_bool_pexpect(zcbor_state_t *state, bool *expected)
1134 : : {
1135 : 0 : PRINT_FUNC();
1136 : 0 : return zcbor_bool_expect(state, *expected);
1137 : : }
1138 : :
1139 : :
1140 : 0 : static bool float_check(zcbor_state_t *state, uint8_t additional_val)
1141 : : {
1142 [ # # ]: 0 : INITIAL_CHECKS_WITH_TYPE(ZCBOR_MAJOR_TYPE_SIMPLE);
1143 [ # # ]: 0 : ZCBOR_ERR_IF(ZCBOR_ADDITIONAL(*state->payload) != additional_val, ZCBOR_ERR_FLOAT_SIZE);
1144 : : return true;
1145 : : }
1146 : :
1147 : :
1148 : 0 : bool zcbor_float16_bytes_decode(zcbor_state_t *state, uint16_t *result)
1149 : : {
1150 : 0 : PRINT_FUNC();
1151 [ # # ]: 0 : ZCBOR_FAIL_IF(!float_check(state, ZCBOR_VALUE_IS_2_BYTES));
1152 : :
1153 [ # # ]: 0 : if (!value_extract(state, result, sizeof(*result))) {
1154 : 0 : ZCBOR_FAIL();
1155 : : }
1156 : :
1157 : : return true;
1158 : : }
1159 : :
1160 : :
1161 : 0 : bool zcbor_float16_bytes_expect(zcbor_state_t *state, uint16_t expected)
1162 : : {
1163 : 0 : PRINT_FUNC();
1164 : 0 : uint16_t actual;
1165 : :
1166 [ # # ]: 0 : if (!zcbor_float16_bytes_decode(state, &actual)) {
1167 : 0 : ZCBOR_FAIL();
1168 : : }
1169 [ # # ]: 0 : if (actual != expected) {
1170 : 0 : ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
1171 : : }
1172 : : return true;
1173 : : }
1174 : :
1175 : :
1176 : 0 : bool zcbor_float16_bytes_pexpect(zcbor_state_t *state, uint16_t *expected)
1177 : : {
1178 : 0 : PRINT_FUNC();
1179 : 0 : return zcbor_float16_bytes_expect(state, *expected);
1180 : : }
1181 : :
1182 : :
1183 : 0 : bool zcbor_float16_decode(zcbor_state_t *state, float *result)
1184 : : {
1185 : 0 : PRINT_FUNC();
1186 : 0 : uint16_t value16;
1187 : :
1188 [ # # ]: 0 : if (!zcbor_float16_bytes_decode(state, &value16)) {
1189 : 0 : ZCBOR_FAIL();
1190 : : }
1191 : :
1192 : 0 : *result = zcbor_float16_to_32(value16);
1193 : 0 : return true;
1194 : : }
1195 : :
1196 : :
1197 : 0 : bool zcbor_float16_expect(zcbor_state_t *state, float expected)
1198 : : {
1199 : 0 : PRINT_FUNC();
1200 : 0 : float actual;
1201 : :
1202 [ # # ]: 0 : if (!zcbor_float16_decode(state, &actual)) {
1203 : 0 : ZCBOR_FAIL();
1204 : : }
1205 [ # # ]: 0 : if (actual != expected) {
1206 : 0 : ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
1207 : : }
1208 : : return true;
1209 : : }
1210 : :
1211 : :
1212 : 0 : bool zcbor_float16_pexpect(zcbor_state_t *state, float *expected)
1213 : : {
1214 : 0 : PRINT_FUNC();
1215 : 0 : return zcbor_float16_expect(state, *expected);
1216 : : }
1217 : :
1218 : :
1219 : 0 : bool zcbor_float32_decode(zcbor_state_t *state, float *result)
1220 : : {
1221 : 0 : PRINT_FUNC();
1222 [ # # ]: 0 : ZCBOR_FAIL_IF(!float_check(state, ZCBOR_VALUE_IS_4_BYTES));
1223 : :
1224 [ # # ]: 0 : if (!value_extract(state, result, sizeof(*result))) {
1225 : 0 : ZCBOR_FAIL();
1226 : : }
1227 : :
1228 : : return true;
1229 : : }
1230 : :
1231 : :
1232 : 0 : bool zcbor_float32_expect(zcbor_state_t *state, float expected)
1233 : : {
1234 : 0 : PRINT_FUNC();
1235 : 0 : float actual;
1236 : :
1237 [ # # ]: 0 : if (!zcbor_float32_decode(state, &actual)) {
1238 : 0 : ZCBOR_FAIL();
1239 : : }
1240 [ # # ]: 0 : if (actual != expected) {
1241 : 0 : ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
1242 : : }
1243 : : return true;
1244 : : }
1245 : :
1246 : :
1247 : 0 : bool zcbor_float32_pexpect(zcbor_state_t *state, float *expected)
1248 : : {
1249 : 0 : PRINT_FUNC();
1250 : 0 : return zcbor_float32_expect(state, *expected);
1251 : : }
1252 : :
1253 : :
1254 : 0 : bool zcbor_float16_32_decode(zcbor_state_t *state, float *result)
1255 : : {
1256 : 0 : PRINT_FUNC();
1257 [ # # ]: 0 : if (zcbor_float16_decode(state, result)) {
1258 : : /* Do nothing */
1259 [ # # ]: 0 : } else if (!zcbor_float32_decode(state, result)) {
1260 : 0 : ZCBOR_FAIL();
1261 : : }
1262 : :
1263 : : return true;
1264 : : }
1265 : :
1266 : :
1267 : 0 : bool zcbor_float16_32_expect(zcbor_state_t *state, float expected)
1268 : : {
1269 : 0 : PRINT_FUNC();
1270 [ # # ]: 0 : if (zcbor_float16_expect(state, expected)) {
1271 : : /* Do nothing */
1272 [ # # ]: 0 : } else if (!zcbor_float32_expect(state, expected)) {
1273 : 0 : ZCBOR_FAIL();
1274 : : }
1275 : :
1276 : : return true;
1277 : : }
1278 : :
1279 : :
1280 : 0 : bool zcbor_float16_32_pexpect(zcbor_state_t *state, float *expected)
1281 : : {
1282 : 0 : PRINT_FUNC();
1283 : 0 : return zcbor_float16_32_expect(state, *expected);
1284 : : }
1285 : :
1286 : :
1287 : 0 : bool zcbor_float64_decode(zcbor_state_t *state, double *result)
1288 : : {
1289 : 0 : PRINT_FUNC();
1290 [ # # ]: 0 : ZCBOR_FAIL_IF(!float_check(state, ZCBOR_VALUE_IS_8_BYTES));
1291 : :
1292 [ # # ]: 0 : if (!value_extract(state, result, sizeof(*result))) {
1293 : 0 : ZCBOR_FAIL();
1294 : : }
1295 : :
1296 : : return true;
1297 : : }
1298 : :
1299 : :
1300 : 0 : bool zcbor_float64_expect(zcbor_state_t *state, double expected)
1301 : : {
1302 : 0 : PRINT_FUNC();
1303 : 0 : double actual;
1304 : :
1305 [ # # ]: 0 : if (!zcbor_float64_decode(state, &actual)) {
1306 : 0 : ZCBOR_FAIL();
1307 : : }
1308 [ # # ]: 0 : if (actual != expected) {
1309 : 0 : ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
1310 : : }
1311 : : return true;
1312 : : }
1313 : :
1314 : :
1315 : 0 : bool zcbor_float64_pexpect(zcbor_state_t *state, double *expected)
1316 : : {
1317 : 0 : PRINT_FUNC();
1318 : 0 : return zcbor_float64_expect(state, *expected);
1319 : : }
1320 : :
1321 : :
1322 : 0 : bool zcbor_float32_64_decode(zcbor_state_t *state, double *result)
1323 : : {
1324 : 0 : PRINT_FUNC();
1325 : 0 : float float_result;
1326 : :
1327 [ # # ]: 0 : if (zcbor_float32_decode(state, &float_result)) {
1328 : 0 : *result = (double)float_result;
1329 [ # # ]: 0 : } else if (!zcbor_float64_decode(state, result)) {
1330 : 0 : ZCBOR_FAIL();
1331 : : }
1332 : :
1333 : : return true;
1334 : : }
1335 : :
1336 : :
1337 : 0 : bool zcbor_float32_64_expect(zcbor_state_t *state, double expected)
1338 : : {
1339 : 0 : PRINT_FUNC();
1340 [ # # ]: 0 : if (zcbor_float64_expect(state, expected)) {
1341 : : /* Do nothing */
1342 [ # # ]: 0 : } else if (!zcbor_float32_expect(state, (float)expected)) {
1343 : 0 : ZCBOR_FAIL();
1344 : : }
1345 : :
1346 : : return true;
1347 : : }
1348 : :
1349 : :
1350 : 0 : bool zcbor_float32_64_pexpect(zcbor_state_t *state, double *expected)
1351 : : {
1352 : 0 : PRINT_FUNC();
1353 : 0 : return zcbor_float32_64_expect(state, *expected);
1354 : : }
1355 : :
1356 : :
1357 : 0 : bool zcbor_float_decode(zcbor_state_t *state, double *result)
1358 : : {
1359 : 0 : PRINT_FUNC();
1360 : 0 : float float_result;
1361 : :
1362 [ # # ]: 0 : if (zcbor_float16_decode(state, &float_result)) {
1363 : 0 : *result = (double)float_result;
1364 [ # # ]: 0 : } else if (zcbor_float32_decode(state, &float_result)) {
1365 : 0 : *result = (double)float_result;
1366 [ # # ]: 0 : } else if (!zcbor_float64_decode(state, result)) {
1367 : 0 : ZCBOR_FAIL();
1368 : : }
1369 : :
1370 : : return true;
1371 : : }
1372 : :
1373 : :
1374 : 0 : bool zcbor_float_expect(zcbor_state_t *state, double expected)
1375 : : {
1376 : 0 : PRINT_FUNC();
1377 [ # # ]: 0 : if (zcbor_float16_expect(state, (float)expected)) {
1378 : : /* Do nothing */
1379 [ # # ]: 0 : } else if (zcbor_float32_expect(state, (float)expected)) {
1380 : : /* Do nothing */
1381 [ # # ]: 0 : } else if (!zcbor_float64_expect(state, expected)) {
1382 : 0 : ZCBOR_FAIL();
1383 : : }
1384 : :
1385 : : return true;
1386 : : }
1387 : :
1388 : :
1389 : 0 : bool zcbor_float_pexpect(zcbor_state_t *state, double *expected)
1390 : : {
1391 : 0 : PRINT_FUNC();
1392 : 0 : return zcbor_float_expect(state, *expected);
1393 : : }
1394 : :
1395 : :
1396 : 0 : bool zcbor_any_skip(zcbor_state_t *state, void *result)
1397 : : {
1398 : 0 : PRINT_FUNC();
1399 : : zcbor_assert_state(result == NULL,
1400 : 0 : "'any' type cannot be returned, only skipped.\r\n");
1401 : 0 : (void)result;
1402 : :
1403 [ # # ]: 0 : INITIAL_CHECKS();
1404 : 0 : zcbor_major_type_t major_type = ZCBOR_MAJOR_TYPE(*state->payload);
1405 : 0 : uint8_t additional = ZCBOR_ADDITIONAL(*state->payload);
1406 : 0 : uint64_t value = 0; /* In case of indefinite_length_array. */
1407 : 0 : zcbor_state_t state_copy;
1408 : :
1409 : 0 : memcpy(&state_copy, state, sizeof(zcbor_state_t));
1410 : :
1411 [ # # ]: 0 : while (major_type == ZCBOR_MAJOR_TYPE_TAG) {
1412 : 0 : uint32_t tag_dummy;
1413 : :
1414 [ # # ]: 0 : if (!zcbor_tag_decode(&state_copy, &tag_dummy)) {
1415 : 0 : ZCBOR_FAIL();
1416 : : }
1417 [ # # ]: 0 : ZCBOR_ERR_IF(state_copy.payload >= state_copy.payload_end, ZCBOR_ERR_NO_PAYLOAD);
1418 : 0 : major_type = ZCBOR_MAJOR_TYPE(*state_copy.payload);
1419 : 0 : additional = ZCBOR_ADDITIONAL(*state_copy.payload);
1420 : : }
1421 : :
1422 : 0 : const bool indefinite_length_array = ((additional == ZCBOR_VALUE_IS_INDEFINITE_LENGTH)
1423 [ # # # # ]: 0 : && ((major_type == ZCBOR_MAJOR_TYPE_LIST) || (major_type == ZCBOR_MAJOR_TYPE_MAP)));
1424 : :
1425 [ # # # # : 0 : ZCBOR_ERR_IF(ZCBOR_ENFORCE_CANONICAL(state) && indefinite_length_array,
# # ]
1426 : : ZCBOR_ERR_INVALID_VALUE_ENCODING);
1427 : :
1428 [ # # # # ]: 0 : if (!indefinite_length_array && !value_extract(&state_copy, &value, sizeof(value))) {
1429 : : /* Can happen because of elem_count (or payload_end) */
1430 : 0 : ZCBOR_FAIL();
1431 : : }
1432 : :
1433 [ # # # # ]: 0 : switch (major_type) {
1434 : 0 : case ZCBOR_MAJOR_TYPE_BSTR:
1435 : : case ZCBOR_MAJOR_TYPE_TSTR:
1436 : : /* 'value' is the length of the BSTR or TSTR.
1437 : : * The subtraction is safe because value_extract() above
1438 : : * checks that payload_end is greater than payload. */
1439 [ # # ]: 0 : ZCBOR_ERR_IF(
1440 : : value > (uint64_t)(state_copy.payload_end - state_copy.payload),
1441 : : ZCBOR_ERR_NO_PAYLOAD);
1442 : 0 : (state_copy.payload) += value;
1443 : 0 : break;
1444 : 0 : case ZCBOR_MAJOR_TYPE_MAP:
1445 [ # # ]: 0 : ZCBOR_ERR_IF(value > (SIZE_MAX / 2), ZCBOR_ERR_INT_SIZE);
1446 : 0 : value *= 2;
1447 : : /* fallthrough */
1448 : 0 : case ZCBOR_MAJOR_TYPE_LIST:
1449 [ # # ]: 0 : if (indefinite_length_array) {
1450 : 0 : state_copy.payload++;
1451 : 0 : value = ZCBOR_LARGE_ELEM_COUNT;
1452 : : }
1453 : 0 : state_copy.elem_count = (size_t)value;
1454 : 0 : state_copy.decode_state.indefinite_length_array = indefinite_length_array;
1455 : 0 : while (!zcbor_array_at_end(&state_copy)) {
1456 [ # # ]: 0 : if (!zcbor_any_skip(&state_copy, NULL)) {
1457 [ # # ]: 0 : ZCBOR_FAIL();
1458 : : }
1459 : : }
1460 [ # # # # ]: 0 : if (indefinite_length_array && !array_end_expect(&state_copy)) {
1461 : : ZCBOR_FAIL();
1462 : : }
1463 : : break;
1464 : : default:
1465 : : /* Do nothing */
1466 : : break;
1467 : : }
1468 : :
1469 : 0 : state->payload = state_copy.payload;
1470 : 0 : state->elem_count--;
1471 : :
1472 : 0 : return true;
1473 : : }
1474 : :
1475 : :
1476 : 0 : bool zcbor_tag_decode(zcbor_state_t *state, uint32_t *result)
1477 : : {
1478 : 0 : PRINT_FUNC();
1479 [ # # ]: 0 : INITIAL_CHECKS_WITH_TYPE(ZCBOR_MAJOR_TYPE_TAG);
1480 : :
1481 [ # # ]: 0 : if (!value_extract(state, result, sizeof(*result))) {
1482 : 0 : ZCBOR_FAIL();
1483 : : }
1484 : 0 : state->elem_count++;
1485 : 0 : return true;
1486 : : }
1487 : :
1488 : :
1489 : 0 : bool zcbor_tag_expect(zcbor_state_t *state, uint32_t expected)
1490 : : {
1491 : 0 : PRINT_FUNC();
1492 : 0 : uint32_t actual;
1493 : :
1494 [ # # ]: 0 : if (!zcbor_tag_decode(state, &actual)) {
1495 : 0 : ZCBOR_FAIL();
1496 : : }
1497 [ # # ]: 0 : if (actual != expected) {
1498 : 0 : ERR_RESTORE(ZCBOR_ERR_WRONG_VALUE);
1499 : : }
1500 : : return true;
1501 : : }
1502 : :
1503 : :
1504 : 0 : bool zcbor_tag_pexpect(zcbor_state_t *state, uint32_t *expected)
1505 : : {
1506 : 0 : PRINT_FUNC();
1507 : 0 : return zcbor_tag_expect(state, *expected);
1508 : : }
1509 : :
1510 : :
1511 : 162 : bool zcbor_multi_decode(size_t min_decode,
1512 : : size_t max_decode,
1513 : : size_t *num_decode,
1514 : : zcbor_decoder_t decoder,
1515 : : zcbor_state_t *state,
1516 : : void *result,
1517 : : size_t result_len)
1518 : : {
1519 : 162 : PRINT_FUNC();
1520 : 162 : ZCBOR_CHECK_ERROR();
1521 [ + + ]: 180 : for (size_t i = 0; i < max_decode; i++) {
1522 : 162 : uint8_t const *payload_bak = state->payload;
1523 : 162 : size_t elem_count_bak = state->elem_count;
1524 : :
1525 [ + + ]: 162 : if (!decoder(state,
1526 : 162 : (uint8_t *)result + i*result_len)) {
1527 : 144 : *num_decode = i;
1528 : 144 : state->payload = payload_bak;
1529 : 144 : state->elem_count = elem_count_bak;
1530 [ - + ]: 144 : ZCBOR_ERR_IF(i < min_decode, ZCBOR_ERR_ITERATIONS);
1531 : : zcbor_log("Found %zu elements.\r\n", i);
1532 : : return true;
1533 : : }
1534 : : }
1535 : 18 : zcbor_log("Found %zu elements.\r\n", max_decode);
1536 : 18 : *num_decode = max_decode;
1537 : 18 : return true;
1538 : : }
1539 : :
1540 : :
1541 : 162 : bool zcbor_present_decode(bool *present,
1542 : : zcbor_decoder_t decoder,
1543 : : zcbor_state_t *state,
1544 : : void *result)
1545 : : {
1546 : 162 : PRINT_FUNC();
1547 : 162 : size_t num_decode = 0;
1548 : 162 : bool retval = zcbor_multi_decode(0, 1, &num_decode, decoder, state, result, 0);
1549 : :
1550 : 162 : zcbor_assert_state(retval, "zcbor_multi_decode should not fail with these parameters.\r\n");
1551 : :
1552 : 162 : *present = !!num_decode;
1553 : 162 : return retval;
1554 : : }
1555 : :
1556 : :
1557 : 0 : void zcbor_new_decode_state(zcbor_state_t *state_array, size_t n_states,
1558 : : const uint8_t *payload, size_t payload_len, size_t elem_count,
1559 : : uint8_t *flags, size_t flags_bytes)
1560 : : {
1561 : 0 : zcbor_new_state(state_array, n_states, payload, payload_len, elem_count, flags, flags_bytes);
1562 : 0 : }
|