QCBOR
qcbor_private.h
1 /* ==========================================================================
2  * Copyright (c) 2016-2018, The Linux Foundation.
3  * Copyright (c) 2018-2024, Laurence Lundblade.
4  * Copyright (c) 2021, Arm Limited.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are
9  * met:
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following
14  * disclaimer in the documentation and/or other materials provided
15  * with the distribution.
16  * * Neither the name of The Linux Foundation nor the names of its
17  * contributors, nor the name "Laurence Lundblade" may be used to
18  * endorse or promote products derived from this software without
19  * specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
22  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  * ========================================================================= */
33 
34 
35 #ifndef qcbor_private_h
36 #define qcbor_private_h
37 
38 
39 #include <stdint.h>
40 #include "UsefulBuf.h"
41 #include "qcbor/qcbor_common.h"
42 
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #if 0
47 } // Keep editor indention formatting happy
48 #endif
49 #endif
50 
51 
52 /* This was originally defined as QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA,
53  * but this is inconsistent with all the other QCBOR_DISABLE_
54  * #defines, so the name was changed and this was added for backwards
55  * compatibility
56  */
57 #ifdef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
58 #define QCBOR_DISABLE_EXP_AND_MANTISSA
59 #endif
60 
61 /* If USEFULBUF_DISABLE_ALL_FLOATis defined then define
62  * QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
63  */
64 #ifdef USEFULBUF_DISABLE_ALL_FLOAT
65 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
66 #define QCBOR_DISABLE_FLOAT_HW_USE
67 #endif /* QCBOR_DISABLE_FLOAT_HW_USE */
68 #ifndef QCBOR_DISABLE_PREFERRED_FLOAT
69 #define QCBOR_DISABLE_PREFERRED_FLOAT
70 #endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
71 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
72 
73 
74 /*
75  * Convenience macro for selecting the proper return value in case floating
76  * point feature(s) are disabled.
77  *
78  * The macros:
79  *
80  * FLOAT_ERR_CODE_NO_FLOAT(x) Can be used when disabled floating point should
81  * result error, and all other cases should return
82  * 'x'.
83  *
84  * The below macros always return QCBOR_ERR_ALL_FLOAT_DISABLED when all
85  * floating point is disabled.
86  *
87  * FLOAT_ERR_CODE_NO_HALF_PREC(x) Can be used when disabled preferred float
88  * results in error, and all other cases should
89  * return 'x'.
90  * FLOAT_ERR_CODE_NO_FLOAT_HW(x) Can be used when disabled hardware floating
91  * point results in error, and all other cases
92  * should return 'x'.
93  * FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) Can be used when either disabled
94  * preferred float or disabling
95  * hardware floating point results in
96  * error, and all other cases should
97  * return 'x'.
98  */
99 #ifdef USEFULBUF_DISABLE_ALL_FLOAT
100  #define FLOAT_ERR_CODE_NO_FLOAT(x) QCBOR_ERR_ALL_FLOAT_DISABLED
101  #define FLOAT_ERR_CODE_NO_HALF_PREC(x) QCBOR_ERR_ALL_FLOAT_DISABLED
102  #define FLOAT_ERR_CODE_NO_FLOAT_HW(x) QCBOR_ERR_ALL_FLOAT_DISABLED
103  #define FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) QCBOR_ERR_ALL_FLOAT_DISABLED
104 #else /* USEFULBUF_DISABLE_ALL_FLOAT*/
105  #define FLOAT_ERR_CODE_NO_FLOAT(x) x
106  #ifdef QCBOR_DISABLE_PREFERRED_FLOAT
107  #define FLOAT_ERR_CODE_NO_HALF_PREC(x) QCBOR_ERR_HALF_PRECISION_DISABLED
108  #define FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) QCBOR_ERR_HALF_PRECISION_DISABLED
109  #else /* QCBOR_DISABLE_PREFERRED_FLOAT */
110  #define FLOAT_ERR_CODE_NO_HALF_PREC(x) x
111  #ifdef QCBOR_DISABLE_FLOAT_HW_USE
112  #define FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) QCBOR_ERR_HW_FLOAT_DISABLED
113  #else
114  #define FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) x
115  #endif
116  #endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
117  #ifdef QCBOR_DISABLE_FLOAT_HW_USE
118  #define FLOAT_ERR_CODE_NO_FLOAT_HW(x) QCBOR_ERR_HW_FLOAT_DISABLED
119  #else /* QCBOR_DISABLE_FLOAT_HW_USE */
120  #define FLOAT_ERR_CODE_NO_FLOAT_HW(x) x
121  #endif /* QCBOR_DISABLE_FLOAT_HW_USE */
122 #endif /*USEFULBUF_DISABLE_ALL_FLOAT*/
123 
124 
125 /*
126  * These are special values for the AdditionalInfo bits that are part of
127  * the first byte. Mostly they encode the length of the data item.
128  */
129 #define LEN_IS_ONE_BYTE 24
130 #define LEN_IS_TWO_BYTES 25
131 #define LEN_IS_FOUR_BYTES 26
132 #define LEN_IS_EIGHT_BYTES 27
133 #define ADDINFO_RESERVED1 28
134 #define ADDINFO_RESERVED2 29
135 #define ADDINFO_RESERVED3 30
136 #define LEN_IS_INDEFINITE 31
137 
138 
139 /*
140  * 24 is a special number for CBOR. Integers and lengths
141  * less than it are encoded in the same byte as the major type.
142  */
143 #define CBOR_TWENTY_FOUR 24
144 
145 
146 /*
147  * Values for the 5 bits for items of major type 7
148  */
149 #define CBOR_SIMPLEV_FALSE 20
150 #define CBOR_SIMPLEV_TRUE 21
151 #define CBOR_SIMPLEV_NULL 22
152 #define CBOR_SIMPLEV_UNDEF 23
153 #define CBOR_SIMPLEV_ONEBYTE 24
154 #define HALF_PREC_FLOAT 25
155 #define SINGLE_PREC_FLOAT 26
156 #define DOUBLE_PREC_FLOAT 27
157 #define CBOR_SIMPLE_BREAK 31
158 #define CBOR_SIMPLEV_RESERVED_START CBOR_SIMPLEV_ONEBYTE
159 #define CBOR_SIMPLEV_RESERVED_END CBOR_SIMPLE_BREAK
160 
161 
162 /* The largest offset to the start of an array or map. It is slightly
163  * less than UINT32_MAX so the error condition can be tested on 32-bit
164  * machines. UINT32_MAX comes from uStart in QCBORTrackNesting being
165  * a uin32_t.
166  *
167  * This will cause trouble on a machine where size_t is less than 32-bits.
168  */
169 #define QCBOR_MAX_ARRAY_OFFSET (UINT32_MAX - 100)
170 
171 
172 /* The number of tags that are 16-bit or larger that can be handled
173  * in a decode.
174  */
175 #define QCBOR_NUM_MAPPED_TAGS 4
176 
177 /* The number of tags (of any size) recorded for an individual item. */
178 #define QCBOR_MAX_TAGS_PER_ITEM1 4
179 
180 
181 
182 
183 /*
184  * PRIVATE DATA STRUCTURE
185  *
186  * Holds the data for tracking array and map nesting during
187  * encoding. Pairs up with the Nesting_xxx functions to make an
188  * "object" to handle nesting encoding.
189  *
190  * uStart is a uint32_t instead of a size_t to keep the size of this
191  * struct down so it can be on the stack without any concern. It
192  * would be about double if size_t was used instead.
193  *
194  * Size approximation (varies with CPU/compiler):
195  * 64-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 8 = 136 bytes
196  * 32-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 4 = 132 bytes
197  */
198 typedef struct __QCBORTrackNesting {
199  /* PRIVATE DATA STRUCTURE */
200  struct {
201  /* See QCBOREncode_OpenMapOrArray() for details on how this works */
202  uint32_t uStart; /* uStart is the position where the array starts */
203  uint16_t uCount; /* Number of items in the arrary or map; counts items
204  * in a map, not pairs of items */
205  uint8_t uMajorType; /* Indicates if item is a map or an array */
206  } pArrays[QCBOR_MAX_ARRAY_NESTING+1], /* stored state for nesting levels */
207  *pCurrentNesting; /* the current nesting level */
209 
210 
211 /*
212  * PRIVATE DATA STRUCTURE
213  *
214  * Context / data object for encoding some CBOR. Used by all encode
215  * functions to form a public "object" that does the job of encdoing.
216  *
217  * Size approximation (varies with CPU/compiler):
218  * 64-bit machine: 27 + 1 (+ 4 padding) + 136 = 32 + 136 = 168 bytes
219  * 32-bit machine: 15 + 1 + 132 = 148 bytes
220  */
222  /* PRIVATE DATA STRUCTURE */
223  UsefulOutBuf OutBuf; /* Pointer to output buffer, its length and
224  * position in it. */
225  uint8_t uError; /* Error state, always from QCBORError enum */
226  QCBORTrackNesting nesting; /* Keep track of array and map nesting */
227 };
228 
229 
230 /*
231  * PRIVATE DATA STRUCTURE
232  *
233  * Holds the data for array and map nesting for decoding work. This
234  * structure and the DecodeNesting_Xxx() functions in qcbor_decode.c
235  * form an "object" that does the work for arrays and maps. All access
236  * to this structure is through DecodeNesting_Xxx() functions.
237  *
238  * 64-bit machine size
239  * 128 = 16 * 8 for the two unions
240  * 64 = 16 * 4 for the uLevelType, 1 byte padded to 4 bytes for alignment
241  * 16 = 16 bytes for two pointers
242  * 208 TOTAL
243  *
244  * 32-bit machine size is 200 bytes
245  */
246 typedef struct __QCBORDecodeNesting {
247  /* PRIVATE DATA STRUCTURE */
249  /*
250  * This keeps tracking info for each nesting level. There are two
251  * main types of levels:
252  * 1) Byte count tracking. This is for the top level input CBOR
253  * which might be a single item or a CBOR sequence and byte
254  * string wrapped encoded CBOR.
255  * 2) Item count tracking. This is for maps and arrays.
256  *
257  * uLevelType has value QCBOR_TYPE_BYTE_STRING for 1) and
258  * QCBOR_TYPE_MAP or QCBOR_TYPE_ARRAY or QCBOR_TYPE_MAP_AS_ARRAY
259  * for 2).
260  *
261  * Item count tracking is either for definite or indefinite-length
262  * maps/arrays. For definite lengths, the total count and items
263  * unconsumed are tracked. For indefinite-length, uTotalCount is
264  * QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH (UINT16_MAX) and
265  * there is no per-item count of members. For indefinite-length
266  * maps and arrays, uCountCursor is UINT16_MAX if not consumed
267  * and zero if it is consumed in the pre-order
268  * traversal. Additionally, if entered in bounded mode,
269  * uCountCursor is QCBOR_COUNT_INDICATES_ZERO_LENGTH to indicate
270  * it is empty.
271  *
272  * This also records whether a level is bounded or not. All
273  * byte-count tracked levels (the top-level sequence and
274  * bstr-wrapped CBOR) are bounded implicitly. Maps and arrays
275  * may or may not be bounded. They are bounded if they were
276  * Entered() and not if they were traversed with GetNext(). They
277  * are marked as bounded by uStartOffset not being @c UINT32_MAX.
278  */
279  /*
280  * If uLevelType can put in a separately indexed array, the
281  * union/struct will be 8 bytes rather than 9 and a lot of
282  * wasted padding for alignment will be saved.
283  */
284  uint8_t uLevelType;
285  union {
286  struct {
287 #define QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH UINT16_MAX
288 #define QCBOR_COUNT_INDICATES_ZERO_LENGTH UINT16_MAX-1
289  uint16_t uCountTotal;
290  uint16_t uCountCursor;
291 #define QCBOR_NON_BOUNDED_OFFSET UINT32_MAX
292  /* The start of the array or map in bounded mode so
293  * the input can be rewound for GetInMapXx() by label. */
294  uint32_t uStartOffset;
295  } ma; /* for maps and arrays */
296  struct {
297  /* The end of the input before the bstr was entered so that
298  * it can be restored when the bstr is exited. */
299  uint32_t uSavedEndOffset;
300  /* The beginning of the bstr so that it can be rewound. */
301  uint32_t uBstrStartOffset;
302  } bs; /* for top-level sequence and bstr-wrapped CBOR */
303  } u;
304  } pLevels[QCBOR_MAX_ARRAY_NESTING+1],
305  *pCurrent,
306  *pCurrentBounded;
307  /*
308  * pCurrent is for item-by-item pre-order traversal.
309  *
310  * pCurrentBounded points to the current bounding level or is NULL
311  * if there isn't one.
312  *
313  * pCurrent must always be below pCurrentBounded as the pre-order
314  * traversal is always bounded by the bounding level.
315  *
316  * When a bounded level is entered, the pre-order traversal is set
317  * to the first item in the bounded level. When a bounded level is
318  * exited, the pre-order traversl is set to the next item after the
319  * map, array or bstr. This may be more than one level up, or even
320  * the end of the input CBOR.
321  */
323 
324 
325 typedef struct {
326  /* PRIVATE DATA STRUCTURE */
327  void *pAllocateCxt;
328  UsefulBuf (* pfAllocator)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
330 
331 
332 /*
333  * PRIVATE DATA STRUCTURE
334  *
335  * The decode context. This data structure plus the public
336  * QCBORDecode_xxx functions form an "object" that does CBOR decoding.
337  *
338  * Size approximation (varies with CPU/compiler):
339  * 64-bit machine: 32 + 1 + 1 + 6 bytes padding + 72 + 16 + 8 + 8 = 144 bytes
340  * 32-bit machine: 16 + 1 + 1 + 2 bytes padding + 68 + 8 + 8 + 4 = 108 bytes
341  */
343  /* PRIVATE DATA STRUCTURE */
344  UsefulInputBuf InBuf;
345 
346  QCBORDecodeNesting nesting;
347 
348  /* If a string allocator is configured for indefinite-length
349  * strings, it is configured here.
350  */
351  QCBORInternalAllocator StringAllocator;
352 
353  /* These are special for the internal MemPool allocator. They are
354  * not used otherwise. We tried packing these in the MemPool
355  * itself, but there are issues with memory alignment.
356  */
357  uint32_t uMemPoolSize;
358  uint32_t uMemPoolFreeOffset;
359 
360  /* A cached offset to the end of the current map 0 if no value is
361  * cached.
362  */
363 #define QCBOR_MAP_OFFSET_CACHE_INVALID UINT32_MAX
364  uint32_t uMapEndOffsetCache;
365 
366  uint8_t uDecodeMode;
367  uint8_t bStringAllocateAll;
368  uint8_t uLastError; /* QCBORError stuffed into a uint8_t */
369 
370  /* See MapTagNumber() for description of how tags are mapped. */
371  uint64_t auMappedTags[QCBOR_NUM_MAPPED_TAGS];
372 
373  uint16_t uLastTags[QCBOR_MAX_TAGS_PER_ITEM1];
374 };
375 
376 
377 /* Used internally in the impementation here Must not conflict with
378  * any of the official CBOR types
379  */
380 #define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
381 #define CBOR_MAJOR_NONE_TYPE_OPEN_BSTR 12
382 
383 
384 /* Add this to types to indicate they are to be encoded as indefinite lengths */
385 #define QCBOR_INDEFINITE_LEN_TYPE_MODIFIER 0x80
386 #define CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN \
387  CBOR_MAJOR_TYPE_ARRAY + QCBOR_INDEFINITE_LEN_TYPE_MODIFIER
388 #define CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN \
389  CBOR_MAJOR_TYPE_MAP + QCBOR_INDEFINITE_LEN_TYPE_MODIFIER
390 #define CBOR_MAJOR_NONE_TYPE_SIMPLE_BREAK \
391  CBOR_MAJOR_TYPE_SIMPLE + QCBOR_INDEFINITE_LEN_TYPE_MODIFIER
392 
393 
394 /* Value of QCBORItem.val.string.len when the string length is
395  * indefinite. Used temporarily in the implementation and never
396  * returned in the public interface.
397  */
398 #define QCBOR_STRING_LENGTH_INDEFINITE SIZE_MAX
399 
400 
401 /* The number of elements in a C array of a particular type */
402 #define C_ARRAY_COUNT(array, type) (sizeof(array)/sizeof(type))
403 
404 
405 #ifdef __cplusplus
406 }
407 #endif
408 
409 #endif /* qcbor_private_h */
struct q_useful_buf UsefulBuf
#define QCBOR_MAX_ARRAY_NESTING
Definition: qcbor_common.h:577
Definition: qcbor_private.h:248
Definition: qcbor_private.h:246
Definition: qcbor_private.h:198
Definition: qcbor_private.h:342
Definition: qcbor_private.h:221
Definition: qcbor_private.h:325
Definition: UsefulBuf.h:1459
Definition: UsefulBuf.h:845