merge from dev
diff --git a/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
index df365fe..6c85e05 100644
--- a/inc/qcbor/qcbor_decode.h
+++ b/inc/qcbor/qcbor_decode.h
@@ -190,10 +190,31 @@
typedef enum {
/** See QCBORDecode_Init() */
QCBOR_DECODE_MODE_NORMAL = 0,
+
/** See QCBORDecode_Init() */
- QCBOR_DECODE_MODE_MAP_STRINGS_ONLY = 1,
+ QCBOR_DECODE_MODE_MAP_STRINGS_ONLY = 0x01,
+
/** See QCBORDecode_Init() */
- QCBOR_DECODE_MODE_MAP_AS_ARRAY = 2,
+ QCBOR_DECODE_MODE_MAP_AS_ARRAY = 0x02,
+
+ /** Makes QCBOR v2 compatible with v1. The error @ref QCBOR_ERR_UNPROCESSED_TAG_NUMBER is not returned.
+ * This can be or'd with the above modes. */
+ QCBOR_DECODE_UNPROCESSED_TAG_NUMBERS = 0x04,
+
+ /** Error out on indefinite length strings, arrays and maps */
+ QCBOR_DECODE_NO_INDEF_LENGTH = 0x08,
+
+ /** Error out if integers or floats are encoded as preferred. */
+ QCBOR_DECODE_ONLY_PREFERRED_NUMBERS = 0x10,
+
+ QCBOR_DECODE_ONLY_PREFERRED_BIG_NUMBERS = 0x20,
+
+ QCBOR_DECODE_ONLY_SORTED_MAPS = 0x40,
+
+ QCBOR_DECODE_ONLY_REDUCED_FLOATS = 0x80,
+
+ QCBOR_DECODE_DISALLOW_DCBOR_SIMPLES = 0x100,
+
/**
* This checks that the input is encoded with preferred
* serialization. The checking is performed as each item is
@@ -205,7 +226,9 @@
* lengths and tags, must be in shortest form, and floating-point
* numbers must be reduced to shortest form all the way to
* half-precision. */
- QCBOR_DECODE_MODE_PREFERRED = 3,
+ QCBOR_DECODE_MODE_PREFERRED = QCBOR_DECODE_NO_INDEF_LENGTH |
+ QCBOR_DECODE_ONLY_PREFERRED_NUMBERS |
+ QCBOR_DECODE_ONLY_PREFERRED_BIG_NUMBERS,
/** This checks that maps in the input are sorted by label as
* described in RFC 8949 section 4.2.1. This also performs
@@ -215,20 +238,17 @@
*
* This also performs all the checks that
* QCBOR_DECODE_MODE_PREFERRED does. */
- QCBOR_DECODE_MODE_CDE = 4,
-
+ QCBOR_DECODE_MODE_CDE = QCBOR_DECODE_MODE_PREFERRED |
+ QCBOR_DECODE_ONLY_SORTED_MAPS,
+
/** This requires integer-float unification. It performs all the checks that
* QCBOR_DECODE_MODE_CDE does. */
- QCBOR_DECODE_MODE_DCBOR = 5,
+ QCBOR_DECODE_MODE_DCBOR = QCBOR_DECODE_MODE_CDE |
+ QCBOR_DECODE_ONLY_REDUCED_FLOATS |
+ QCBOR_DECODE_DISALLOW_DCBOR_SIMPLES,
- /** Makes QCBOR v2 compatible with v1. The error @ref QCBOR_ERR_UNPROCESSED_TAG_NUMBER is not returned.
- * This can be or'd with the above modes. */
- QCBOR_DECODE_UNPROCESSED_TAG_NUMBERS = 8,
-
- /* This is stored in uint8_t in places; never add values > 255 */
} QCBORDecodeMode;
-#define QCBOR_DECODE_MODE_MASK 0x07
/**
diff --git a/inc/qcbor/qcbor_private.h b/inc/qcbor/qcbor_private.h
index e69f97f..f860c49 100644
--- a/inc/qcbor/qcbor_private.h
+++ b/inc/qcbor/qcbor_private.h
@@ -256,7 +256,7 @@
* 32-bit machine size is 200 bytes
*/
typedef struct __QCBORDecodeNesting {
- /* PRIVATE DATA STRUCTURE */
+ /* PRIVATE DATA STRUCTURE */
struct nesting_decode_level {
/*
* This keeps tracking info for each nesting level. There are two
@@ -346,6 +346,7 @@
typedef uint16_t QCBORMappedTagNumbers[QCBOR_MAX_TAGS_PER_ITEM1];
+
/*
* PRIVATE DATA STRUCTURE
*
@@ -380,7 +381,7 @@
#define QCBOR_MAP_OFFSET_CACHE_INVALID UINT32_MAX
uint32_t uMapEndOffsetCache;
- uint8_t uDecodeMode;
+ uint32_t uDecodeMode;
uint8_t bStringAllocateAll;
uint8_t uLastError; /* QCBORError stuffed into a uint8_t */
uint8_t bAllowAllLabels; /* Used internally only, not an external feature yet */
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index fd16322..13f1f2f 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -647,14 +647,14 @@
void
QCBORDecode_Init(QCBORDecodeContext *pMe,
UsefulBufC EncodedCBOR,
- QCBORDecodeMode nDecodeMode)
+ QCBORDecodeMode uConfigFlags)
{
memset(pMe, 0, sizeof(QCBORDecodeContext));
UsefulInputBuf_Init(&(pMe->InBuf), EncodedCBOR);
/* Don't bother with error check on decode mode. If a bad value is
* passed it will just act as if the default normal mode of 0 was set.
*/
- pMe->uDecodeMode = (uint8_t)nDecodeMode;
+ pMe->uDecodeMode = (uint32_t)uConfigFlags;
DecodeNesting_Init(&(pMe->nesting));
/* Inialize me->auMappedTags to CBOR_TAG_INVALID16. See
@@ -766,7 +766,7 @@
* @brief Decode the CBOR head, the type and argument.
*
* @param[in] pUInBuf The input buffer to read from.
- * @param[in] bRequirePreferred Require preferred serialization for argument.
+ * @param[in] uConfigFlags Decode mode flags.
* @param[out] pnMajorType The decoded major type.
* @param[out] puArgument The decoded argument.
* @param[out] pnAdditionalInfo The decoded Lower 5 bits of initial byte.
@@ -786,9 +786,9 @@
* analyzers happier.
*/
static QCBORError
-QCBOR_Private_DecodeHead(UsefulInputBuf *pUInBuf,
+QCBOR_Private_DecodeHead(UsefulInputBuf *pUInBuf,
#ifndef QCBOR_DISABLE_DECODE_CONFORMANCE
- bool bRequirePreferred,
+ QCBORDecodeMode uConfigFlags,
#endif
int *pnMajorType,
uint64_t *puArgument,
@@ -817,7 +817,7 @@
#ifndef QCBOR_DISABLE_DECODE_CONFORMANCE
/* If requested, check that argument is in preferred form */
- if(bRequirePreferred) {
+ if(uConfigFlags & QCBOR_DECODE_ONLY_PREFERRED_NUMBERS) {
uint64_t uMinArgument;
if(nAdditionalInfo == LEN_IS_ONE_BYTE) {
@@ -845,7 +845,7 @@
goto Done;
} else {
#ifndef QCBOR_DISABLE_DECODE_CONFORMANCE
- if(bRequirePreferred && nAdditionalInfo == LEN_IS_INDEFINITE) {
+ if(uConfigFlags & QCBOR_DECODE_NO_INDEF_LENGTH && nAdditionalInfo == LEN_IS_INDEFINITE) {
uReturn = QCBOR_ERR_PREFERRED_CONFORMANCE;
goto Done;
}
@@ -1047,7 +1047,7 @@
/**
* @brief Decode array or map.
*
- * @param[in] uDecodeMode3Bit Decoder mode.
+ * @param[in] uConfigFlags Decoder mode.
* @param[in] nMajorType Whether it is a byte or text string.
* @param[in] uItemCount The length of the string.
* @param[in] nAdditionalInfo Whether it is an indefinite-length.
@@ -1066,11 +1066,11 @@
* QCBOR_DISABLE_NON_INTEGER_LABELS.
*/
static QCBORError
-QCBOR_Private_DecodeArrayOrMap(const uint8_t uDecodeMode3Bit,
- const int nMajorType,
- uint64_t uItemCount,
- const int nAdditionalInfo,
- QCBORItem *pDecodedItem)
+QCBOR_Private_DecodeArrayOrMap(const QCBORDecodeMode uConfigFlags,
+ const int nMajorType,
+ uint64_t uItemCount,
+ const int nAdditionalInfo,
+ QCBORItem *pDecodedItem)
{
QCBORError uReturn;
@@ -1084,7 +1084,7 @@
#endif
pDecodedItem->uDataType = (uint8_t)nMajorType;
#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
- if(uDecodeMode3Bit == QCBOR_DECODE_MODE_MAP_AS_ARRAY && nMajorType == QCBOR_TYPE_MAP) {
+ if((uConfigFlags & QCBOR_DECODE_MODE_MAP_AS_ARRAY) && nMajorType == QCBOR_TYPE_MAP) {
pDecodedItem->uDataType = QCBOR_TYPE_MAP_AS_ARRAY;
}
#else
@@ -1107,7 +1107,7 @@
} else {
#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
- if(uDecodeMode3Bit == QCBOR_DECODE_MODE_MAP_AS_ARRAY && nMajorType == QCBOR_TYPE_MAP) {
+ if((uConfigFlags & QCBOR_DECODE_MODE_MAP_AS_ARRAY) && nMajorType == QCBOR_TYPE_MAP) {
/* ------ Map as array ------ */
uItemCount *= 2;
}
@@ -1162,7 +1162,7 @@
#if !defined(QCBOR_DISABLE_DECODE_CONFORMANCE) && !defined(QCBOR_DISABLE_PREFERRED_FLOAT)
static QCBORError
-QCBORDecode_Private_HalfConformance(const double d, const uint8_t uDecodeMode3Bit)
+QCBORDecode_Private_HalfConformance(const double d, const QCBORDecodeMode uConfigFlags)
{
struct IEEE754_ToInt ToInt;
@@ -1176,7 +1176,7 @@
* The only thing allowed here is a double/half-precision that
* can't be converted to anything but a double.
*/
- if(uDecodeMode3Bit >= QCBOR_DECODE_MODE_DCBOR) {
+ if(uConfigFlags & QCBOR_DECODE_ONLY_REDUCED_FLOATS) {
ToInt = IEEE754_DoubleToInt(d);
if(ToInt.type != QCBOR_TYPE_DOUBLE) {
return QCBOR_ERR_DCBOR_CONFORMANCE;
@@ -1188,12 +1188,12 @@
static QCBORError
-QCBORDecode_Private_SingleConformance(const float f, const uint8_t uDecodeMode3Bit)
+QCBORDecode_Private_SingleConformance(const float f, const QCBORDecodeMode uconfigFlags)
{
struct IEEE754_ToInt ToInt;
IEEE754_union ToSmaller;
- if(uDecodeMode3Bit >= QCBOR_DECODE_MODE_DCBOR) {
+ if(uconfigFlags & QCBOR_DECODE_ONLY_REDUCED_FLOATS) {
/* See if it could have been encoded as an integer */
ToInt = IEEE754_SingleToInt(f);
if(ToInt.type == IEEE754_ToInt_IS_INT || ToInt.type == IEEE754_ToInt_IS_UINT) {
@@ -1207,7 +1207,7 @@
}
/* See if it could have been encoded shorter */
- if(uDecodeMode3Bit >= QCBOR_DECODE_MODE_PREFERRED) {
+ if(uconfigFlags & QCBOR_DECODE_ONLY_PREFERRED_NUMBERS) {
ToSmaller = IEEE754_SingleToHalf(f, true);
if(ToSmaller.uSize != sizeof(float)) {
return QCBOR_ERR_PREFERRED_CONFORMANCE;
@@ -1219,12 +1219,12 @@
static QCBORError
-QCBORDecode_Private_DoubleConformance(const double d, uint8_t uDecodeMode3Bit)
+QCBORDecode_Private_DoubleConformance(const double d, QCBORDecodeMode uConfigFlags)
{
struct IEEE754_ToInt ToInt;
IEEE754_union ToSmaller;
- if(uDecodeMode3Bit >= QCBOR_DECODE_MODE_DCBOR) {
+ if(uConfigFlags & QCBOR_DECODE_ONLY_REDUCED_FLOATS) {
/* See if it could have been encoded as an integer */
ToInt = IEEE754_DoubleToInt(d);
if(ToInt.type == IEEE754_ToInt_IS_INT || ToInt.type == IEEE754_ToInt_IS_UINT) {
@@ -1237,7 +1237,7 @@
}
/* See if it could have been encoded shorter */
- if(uDecodeMode3Bit >= QCBOR_DECODE_MODE_PREFERRED) {
+ if(uConfigFlags & QCBOR_DECODE_ONLY_PREFERRED_NUMBERS) {
ToSmaller = IEEE754_DoubleToSmaller(d, true, true);
if(ToSmaller.uSize != sizeof(double)) {
return QCBOR_ERR_PREFERRED_CONFORMANCE;
@@ -1249,10 +1249,10 @@
#else /* ! QCBOR_DISABLE_DECODE_CONFORMANCE && ! QCBOR_DISABLE_PREFERRED_FLOAT */
static QCBORError
-QCBORDecode_Private_SingleConformance(const float f, uint8_t uDecodeMode3Bit)
+QCBORDecode_Private_SingleConformance(const float f, const QCBORDecodeMode uConfigFlags)
{
(void)f;
- if(uDecodeMode3Bit>= QCBOR_DECODE_MODE_PREFERRED) {
+ if(uConfigFlags & QCBOR_DECODE_ONLY_REDUCED_FLOATS | QCBOR_DECODE_ONLY_PREFERRED_NUMBERS) {
return QCBOR_ERR_CANT_CHECK_FLOAT_CONFORMANCE;
} else {
return QCBOR_SUCCESS;
@@ -1260,10 +1260,10 @@
}
static QCBORError
-QCBORDecode_Private_DoubleConformance(const double d, uint8_t uDecodeMode3Bit)
+QCBORDecode_Private_DoubleConformance(const double d, const QCBORDecodeMode uConfigFlags)
{
(void)d;
- if(uDecodeMode3Bit>= QCBOR_DECODE_MODE_PREFERRED) {
+ if(uConfigFlags & QCBOR_DECODE_ONLY_REDUCED_FLOATS | QCBOR_DECODE_ONLY_PREFERRED_NUMBERS) {
return QCBOR_ERR_CANT_CHECK_FLOAT_CONFORMANCE;
} else {
return QCBOR_SUCCESS;
@@ -1276,10 +1276,10 @@
* Decode a float
*/
static QCBORError
-QCBOR_Private_DecodeFloat(const uint8_t uDecodeMode3Bit,
- const int nAdditionalInfo,
- const uint64_t uArgument,
- QCBORItem *pDecodedItem)
+QCBOR_Private_DecodeFloat(const QCBORDecodeMode uConfigFlags,
+ const int nAdditionalInfo,
+ const uint64_t uArgument,
+ QCBORItem *pDecodedItem)
{
QCBORError uReturn = QCBOR_SUCCESS;
float single;
@@ -1296,7 +1296,7 @@
pDecodedItem->val.dfnum = IEEE754_HalfToDouble((uint16_t)uArgument);
pDecodedItem->uDataType = QCBOR_TYPE_DOUBLE;
- uReturn = QCBORDecode_Private_HalfConformance(pDecodedItem->val.dfnum, uDecodeMode3Bit);
+ uReturn = QCBORDecode_Private_HalfConformance(pDecodedItem->val.dfnum, uConfigFlags);
if(uReturn != QCBOR_SUCCESS) {
break;
}
@@ -1314,7 +1314,7 @@
* 32 bits. It was widened to 64 bits to be passed in here.
*/
single = UsefulBufUtil_CopyUint32ToFloat((uint32_t)uArgument);
- uReturn = QCBORDecode_Private_SingleConformance(single, uDecodeMode3Bit);
+ uReturn = QCBORDecode_Private_SingleConformance(single, uConfigFlags);
if(uReturn != QCBOR_SUCCESS) {
break;
}
@@ -1342,7 +1342,7 @@
pDecodedItem->val.dfnum = UsefulBufUtil_CopyUint64ToDouble(uArgument);
pDecodedItem->uDataType = QCBOR_TYPE_DOUBLE;
- uReturn = QCBORDecode_Private_DoubleConformance(pDecodedItem->val.dfnum, uDecodeMode3Bit);
+ uReturn = QCBORDecode_Private_DoubleConformance(pDecodedItem->val.dfnum, uConfigFlags);
if(uReturn != QCBOR_SUCCESS) {
break;
}
@@ -1400,10 +1400,10 @@
* type in input.
*/
static QCBORError
-QCBOR_Private_DecodeType7(const uint8_t uDecodeMode3Bit,
- const int nAdditionalInfo,
- const uint64_t uArgument,
- QCBORItem *pDecodedItem)
+QCBOR_Private_DecodeType7(const QCBORDecodeMode uConfigFlags,
+ const int nAdditionalInfo,
+ const uint64_t uArgument,
+ QCBORItem *pDecodedItem)
{
QCBORError uReturn = QCBOR_SUCCESS;
@@ -1423,7 +1423,7 @@
case SINGLE_PREC_FLOAT: /* 26 */
case DOUBLE_PREC_FLOAT: /* 27 */
#ifndef USEFULBUF_DISABLE_ALL_FLOAT
- uReturn = QCBOR_Private_DecodeFloat(uDecodeMode3Bit, nAdditionalInfo, uArgument, pDecodedItem);
+ uReturn = QCBOR_Private_DecodeFloat(uConfigFlags, nAdditionalInfo, uArgument, pDecodedItem);
#else
uReturn = QCBOR_ERR_ALL_FLOAT_DISABLED;
#endif /* ! USEFULBUF_DISABLE_ALL_FLOAT */
@@ -1435,7 +1435,7 @@
case CBOR_SIMPLEV_UNDEF: /* 23 */
case CBOR_SIMPLE_BREAK: /* 31 */
#ifndef QCBOR_DISABLE_DECODE_CONFORMANCE
- if(uDecodeMode3Bit >= QCBOR_DECODE_MODE_DCBOR &&
+ if((uConfigFlags & QCBOR_DECODE_DISALLOW_DCBOR_SIMPLES) &&
nAdditionalInfo == CBOR_SIMPLEV_UNDEF) {
uReturn = QCBOR_ERR_DCBOR_CONFORMANCE;
goto Done;
@@ -1455,7 +1455,7 @@
default: /* 0-19 */
#ifndef QCBOR_DISABLE_DECODE_CONFORMANCE
- if(uDecodeMode3Bit >= QCBOR_DECODE_MODE_DCBOR &&
+ if((uConfigFlags & QCBOR_DECODE_DISALLOW_DCBOR_SIMPLES) &&
(uArgument < CBOR_SIMPLEV_FALSE || uArgument > CBOR_SIMPLEV_NULL)) {
uReturn = QCBOR_ERR_DCBOR_CONFORMANCE;
goto Done;
@@ -1513,10 +1513,11 @@
QCBORItem *pDecodedItem)
{
QCBORError uReturn;
- int nMajorType = 0;
- uint64_t uArgument = 0;
- int nAdditionalInfo = 0;
- uint8_t uDecodeMode3Bit = pMe->uDecodeMode & QCBOR_DECODE_MODE_MASK;
+ int nMajorType = 0;
+ uint64_t uArgument = 0;
+ int nAdditionalInfo = 0;
+
+ const QCBORDecodeMode uDecodeMode = pMe->uDecodeMode;
memset(pDecodedItem, 0, sizeof(QCBORItem));
@@ -1526,7 +1527,7 @@
uReturn = QCBOR_Private_DecodeHead(&(pMe->InBuf),
#ifndef QCBOR_DISABLE_DECODE_CONFORMANCE
// TODO: make this prettier; will optimizer take out stuff without ifdef?
- uDecodeMode3Bit >= QCBOR_DECODE_MODE_PREFERRED,
+ uDecodeMode,
#endif /* !QCBOR_DISABLE_DECODE_CONFORMANCE */
&nMajorType,
&uArgument,
@@ -1553,7 +1554,7 @@
case CBOR_MAJOR_TYPE_ARRAY: /* Major type 4 */
case CBOR_MAJOR_TYPE_MAP: /* Major type 5 */
- return QCBOR_Private_DecodeArrayOrMap(uDecodeMode3Bit, nMajorType, uArgument, nAdditionalInfo, pDecodedItem);
+ return QCBOR_Private_DecodeArrayOrMap(uDecodeMode, nMajorType, uArgument, nAdditionalInfo, pDecodedItem);
break;
case CBOR_MAJOR_TYPE_TAG: /* Major type 6, tag numbers */
@@ -1562,7 +1563,7 @@
case CBOR_MAJOR_TYPE_SIMPLE:
/* Major type 7: float, double, true, false, null... */
- return QCBOR_Private_DecodeType7(uDecodeMode3Bit, nAdditionalInfo, uArgument, pDecodedItem);
+ return QCBOR_Private_DecodeType7(uDecodeMode, nAdditionalInfo, uArgument, pDecodedItem);
break;
default:
@@ -2034,7 +2035,7 @@
/* TODO: QCBOR_DECODE_MODE_MAP_STRINGS_ONLY might have been a bad idea. Maybe
* get rid of it in QCBOR 2.0
*/
- if((pMe->uDecodeMode & QCBOR_DECODE_MODE_MASK) == QCBOR_DECODE_MODE_MAP_STRINGS_ONLY &&
+ if(pMe->uDecodeMode & QCBOR_DECODE_MODE_MAP_STRINGS_ONLY &&
LabelItem.uDataType != QCBOR_TYPE_TEXT_STRING) {
uErr = QCBOR_ERR_MAP_LABEL_TYPE;
goto Done;
@@ -2663,7 +2664,7 @@
#ifndef QCBOR_DISABLE_DECODE_CONFORMANCE
if(uErr == QCBOR_SUCCESS &&
- (pMe->uDecodeMode & QCBOR_DECODE_MODE_MASK) >= QCBOR_DECODE_MODE_CDE &&
+ pMe->uDecodeMode & QCBOR_DECODE_ONLY_SORTED_MAPS &&
pDecodedItem->uDataType == QCBOR_TYPE_MAP) {
/* Traverse map checking sort order and for duplicates */
uErr = QCBORDecode_Private_CheckMap(pMe, pDecodedItem);
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 0fabc4f..98a841d 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -2610,7 +2610,7 @@
}
#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
- if(nIndex == 57) {
+ if(nIndex == 42) {
uCBORError = 9; /* For setting break points */
}