1 /*
2 * Copyright (c) 2020 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZCBOR_COMMON_H__
8 #define ZCBOR_COMMON_H__
9
10 #include <stdint.h>
11 #include <stdbool.h>
12 #include <stddef.h>
13 #include <string.h>
14 #include "zcbor_tags.h"
15
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19
20 #define ZCBOR_STRINGIFY_PRE(x) #x
21 #define ZCBOR_STRINGIFY(s) ZCBOR_STRINGIFY_PRE(s)
22
23 #define ZCBOR_VERSION_MAJOR 0
24 #define ZCBOR_VERSION_MINOR 9
25 #define ZCBOR_VERSION_BUGFIX 1
26
27 /** The version string with dots and not prefix. */
28 #define ZCBOR_VERSION_STR ZCBOR_STRINGIFY(ZCBOR_VERSION_MAJOR) \
29 "." ZCBOR_STRINGIFY(ZCBOR_VERSION_MINOR) \
30 "." ZCBOR_STRINGIFY(ZCBOR_VERSION_BUGFIX)
31
32 /** Monotonically increasing integer representing the version. */
33 #define ZCBOR_VERSION ((ZCBOR_VERSION_MAJOR << 24) \
34 + (ZCBOR_VERSION_MINOR << 16) \
35 + (ZCBOR_VERSION_BUGFIX << 8))
36
37 /** Convenience type that allows pointing to strings directly inside the payload
38 * without the need to copy out.
39 */
40 struct zcbor_string {
41 const uint8_t *value;
42 size_t len;
43 };
44
45
46 /** Type representing a string fragment.
47 *
48 * Don't modify any member variables, or subsequent calls may fail.
49 **/
50 struct zcbor_string_fragment {
51 struct zcbor_string fragment; ///! Location and length of the fragment.
52 size_t offset; ///! The offset in the full string at which this fragment belongs.
53 size_t total_len; ///! The total length of the string this fragment is a part of.
54 };
55
56
57 /** Size to use in struct zcbor_string_fragment when the real size is unknown. */
58 #define ZCBOR_STRING_FRAGMENT_UNKNOWN_LENGTH SIZE_MAX
59
60 #ifndef MIN
61 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
62 #endif
63
64 #ifndef MAX
65 #define MAX(a, b) (((a) < (b)) ? (b) : (a))
66 #endif
67
68 #ifndef ZCBOR_ARRAY_SIZE
69 #define ZCBOR_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
70 #endif
71
72 /* Endian-dependent offset of smaller integer in a bigger one. */
73 #ifdef ZCBOR_BIG_ENDIAN
74 #define ZCBOR_ECPY_OFFS(dst_len, src_len) ((dst_len) - (src_len))
75 #else
76 #define ZCBOR_ECPY_OFFS(dst_len, src_len) (0)
77 #endif /* ZCBOR_BIG_ENDIAN */
78
79 #if SIZE_MAX <= UINT64_MAX
80 /** The ZCBOR_SUPPORTS_SIZE_T will be defined if processing of size_t type variables directly
81 * with zcbor_size_ functions is supported.
82 **/
83 #define ZCBOR_SUPPORTS_SIZE_T
84 #else
85 #warning "zcbor: Unsupported size_t encoding size"
86 #endif
87
88 struct zcbor_state_constant;
89
90 /** The zcbor_state_t structure is used for both encoding and decoding. */
91 typedef struct {
92 union {
93 uint8_t *payload_mut;
94 uint8_t const *payload; /**< The current place in the payload. Will be
95 updated when an element is correctly
96 processed. */
97 };
98 uint8_t const *payload_bak; /**< Temporary backup of payload. */
99 size_t elem_count; /**< The current element is part of a LIST or a MAP,
100 and this keeps count of how many elements are
101 expected. This will be checked before processing
102 and decremented if the element is correctly
103 processed. */
104 uint8_t const *payload_end; /**< The end of the payload. This will be
105 checked against payload before
106 processing each element. */
107 bool payload_moved; /**< Is set to true while the state is stored as a backup
108 if @ref zcbor_update_state is called, since that function
109 updates the payload_end of all backed-up states. */
110
111 /* This is the "decode state", the part of zcbor_state_t that is only used by zcbor_decode.c. */
112 struct {
113 bool indefinite_length_array; /**< Is set to true if the decoder is currently
114 decoding the contents of an indefinite-
115 length array. */
116 bool counting_map_elems; /**< Is set to true while the number of elements of the
117 current map are being counted. */
118 #ifdef ZCBOR_MAP_SMART_SEARCH
119 uint8_t *map_search_elem_state; /**< Optional flags to use when searching unordered
120 maps. If this is not NULL and map_elem_count
121 is non-zero, this consists of one flag per element
122 in the current map. The n-th bit can be set to 0
123 to indicate that the n-th element in the
124 map should not be searched. These are manipulated
125 via zcbor_elem_processed() or
126 zcbor_unordered_map_search(), and should not be
127 manipulated directly. */
128 #else
129 size_t map_elems_processed; /**< The number of elements of an unordered map
130 that have been processed. */
131 #endif
132 size_t map_elem_count; /**< Number of elements in the current unordered map.
133 This also serves as the number of bits (not bytes)
134 in the map_search_elem_state array (when applicable). */
135 } decode_state;
136 struct zcbor_state_constant *constant_state; /**< The part of the state that is
137 not backed up and duplicated. */
138 } zcbor_state_t;
139
140 struct zcbor_state_constant {
141 zcbor_state_t *backup_list;
142 size_t current_backup;
143 size_t num_backups;
144 int error;
145 #ifdef ZCBOR_STOP_ON_ERROR
146 bool stop_on_error;
147 #endif
148 bool enforce_canonical; /**< Fail when decoding if data is non-canonical.
149 The default/initial value follows ZCBOR_CANONICAL */
150 bool manually_process_elem; /**< Whether an (unordered map) element should be automatically
151 marked as processed when found via @ref zcbor_search_map_key. */
152 #ifdef ZCBOR_MAP_SMART_SEARCH
153 uint8_t *map_search_elem_state_end; /**< The end of the @ref map_search_elem_state buffer. */
154 #endif
155 };
156
157 #ifdef ZCBOR_CANONICAL
158 #define ZCBOR_ENFORCE_CANONICAL_DEFAULT true
159 #else
160 #define ZCBOR_ENFORCE_CANONICAL_DEFAULT false
161 #endif
162
163 #define ZCBOR_ENFORCE_CANONICAL(state) (state->constant_state \
164 ? state->constant_state->enforce_canonical : ZCBOR_ENFORCE_CANONICAL_DEFAULT)
165
166 #define ZCBOR_MANUALLY_PROCESS_ELEM_DEFAULT false
167
168 #define ZCBOR_MANUALLY_PROCESS_ELEM(state) (state->constant_state \
169 ? state->constant_state->manually_process_elem : ZCBOR_MANUALLY_PROCESS_ELEM_DEFAULT)
170
171 /** Function pointer type used with zcbor_multi_decode.
172 *
173 * This type is compatible with all decoding functions here and in the generated
174 * code, except for zcbor_multi_decode.
175 */
176 typedef bool(zcbor_encoder_t)(zcbor_state_t *, const void *);
177 typedef bool(zcbor_decoder_t)(zcbor_state_t *, void *);
178
179 /** Enumeration representing the major types available in CBOR.
180 *
181 * The major type is represented in the 3 first bits of the header byte.
182 */
183 typedef enum
184 {
185 ZCBOR_MAJOR_TYPE_PINT = 0, ///! Positive Integer
186 ZCBOR_MAJOR_TYPE_NINT = 1, ///! Negative Integer
187 ZCBOR_MAJOR_TYPE_BSTR = 2, ///! Byte String
188 ZCBOR_MAJOR_TYPE_TSTR = 3, ///! Text String
189 ZCBOR_MAJOR_TYPE_LIST = 4, ///! List
190 ZCBOR_MAJOR_TYPE_MAP = 5, ///! Map
191 ZCBOR_MAJOR_TYPE_TAG = 6, ///! Semantic Tag
192 ZCBOR_MAJOR_TYPE_SIMPLE = 7, ///! Simple values and floats
193 } zcbor_major_type_t;
194
195 /** Extract the major type, i.e. the first 3 bits of the header byte. */
196 #define ZCBOR_MAJOR_TYPE(header_byte) ((zcbor_major_type_t)(((header_byte) >> 5) & 0x7))
197
198 /** Extract the additional info, i.e. the last 5 bits of the header byte. */
199 #define ZCBOR_ADDITIONAL(header_byte) ((header_byte) & 0x1F)
200
201 /** Convenience macro for failing out of a decoding/encoding function.
202 */
203 #define ZCBOR_FAIL() \
204 do {\
205 zcbor_log("ZCBOR_FAIL "); \
206 zcbor_trace_file(state); \
207 return false; \
208 } while(0)
209
210 #define ZCBOR_FAIL_IF(expr) \
211 do {\
212 if (expr) { \
213 zcbor_log("ZCBOR_FAIL_IF(" #expr ") "); \
214 ZCBOR_FAIL(); \
215 } \
216 } while(0)
217
218 #define ZCBOR_ERR(err) \
219 do { \
220 zcbor_log("ZCBOR_ERR(%d) ", err); \
221 zcbor_error(state, err); \
222 ZCBOR_FAIL(); \
223 } while(0)
224
225 #define ZCBOR_ERR_IF(expr, err) \
226 do {\
227 if (expr) { \
228 zcbor_log("ZCBOR_ERR_IF(" #expr ", %d) ", err); \
229 ZCBOR_ERR(err); \
230 } \
231 } while(0)
232
233 #define ZCBOR_CHECK_PAYLOAD() \
234 ZCBOR_ERR_IF(state->payload >= state->payload_end, ZCBOR_ERR_NO_PAYLOAD)
235
236 #ifdef ZCBOR_STOP_ON_ERROR
237 #define ZCBOR_CHECK_ERROR() \
238 do { \
239 if (!zcbor_check_error(state)) { \
240 ZCBOR_FAIL(); \
241 } \
242 } while(0)
243 #else
244 #define ZCBOR_CHECK_ERROR()
245 #endif
246
247 #define ZCBOR_VALUE_IN_HEADER 23 ///! Values below this are encoded directly in the header.
248 #define ZCBOR_VALUE_IS_1_BYTE 24 ///! The next 1 byte contains the value.
249 #define ZCBOR_VALUE_IS_2_BYTES 25 ///! The next 2 bytes contain the value.
250 #define ZCBOR_VALUE_IS_4_BYTES 26 ///! The next 4 bytes contain the value.
251 #define ZCBOR_VALUE_IS_8_BYTES 27 ///! The next 8 bytes contain the value.
252 #define ZCBOR_VALUE_IS_INDEFINITE_LENGTH 31 ///! The list or map has indefinite length, and will instead be terminated by a 0xFF token.
253
254 #define ZCBOR_BOOL_TO_SIMPLE ((uint8_t)20) ///! In CBOR, false/true have the values 20/21
255 #define ZCBOR_NIL_VAL ((uint8_t)22)
256 #define ZCBOR_UNDEF_VAL ((uint8_t)23)
257
258 #define ZCBOR_IS_FLOAT(header_byte) (((header_byte) >= 0xF9) && ((header_byte) <= 0xFB))
259
260 #define ZCBOR_FLAG_RESTORE 1UL ///! Restore from the backup. Overwrite the current state with the state from the backup.
261 #define ZCBOR_FLAG_CONSUME 2UL ///! Consume the backup. Remove the backup from the stack of backups.
262 #define ZCBOR_FLAG_KEEP_PAYLOAD 4UL ///! Keep the pre-restore payload after restoring.
263 #define ZCBOR_FLAG_KEEP_DECODE_STATE 8UL ///! Keep the pre-restore decode state (everything only used for decoding)
264
265 #define ZCBOR_SUCCESS 0
266 #define ZCBOR_ERR_NO_BACKUP_MEM 1
267 #define ZCBOR_ERR_NO_BACKUP_ACTIVE 2
268 #define ZCBOR_ERR_LOW_ELEM_COUNT 3
269 #define ZCBOR_ERR_HIGH_ELEM_COUNT 4
270 #define ZCBOR_ERR_INT_SIZE 5
271 #define ZCBOR_ERR_FLOAT_SIZE 6
272 #define ZCBOR_ERR_ADDITIONAL_INVAL 7 ///! > 27
273 #define ZCBOR_ERR_NO_PAYLOAD 8
274 #define ZCBOR_ERR_PAYLOAD_NOT_CONSUMED 9
275 #define ZCBOR_ERR_WRONG_TYPE 10
276 #define ZCBOR_ERR_WRONG_VALUE 11
277 #define ZCBOR_ERR_WRONG_RANGE 12
278 #define ZCBOR_ERR_ITERATIONS 13
279 #define ZCBOR_ERR_ASSERTION 14
280 #define ZCBOR_ERR_PAYLOAD_OUTDATED 15 ///! Because of a call to @ref zcbor_update_state
281 #define ZCBOR_ERR_ELEM_NOT_FOUND 16
282 #define ZCBOR_ERR_MAP_MISALIGNED 17
283 #define ZCBOR_ERR_ELEMS_NOT_PROCESSED 18
284 #define ZCBOR_ERR_NOT_AT_END 19
285 #define ZCBOR_ERR_MAP_FLAGS_NOT_AVAILABLE 20
286 #define ZCBOR_ERR_INVALID_VALUE_ENCODING 21 ///! When ZCBOR_CANONICAL is defined, and the incoming data is not encoded with minimal length, or uses indefinite length array.
287 #define ZCBOR_ERR_CONSTANT_STATE_MISSING 22
288 #define ZCBOR_ERR_UNKNOWN 31
289
290 /** The largest possible elem_count. */
291 #define ZCBOR_MAX_ELEM_COUNT SIZE_MAX
292
293 /** Initial value for elem_count for when it just needs to be large. */
294 #define ZCBOR_LARGE_ELEM_COUNT (ZCBOR_MAX_ELEM_COUNT - 15)
295
296
297 /** Take a backup of the current state. Overwrite the current elem_count. */
298 bool zcbor_new_backup(zcbor_state_t *state, size_t new_elem_count);
299
300 /** Consult the most recent backup. In doing so, check whether elem_count is
301 * less than or equal to max_elem_count.
302 * Also, take action based on the flags (See ZCBOR_FLAG_*).
303 */
304 bool zcbor_process_backup(zcbor_state_t *state, uint32_t flags, size_t max_elem_count);
305
306 /** Convenience function for starting encoding/decoding of a union.
307 *
308 * That is, for attempting to encode, or especially decode, multiple options.
309 * Makes a new backup.
310 */
311 bool zcbor_union_start_code(zcbor_state_t *state);
312
313 /** Convenience function before encoding/decoding one element of a union.
314 *
315 * Call this before attempting each option.
316 * Restores the backup, without consuming it.
317 */
318 bool zcbor_union_elem_code(zcbor_state_t *state);
319
320 /** Convenience function before encoding/decoding one element of a union.
321 *
322 * Consumes the backup without restoring it.
323 */
324 bool zcbor_union_end_code(zcbor_state_t *state);
325
326 /** Initialize a state with backups.
327 * As long as n_states is more than 1, one of the states in the array is used
328 * as a struct zcbor_state_constant object.
329 * If there is no struct zcbor_state_constant (n_states == 1), error codes are
330 * not available.
331 * This means that you get a state with (n_states - 2) backups.
332 * payload, payload_len, elem_count, and elem_state are used to initialize the first state.
333 * The elem_state is only needed for unordered maps, when ZCBOR_MAP_SMART_SEARCH is enabled.
334 * It is ignored otherwise.
335 */
336 void zcbor_new_state(zcbor_state_t *state_array, size_t n_states,
337 const uint8_t *payload, size_t payload_len, size_t elem_count,
338 uint8_t *elem_state, size_t elem_state_bytes);
339
340 /** Do boilerplate entry function procedure.
341 * Initialize states, call function, and check the result.
342 */
343 int zcbor_entry_function(const uint8_t *payload, size_t payload_len,
344 void *result, size_t *payload_len_out, zcbor_state_t *state, zcbor_decoder_t func,
345 size_t n_states, size_t elem_count);
346
347 #ifdef ZCBOR_STOP_ON_ERROR
348 /** Check stored error and fail if present, but only if stop_on_error is true.
349 *
350 * @retval true No error found
351 * @retval false An error was found
352 */
zcbor_check_error(const zcbor_state_t * state)353 static inline bool zcbor_check_error(const zcbor_state_t *state)
354 {
355 struct zcbor_state_constant *cs = state->constant_state;
356 return !(cs && cs->stop_on_error && cs->error);
357 }
358 #endif
359
360 /** Return the current error state, replacing it with SUCCESS. */
zcbor_pop_error(zcbor_state_t * state)361 static inline int zcbor_pop_error(zcbor_state_t *state)
362 {
363 if (!state->constant_state) {
364 return ZCBOR_SUCCESS;
365 }
366 int err = state->constant_state->error;
367
368 state->constant_state->error = ZCBOR_SUCCESS;
369 return err;
370 }
371
372 /** Look at current error state without altering it */
zcbor_peek_error(const zcbor_state_t * state)373 static inline int zcbor_peek_error(const zcbor_state_t *state)
374 {
375 if (!state->constant_state) {
376 return ZCBOR_SUCCESS;
377 } else {
378 return state->constant_state->error;
379 }
380 }
381
382 /** Write the provided error to the error state. */
zcbor_error(zcbor_state_t * state,int err)383 static inline void zcbor_error(zcbor_state_t *state, int err)
384 {
385 #ifdef ZCBOR_STOP_ON_ERROR
386 if (zcbor_check_error(state))
387 #endif
388 {
389 if (state->constant_state) {
390 state->constant_state->error = err;
391 }
392 }
393 }
394
395 /** Whether the current payload is exhausted. */
zcbor_payload_at_end(const zcbor_state_t * state)396 static inline bool zcbor_payload_at_end(const zcbor_state_t *state)
397 {
398 return (state->payload == state->payload_end);
399 }
400
401 /** Update the current payload pointer (and payload_end).
402 *
403 * For use when the payload is divided into multiple chunks.
404 *
405 * This function also updates all backups to the new payload_end.
406 * This sets a flag so that @ref zcbor_process_backup fails if a backup is
407 * processed with the flag @ref ZCBOR_FLAG_RESTORE, but without the flag
408 * @ref ZCBOR_FLAG_KEEP_PAYLOAD since this would cause an invalid state.
409 *
410 * @param[inout] state The current state, will be updated with
411 * the new payload pointer.
412 * @param[in] payload The new payload chunk.
413 * @param[in] payload_len The length of the new payload chunk.
414 */
415 void zcbor_update_state(zcbor_state_t *state,
416 const uint8_t *payload, size_t payload_len);
417
418 /** Check that the provided fragments are complete and in the right order.
419 *
420 * If the total length is not known, the total_len can have the value
421 * @ref ZCBOR_STRING_FRAGMENT_UNKNOWN_LENGTH. If so, all fragments will be
422 * updated with the actual total length.
423 *
424 * @param[in] fragments An array of string fragments. Cannot be NULL.
425 * @param[in] num_fragments The number of fragments in @p fragments.
426 *
427 * @retval true If the fragments are in the right order, and there are no
428 * fragments missing.
429 * @retval false If not all fragments have the same total_len, or gaps are
430 * found, or if any fragment value is NULL.
431 */
432 bool zcbor_validate_string_fragments(struct zcbor_string_fragment *fragments,
433 size_t num_fragments);
434
435 /** Assemble the fragments into a single string.
436 *
437 * The fragments are copied in the order they appear, without regard for
438 * offset or total_len. To ensure that the fragments are correct, first
439 * validate with @ref zcbor_validate_string_fragments.
440 *
441 * @param[in] fragments An array of string fragments. Cannot be NULL.
442 * @param[in] num_fragments The number of fragments in @p fragments.
443 * @param[out] result The buffer to place the assembled string into.
444 * @param[inout] result_len In: The length of the @p result.
445 * Out: The length of the assembled string.
446 *
447 * @retval true On success.
448 * @retval false If the assembled string would be larger than the buffer.
449 * The buffer might still be written to.
450 */
451 bool zcbor_splice_string_fragments(struct zcbor_string_fragment *fragments,
452 size_t num_fragments, uint8_t *result, size_t *result_len);
453
454 /** Compare two struct zcbor_string instances.
455 *
456 * @param[in] str1 A string
457 * @param[in] str2 A string to compare to @p str1
458 *
459 * @retval true if the strings are identical
460 * @retval false if length or contents don't match, or one one or both strings is NULL.
461 */
462 bool zcbor_compare_strings(const struct zcbor_string *str1,
463 const struct zcbor_string *str2);
464
465 /** Calculate the length of a CBOR string, list, or map header.
466 *
467 * This can be used to find the start of the CBOR object when you have a
468 * pointer to the start of the contents. The function assumes that the header
469 * will be the shortest it can be.
470 *
471 * @param[in] num_elems The number of elements in the string, list, or map.
472 *
473 * @return The length of the header in bytes (1-9).
474 */
475 size_t zcbor_header_len(uint64_t value);
476
477 /** Like @ref zcbor_header_len but for integer of any size <= 8. */
478 size_t zcbor_header_len_ptr(const void *const value, size_t value_len);
479
480 /** If a string (header + payload) is encoded into the rest of the payload, how long would it be?
481 *
482 * Note that a string with this length doesn't necessarily fill the rest of the
483 * payload. For some payload lengths, e.g. 25, it's impossible to encode a
484 * string of that total length.
485 *
486 * @param[in] state The current state.
487 *
488 * @return The length of the string (payload, not including header) in bytes.
489 */
490 size_t zcbor_remaining_str_len(zcbor_state_t *state);
491
492 /** Convert a float16 value to float32.
493 *
494 * @param[in] input The float16 value stored in a uint16_t.
495 *
496 * @return The resulting float32 value.
497 */
498 float zcbor_float16_to_32(uint16_t input);
499
500 /** Convert a float32 value to float16.
501 *
502 * @param[in] input The float32 value.
503 *
504 * @return The resulting float16 value as a uint16_t.
505 */
506 uint16_t zcbor_float32_to_16(float input);
507
508 #ifdef ZCBOR_MAP_SMART_SEARCH
zcbor_round_up(size_t x,size_t align)509 static inline size_t zcbor_round_up(size_t x, size_t align)
510 {
511 return (((x) + (align) - 1) / (align) * (align));
512 }
513
514 #define ZCBOR_BITS_PER_BYTE 8
515 /** Calculate the number of bytes needed to hold @p num_flags 1 bit flags
516 */
zcbor_flags_to_bytes(size_t num_flags)517 static inline size_t zcbor_flags_to_bytes(size_t num_flags)
518 {
519 return zcbor_round_up(num_flags, ZCBOR_BITS_PER_BYTE) / ZCBOR_BITS_PER_BYTE;
520 }
521
522 /** Calculate the number of zcbor_state_t instances needed to hold @p num_flags 1 bit flags
523 */
zcbor_flags_to_states(size_t num_flags)524 static inline size_t zcbor_flags_to_states(size_t num_flags)
525 {
526 return zcbor_round_up(num_flags, sizeof(zcbor_state_t) * ZCBOR_BITS_PER_BYTE)
527 / (sizeof(zcbor_state_t) * ZCBOR_BITS_PER_BYTE);
528 }
529
530 #define ZCBOR_FLAG_STATES(n_flags) zcbor_flags_to_states(n_flags)
531
532 #else
533 #define ZCBOR_FLAG_STATES(n_flags) 0
534 #endif
535
536 size_t strnlen(const char *, size_t);
537
538 #ifdef __cplusplus
539 }
540 #endif
541
542 #endif /* ZCBOR_COMMON_H__ */
543