QCBOR
qcbor_decode.h
Go to the documentation of this file.
1 /* ===========================================================================
2  * Copyright (c) 2016-2018, The Linux Foundation.
3  * Copyright (c) 2018-2025, 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_decode_h
36 #define qcbor_decode_h
37 
38 
39 #include "qcbor/qcbor_common.h"
40 #include "qcbor/qcbor_private.h"
41 #include <stdbool.h>
42 
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #if 0
47 } /* Keep editor indention formatting happy */
48 #endif
49 #endif
50 
51 
190 typedef enum {
197  /* This is stored in uint8_t in places; never add values > 255 */
199 
204 #define QCBOR_MAX_DECODE_INPUT_SIZE (UINT32_MAX - 2)
205 
210 #define QCBOR_MAX_TAGS_PER_ITEM QCBOR_MAX_TAGS_PER_ITEM1
211 
212 
213 
214 /* Do not renumber these. Code depends on some of these values. */
216 #define QCBOR_TYPE_NONE 0
217 
219 #define QCBOR_TYPE_ANY 1
220 
224 #define QCBOR_TYPE_INT64 2
225 
228 #define QCBOR_TYPE_UINT64 3
229 
231 #define QCBOR_TYPE_ARRAY 4
232 
234 #define QCBOR_TYPE_MAP 5
235 
237 #define QCBOR_TYPE_BYTE_STRING 6
238 
242 #define QCBOR_TYPE_TEXT_STRING 7
243 
246 #define QCBOR_TYPE_POSBIGNUM 9
247 
250 #define QCBOR_TYPE_NEGBIGNUM 10
251 
257 #define QCBOR_TYPE_DATE_STRING 11
258 
261 #define QCBOR_TYPE_DATE_EPOCH 12
262 
270 #define QCBOR_TYPE_UKNOWN_SIMPLE 13
271 
274 #define QCBOR_TYPE_DECIMAL_FRACTION 14
275 
279 #define QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM 15
280 
284 #define QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM 16
285 
289 #define QCBOR_TYPE_BIGFLOAT 17
290 
294 #define QCBOR_TYPE_BIGFLOAT_POS_BIGNUM 18
295 
299 #define QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM 19
300 
302 #define QCBOR_TYPE_FALSE 20
303 
305 #define QCBOR_TYPE_TRUE 21
306 
308 #define QCBOR_TYPE_NULL 22
309 
311 #define QCBOR_TYPE_UNDEF 23
312 
314 #define QCBOR_TYPE_FLOAT 26
315 
317 #define QCBOR_TYPE_DOUBLE 27
318 
319 #define QCBOR_TYPE_BREAK 31 /* Used internally; never returned */
320 
323 #define QCBOR_TYPE_MAP_AS_ARRAY 32
324 
328 #define QBCOR_TYPE_WRAPPED_CBOR 36
329 
331 #define QCBOR_TYPE_URI 44
332 
335 #define QCBOR_TYPE_BASE64URL 45
336 
339 #define QCBOR_TYPE_BASE64 46
340 
342 #define QCBOR_TYPE_REGEX 47
343 
346 #define QCBOR_TYPE_MIME 48
347 
349 #define QCBOR_TYPE_UUID 49
350 
353 #define QBCOR_TYPE_WRAPPED_CBOR_SEQUENCE 75
354 
357 #define QCBOR_TYPE_BINARY_MIME 76
358 
362 #define QCBOR_TYPE_DAYS_STRING 77
363 
367 #define QCBOR_TYPE_DAYS_EPOCH 78
368 
369 #define QCBOR_TYPE_TAG 254 /* Used internally; never returned */
370 
371 #define QCBOR_TYPE_OPTTAG QCBOR_TYPE_TAG /* Depricated. See QCBOR_TYPE_TAG */
372 
373 
374 
379 #define QCBOR_LAST_UNMAPPED_TAG (CBOR_TAG_INVALID16 - QCBOR_NUM_MAPPED_TAGS - 1)
380 
381 
416 typedef struct {
417  int64_t nExponent;
418  union {
419  int64_t nInt;
420  UsefulBufC bigNum;
421  } Mantissa;
423 
424 
434 typedef struct _QCBORItem {
437  uint8_t uDataType;
438 
441  uint8_t uLabelType;
442 
445  uint8_t uNestingLevel;
446 
450  uint8_t uNextNestLevel;
451 
456  uint8_t uDataAlloc;
457 
462  uint8_t uLabelAlloc;
463 
466  union {
468  int64_t int64;
470  uint64_t uint64;
482  uint16_t uCount;
483 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
489  double dfnum;
491  float fnum;
492 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
503  struct {
504  int64_t nSeconds;
505 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
506  double fSecondsFraction;
507 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
509 
512  int64_t epochDays;
520  uint8_t uSimple;
521 #ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
522  QCBORExpAndMantissa expAndMantissa;
523 #endif /* ! QCBOR_DISABLE_EXP_AND_MANTISSA */
524  uint64_t uTagV; /* Used internally during decoding */
525 
526  } val;
527 
529  union {
531  int64_t int64;
532 #ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
534  uint64_t uint64;
538 #endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
539  } label;
540 
541 #ifndef QCBOR_DISABLE_TAGS
563 #endif
564 
566 
570 #define QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH UINT16_MAX
571 
572 
573 
574 
633 typedef UsefulBuf (* QCBORStringAllocate)(void *pAllocateCxt,
634  void *pOldMem,
635  size_t uNewSize);
636 
637 
648 #define QCBOR_DECODE_MIN_MEM_POOL_SIZE 8
649 
650 
651 
652 
660 
661 
699 void
701 
702 
751  UsefulBuf MemPool,
752  bool bAllStrings);
753 
754 
788 void
790  QCBORStringAllocate pfAllocateFunction,
791  void *pAllocateContext,
792  bool bAllStrings);
793 
794 
974 void
976 
977 
993 
994 
1017 void
1019 
1020 
1044 void
1046 
1047 
1059 QCBORError
1061 
1062 
1105 static uint32_t
1107 
1108 
1121 QCBORError
1123 
1124 
1158 uint64_t
1159 QCBORDecode_GetNthTag(QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint32_t uIndex);
1160 
1161 
1181 uint64_t
1182 QCBORDecode_GetNthTagOfLast(const QCBORDecodeContext *pCtx, uint32_t uIndex);
1183 
1184 
1223 QCBORError
1225 
1226 
1252 QCBORError
1254 
1255 
1265 static UsefulBufC
1267 
1268 
1296 static QCBORError
1298 
1299 
1309 static QCBORError
1311 
1312 
1319 static bool
1321 
1322 
1342 static bool
1344 
1345 
1366 static void
1368 
1369 
1370 
1371 
1415 static inline int
1416 QCBOR_Int64ToInt32(int64_t src, int32_t *dest)
1417 {
1418  if(src > INT32_MAX || src < INT32_MIN) {
1419  return -1;
1420  } else {
1421  *dest = (int32_t) src;
1422  }
1423  return 0;
1424 }
1425 
1426 static inline int
1427 QCBOR_Int64ToInt16(int64_t src, int16_t *dest)
1428 {
1429  if(src > INT16_MAX || src < INT16_MIN) {
1430  return -1;
1431  } else {
1432  *dest = (int16_t) src;
1433  }
1434  return 0;
1435 }
1436 
1437 static inline int
1438 QCBOR_Int64ToInt8(int64_t src, int8_t *dest)
1439 {
1440  if(src > INT8_MAX || src < INT8_MIN) {
1441  return -1;
1442  } else {
1443  *dest = (int8_t) src;
1444  }
1445  return 0;
1446 }
1447 
1448 static inline int
1449 QCBOR_Int64ToUInt32(int64_t src, uint32_t *dest)
1450 {
1451  if(src > UINT32_MAX || src < 0) {
1452  return -1;
1453  } else {
1454  *dest = (uint32_t) src;
1455  }
1456  return 0;
1457 }
1458 
1463 #define QCBOR_Int64UToInt16 QCBOR_Int64ToUInt16
1464 
1465 static inline int
1466 QCBOR_Int64ToUInt16(int64_t src, uint16_t *dest)
1467 {
1468  if(src > UINT16_MAX || src < 0) {
1469  return -1;
1470  } else {
1471  *dest = (uint16_t) src;
1472  }
1473  return 0;
1474 }
1475 
1476 static inline int
1477 QCBOR_Int64ToUInt8(int64_t src, uint8_t *dest)
1478 {
1479  if(src > UINT8_MAX || src < 0) {
1480  return -1;
1481  } else {
1482  *dest = (uint8_t) src;
1483  }
1484  return 0;
1485 }
1486 
1487 static inline int
1488 QCBOR_Int64ToUInt64(int64_t src, uint64_t *dest)
1489 {
1490  if(src < 0) {
1491  return -1;
1492  } else {
1493  *dest = (uint64_t) src;
1494  }
1495  return 0;
1496 }
1497 
1498 
1499 
1500 
1501 /* ========================================================================= *
1502  * BEGINNING OF DEPRECATED FUNCTIONS *
1503  * *
1504  * There is no plan to remove these in future versions. *
1505  * They just have been replaced by something better. *
1506  * ========================================================================= */
1507 
1512 typedef struct {
1513  uint8_t uNumTags;
1514  const uint64_t *puTags;
1515 } QCBORTagListIn;
1516 
1517 
1531 typedef struct {
1532  uint8_t uNumUsed;
1533  uint8_t uNumAllocated;
1534  uint64_t *puTags;
1535 } QCBORTagListOut;
1536 
1537 
1547 void
1549  const QCBORTagListIn *pTagList);
1550 
1551 
1577 bool
1579  const QCBORItem *pItem,
1580  uint64_t uTag);
1581 
1582 
1617 QCBORError
1619  QCBORItem *pDecodedItem,
1620  QCBORTagListOut *pTagList);
1621 
1622 
1623 /* ========================================================================= *
1624  * END OF DEPRECATED FUNCTIONS *
1625  * ========================================================================= */
1626 
1627 
1628 
1629 
1630 /* ========================================================================= *
1631  * BEGINNING OF PRIVATE INLINE IMPLEMENTATION *
1632  * ========================================================================= */
1633 
1634 static inline uint32_t
1636 {
1637  if(pMe->uLastError) {
1638  return UINT32_MAX;
1639  }
1640 
1641  /* Cast is safe because decoder input size is restricted. */
1642  return (uint32_t)UsefulInputBuf_Tell(&(pMe->InBuf));
1643 }
1644 
1645 static inline UsefulBufC
1647 {
1648  return UsefulInputBuf_RetrieveUndecodedInput(&(pMe->InBuf));
1649 }
1650 
1651 static inline QCBORError
1653 {
1654  return (QCBORError)pMe->uLastError;
1655 }
1656 
1657 static inline QCBORError
1659 {
1660  const QCBORError uReturn = (QCBORError)pMe->uLastError;
1661  pMe->uLastError = QCBOR_SUCCESS;
1662  return uReturn;
1663 }
1664 
1665 static inline bool
1667 {
1668  if(uErr >= QCBOR_START_OF_NOT_WELL_FORMED_ERRORS &&
1669  uErr <= QCBOR_END_OF_NOT_WELL_FORMED_ERRORS) {
1670  return true;
1671  } else {
1672  return false;
1673  }
1674 }
1675 
1676 static inline bool
1678 {
1679  if(uErr >= QCBOR_START_OF_UNRECOVERABLE_DECODE_ERRORS &&
1680  uErr <= QCBOR_END_OF_UNRECOVERABLE_DECODE_ERRORS) {
1681  return true;
1682  } else {
1683  return false;
1684  }
1685 }
1686 
1687 
1688 static inline void
1690 {
1691  pMe->uLastError = (uint8_t)uError;
1692 }
1693 
1694 /* ======================================================================== *
1695  * END OF PRIVATE INLINE IMPLEMENTATION *
1696  * ======================================================================== */
1697 
1698 
1699 /* A few cross checks on size constants and special value lengths */
1700 #if QCBOR_MAP_OFFSET_CACHE_INVALID < QCBOR_MAX_DECODE_INPUT_SIZE
1701 #error QCBOR_MAP_OFFSET_CACHE_INVALID is too large
1702 #endif
1703 
1704 #if QCBOR_NON_BOUNDED_OFFSET < QCBOR_MAX_DECODE_INPUT_SIZE
1705 #error QCBOR_NON_BOUNDED_OFFSET is too large
1706 #endif
1707 
1708 #ifdef __cplusplus
1709 }
1710 #endif
1711 
1712 #endif /* qcbor_decode_h */
struct q_useful_buf UsefulBuf
static UsefulBufC UsefulInputBuf_RetrieveUndecodedInput(UsefulInputBuf *pUInBuf)
Retrieve the undecoded input buffer.
Definition: UsefulBuf.h:2548
static size_t UsefulInputBuf_Tell(UsefulInputBuf *pUInBuf)
Returns current position in input buffer.
Definition: UsefulBuf.h:2290
QCBORError
Definition: qcbor_common.h:265
@ QCBOR_SUCCESS
Definition: qcbor_common.h:267
void QCBORDecode_SetCallerConfiguredTagList(QCBORDecodeContext *pCtx, const QCBORTagListIn *pTagList)
Deprecated – Configure list of caller-selected tags to be recognized.
QCBORError QCBORDecode_PartialFinish(QCBORDecodeContext *pCtx, size_t *puConsumed)
Return number of bytes consumed so far.
void QCBORDecode_VGetNext(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem)
Get the next item (integer, byte string, array...) in the preorder traversal of the CBOR tree.
#define QCBOR_MAX_TAGS_PER_ITEM
Definition: qcbor_decode.h:210
uint64_t QCBORDecode_GetNthTagOfLast(const QCBORDecodeContext *pCtx, uint32_t uIndex)
Returns the tag numbers for last-decoded item.
QCBORError QCBORDecode_GetNextWithTags(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem, QCBORTagListOut *pTagList)
Deprecated – Gets the next item including full list of tags for item.
static void QCBORDecode_SetError(QCBORDecodeContext *pCtx, QCBORError uError)
Manually set error condition, or set user-defined error.
Definition: qcbor_decode.h:1689
QCBORError QCBORDecode_EndCheck(QCBORDecodeContext *pCtx)
Tell whether cursor is at end of the input.
QCBORError QCBORDecode_GetNext(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem)
Preorder traversal like QCBORDecode_VGetNext() without use of internal error state.
static QCBORError QCBORDecode_GetAndResetError(QCBORDecodeContext *pCtx)
Get and reset the decoding error.
Definition: qcbor_decode.h:1658
static bool QCBORDecode_IsUnrecoverableError(QCBORError uErr)
Whether a decoding error is recoverable.
Definition: qcbor_decode.h:1677
void QCBORDecode_VPeekNext(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem)
Get the next data item without consuming it.
QCBORError QCBORDecode_Finish(QCBORDecodeContext *pCtx)
Check that a decode completed successfully.
static UsefulBufC QCBORDecode_RetrieveUndecodedInput(QCBORDecodeContext *pCtx)
Retrieve the undecoded input buffer.
Definition: qcbor_decode.h:1646
uint64_t QCBORDecode_GetNthTag(QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint32_t uIndex)
Returns the tag numbers for an item.
void QCBORDecode_VGetNextConsume(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem)
Get the next item, fully consuming it if it is a map or array.
bool QCBORDecode_IsTagged(QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint64_t uTag)
Deprecated – Determine if a CBOR item is a particular tag.
void QCBORDecode_Init(QCBORDecodeContext *pCtx, UsefulBufC EncodedCBOR, QCBORDecodeMode nMode)
void QCBORDecode_SetUpAllocator(QCBORDecodeContext *pCtx, QCBORStringAllocate pfAllocateFunction, void *pAllocateContext, bool bAllStrings)
Sets up a custom string allocator for indefinite-length strings.
UsefulBuf(* QCBORStringAllocate)(void *pAllocateCxt, void *pOldMem, size_t uNewSize)
Prototype for the implementation of a string allocator.
Definition: qcbor_decode.h:633
static bool QCBORDecode_IsNotWellFormedError(QCBORError uErr)
Whether an error indicates non-well-formed CBOR.
Definition: qcbor_decode.h:1666
static int QCBOR_Int64ToInt32(int64_t src, int32_t *dest)
Convert int64_t to smaller integers safely.
Definition: qcbor_decode.h:1416
QCBORError QCBORDecode_PeekNext(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem)
Get the next data item without consuming it without use of internal error state.
static QCBORError QCBORDecode_GetError(QCBORDecodeContext *pCtx)
Get the decoding error.
Definition: qcbor_decode.h:1652
QCBORError QCBORDecode_SetMemPool(QCBORDecodeContext *pCtx, UsefulBuf MemPool, bool bAllStrings)
Set up the MemPool string allocator for indefinite-length strings.
static uint32_t QCBORDecode_Tell(QCBORDecodeContext *pCtx)
Get the current traversal cursort offset in the input CBOR.
Definition: qcbor_decode.h:1635
struct _QCBORItem QCBORItem
QCBORDecodeMode
Definition: qcbor_decode.h:190
@ QCBOR_DECODE_MODE_NORMAL
Definition: qcbor_decode.h:192
@ QCBOR_DECODE_MODE_MAP_STRINGS_ONLY
Definition: qcbor_decode.h:194
@ QCBOR_DECODE_MODE_MAP_AS_ARRAY
Definition: qcbor_decode.h:196
Definition: qcbor_private.h:342
Definition: qcbor_decode.h:434
union _QCBORItem::@2 label
UsefulBufC bigNum
Definition: qcbor_decode.h:518
uint8_t uSimple
Definition: qcbor_decode.h:520
UsefulBufC string
Definition: qcbor_decode.h:475
uint8_t uLabelAlloc
Definition: qcbor_decode.h:462
double dfnum
Definition: qcbor_decode.h:489
int64_t epochDays
Definition: qcbor_decode.h:512
float fnum
Definition: qcbor_decode.h:491
int64_t int64
Definition: qcbor_decode.h:468
uint64_t uint64
Definition: qcbor_decode.h:470
uint8_t uDataAlloc
Definition: qcbor_decode.h:456
UsefulBufC dateString
Definition: qcbor_decode.h:515
union _QCBORItem::@1 val
uint8_t uDataType
Definition: qcbor_decode.h:437
uint8_t uNestingLevel
Definition: qcbor_decode.h:445
uint8_t uLabelType
Definition: qcbor_decode.h:441
uint8_t uNextNestLevel
Definition: qcbor_decode.h:450
struct _QCBORItem::@1::@3 epochDate
uint16_t uTags[QCBOR_MAX_TAGS_PER_ITEM]
Definition: qcbor_decode.h:562
uint16_t uCount
Definition: qcbor_decode.h:482
Definition: qcbor_decode.h:416
Definition: qcbor_decode.h:1512
Definition: qcbor_decode.h:1531
Definition: UsefulBuf.h:273
Definition: UsefulBuf.h:284