disable encode guards mostly working
diff --git a/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
index 90a1686..1033871 100644
--- a/inc/qcbor/qcbor_decode.h
+++ b/inc/qcbor/qcbor_decode.h
@@ -936,7 +936,7 @@
@param[in] pItem The CBOR item to get the tag for.
@param[in] uIndex The index of the tag to get.
- @returns The actual nth tag value.
+ @returns The actual nth tag value or CBOR_TAG_INVALID64.
Up to @ref QCBOR_MAX_TAGS_PER_ITEM are recorded for a decoded CBOR item. If there
are more than this, the @ref QCBOR_ERR_TOO_MANY_TAGS error is returned
@@ -945,20 +945,35 @@
The 0th tag (@c uIndex 0) is the one that occurs closest to the data item.
Tags nest, so the nth tag applies to what ever type
- is a result of applying the (n-1) tag.
+ is a result of applying the (n-1) tag. See also @ref Tag-Usage.
To reduce memory used by a QCBORItem, this implementation maps
all tags larger than UINT16_MAX. This function does the unmapping.
- This returns @ref CBOR_TAG_INVALID64 on all errors or if the nth tag is requested and
- there is no nth tag. If there are no tags on the item, then
- requesting the 0th tag will return @ref CBOR_TAG_INVALID64.
+ This returns @ref CBOR_TAG_INVALID64 if any error occurred getting
+ the item. This is also returned if there are no tags on the item or
+ there is no nth tag.
*/
uint64_t QCBORDecode_GetNthTag(QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint32_t uIndex);
+/**
+@brief Returns the tag value for last-fetched item.
+
+@param[in] pCtx The decoder context.
+@param[in] uIndex The index of the tag to get.
+
+@returns The actual nth tag value or CBOR_TAG_INVALID64.
+
+ This is similar to QCBORDecode_GetNthTag(), but works with spiffy decoding
+ functions. These generally do not return a QCBORItem with the tag set.
+ This gets the tags for the most recently decoded item.
+
+ If a decoding error set then this returns CBOR_TAG_INVALID64.
+*/
uint64_t QCBORDecode_GetNthTagOfLast(const QCBORDecodeContext *pCtx, uint32_t uIndex);
+
/**
@brief Check whether all the bytes have been decoded and maps and arrays closed.
diff --git a/inc/qcbor/qcbor_private.h b/inc/qcbor/qcbor_private.h
index a72cfdd..b161752 100644
--- a/inc/qcbor/qcbor_private.h
+++ b/inc/qcbor/qcbor_private.h
@@ -266,8 +266,15 @@
#define CBOR_MAJOR_NONE_TYPE_RAW 9
#define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
#define CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY 11
-#define CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN 12
-#define CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN 13
+
+// Add this to types to indicate they are to be encoded as indefinite lengths
+#define QCBOR_INDEFINITE_LEN_TYPE_MODIFIER 0x80
+#define CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN \
+ CBOR_MAJOR_TYPE_ARRAY + QCBOR_INDEFINITE_LEN_TYPE_MODIFIER
+#define CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN \
+ CBOR_MAJOR_TYPE_MAP + QCBOR_INDEFINITE_LEN_TYPE_MODIFIER
+#define CBOR_MAJOR_NONE_TYPE_SIMPLE_BREAK \
+ CBOR_MAJOR_TYPE_SIMPLE + QCBOR_INDEFINITE_LEN_TYPE_MODIFIER
#ifdef __cplusplus
}
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 3e36e5a..001a778 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -2193,6 +2193,9 @@
const QCBORItem *pItem,
uint32_t uIndex)
{
+ if(pItem->uDataType == QCBOR_TYPE_NONE) {
+ return CBOR_TAG_INVALID64;
+ }
if(uIndex >= QCBOR_MAX_TAGS_PER_ITEM) {
return CBOR_TAG_INVALID64;
} else {
@@ -2206,6 +2209,9 @@
uint64_t QCBORDecode_GetNthTagOfLast(const QCBORDecodeContext *pMe,
uint32_t uIndex)
{
+ if(pMe->uLastError != QCBOR_SUCCESS) {
+ return CBOR_TAG_INVALID64;
+ }
if(uIndex >= QCBOR_MAX_TAGS_PER_ITEM) {
return CBOR_TAG_INVALID64;
} else {
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index a025e91..f800cb4 100644
--- a/src/qcbor_encode.c
+++ b/src/qcbor_encode.c
@@ -129,6 +129,7 @@
return pNesting->pCurrentNesting->uStart;
}
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
inline static uint8_t Nesting_GetMajorType(QCBORTrackNesting *pNesting)
{
return pNesting->pCurrentNesting->uMajorType;
@@ -138,6 +139,7 @@
{
return pNesting->pCurrentNesting == &pNesting->pArrays[0] ? false : true;
}
+#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
@@ -327,29 +329,19 @@
// The 5 bits in the initial byte that are not the major type
int nAdditionalInfo;
- if(uMajorType > 10) {
- uMajorType = uMajorType & 0x07;
- nAdditionalInfo = 31;
- } else
-/*
-#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDSX
- if (uMajorType == CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN) {
- uMajorType = CBOR_MAJOR_TYPE_ARRAY;
- nAdditionalInfo = LEN_IS_INDEFINITE;
- } else if (uMajorType == CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN) {
- uMajorType = CBOR_MAJOR_TYPE_MAP;
- nAdditionalInfo = LEN_IS_INDEFINITE;
- } else
+ if(uMajorType > QCBOR_INDEFINITE_LEN_TYPE_MODIFIER) {
+ // Special case for start & end of indefinite length
+ uMajorType = uMajorType - QCBOR_INDEFINITE_LEN_TYPE_MODIFIER;
+ // Take advantage of design of CBOR where additional info
+ // is 31 for both opening and closing indefinite length
+ // maps and arrays.
+#if CBOR_SIMPLE_BREAK != LEN_IS_INDEFINITE
+#error additional info for opening array not the same as for closing
#endif
- */
- if (uArgument < CBOR_TWENTY_FOUR && uMinLen == 0) {
+ nAdditionalInfo = CBOR_SIMPLE_BREAK;
+ } else if (uArgument < CBOR_TWENTY_FOUR && uMinLen == 0) {
// Simple case where argument is < 24
nAdditionalInfo = (int)uArgument;
-#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
- } else if (uMajorType == CBOR_MAJOR_TYPE_SIMPLE && uArgument == CBOR_SIMPLE_BREAK) {
- // Break statement can be encoded in single byte too (0xff)
- nAdditionalInfo = 31;
-#endif
} else {
/*
Encode argument in 1,2,4 or 8 bytes. Outer loop
@@ -463,8 +455,9 @@
}
}
#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
// A stack buffer large enough for a CBOR head
- UsefulBuf_MAKE_STACK_UB (pBufferForEncodedHead,QCBOR_HEAD_BUFFER_SIZE);
+ UsefulBuf_MAKE_STACK_UB(pBufferForEncodedHead, QCBOR_HEAD_BUFFER_SIZE);
UsefulBufC EncodedHead = QCBOREncode_EncodeHead(pBufferForEncodedHead,
uMajorType,
@@ -497,7 +490,7 @@
me->uError = Nesting_Increment(&(me->nesting));
}
#else
- Nesting_Increment(&(me->nesting));
+ (void)Nesting_Increment(&(me->nesting));
#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
}
@@ -525,9 +518,8 @@
me->uError = Nesting_Increment(&(me->nesting));
}
#else
- Nesting_Increment(&(me->nesting));
+ (void)Nesting_Increment(&(me->nesting));
#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
-
}
@@ -573,7 +565,7 @@
me->uError = Nesting_Increment(&(me->nesting));
}
#else
- Nesting_Increment(&(me->nesting));
+ (void)Nesting_Increment(&(me->nesting));
#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
}
@@ -612,7 +604,7 @@
me->uError = Nesting_Increment(&(me->nesting));
}
#else
- Nesting_Increment(&(me->nesting));
+ (void)Nesting_Increment(&(me->nesting));
#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
}
@@ -837,7 +829,7 @@
#endif
// Append the break marker (0xff for both arrays and maps)
- AppendCBORHead(me, CBOR_MAJOR_TYPE_SIMPLE, CBOR_SIMPLE_BREAK, 0);
+ AppendCBORHead(me, CBOR_MAJOR_NONE_TYPE_SIMPLE_BREAK, CBOR_SIMPLE_BREAK, 0);
Nesting_Decrease(&(me->nesting));
}
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index cfa1450..edcaad7 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -2890,6 +2890,11 @@
return -6;
}
+ if(QCBORDecode_GetNthTag(&DCtx, &Item, 0) != CBOR_TAG_INVALID64) {
+ return -106;
+ }
+
+
/* tag 10489608748473423768(
2442302356(
21590(
@@ -5040,10 +5045,15 @@
QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spRecoverableMapErrors), 0);
QCBORDecode_EnterMap(&DCtx, NULL);
QCBORDecode_GetInt64InMapN(&DCtx, 0x01, &nInt);
- uErr = QCBORDecode_GetAndResetError(&DCtx);
+ uErr = QCBORDecode_GetError(&DCtx);
if(uErr != QCBOR_ERR_TOO_MANY_TAGS) {
return 2021;
}
+ if(QCBORDecode_GetNthTagOfLast(&DCtx, 0) != CBOR_TAG_INVALID64) {
+ return 2121;
+ }
+ (void)QCBORDecode_GetAndResetError(&DCtx);
+
QCBORDecode_GetEpochDateInMapN(&DCtx, 0x02, QCBOR_TAG_REQUIREMENT_TAG, &nInt);
uErr = QCBORDecode_GetAndResetError(&DCtx);
diff --git a/test/qcbor_encode_tests.c b/test/qcbor_encode_tests.c
index c573a4b..57c4ff8 100644
--- a/test/qcbor_encode_tests.c
+++ b/test/qcbor_encode_tests.c
@@ -924,6 +924,8 @@
static const uint8_t spExpectedEncodedSimpleIndefiniteLength[] = {
0x9f, 0xf5, 0xf4, 0xf6, 0xf7, 0xbf, 0x65, 0x55, 0x4e, 0x44, 0x65, 0x66, 0xf7, 0xff, 0xff};
+// 9F F5 F4 F6 F7 BF 65 55 4E 44 65 66 F7 F8 1F F8 1F 69 73 20 74 68 65 20
+
int32_t SimpleValuesIndefiniteLengthTest1()
{
QCBOREncodeContext ECtx;
@@ -1780,8 +1782,12 @@
int32_t BstrWrapErrorTest()
{
- // ---- Test closing a bstrwrap when it is an array that is open ---------
QCBOREncodeContext EC;
+ UsefulBufC Wrapped;
+ UsefulBufC Encoded2;
+
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+ // ---- Test closing a bstrwrap when it is an array that is open ---------
QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
@@ -1792,12 +1798,10 @@
QCBOREncode_AddUInt64(&EC, 466);
QCBOREncode_OpenArray(&EC);
- UsefulBufC Wrapped;
QCBOREncode_CloseBstrWrap(&EC, &Wrapped);
QCBOREncode_CloseArray(&EC);
- UsefulBufC Encoded2;
if(QCBOREncode_Finish(&EC, &Encoded2) != QCBOR_ERR_CLOSE_MISMATCH) {
return -1;
}
@@ -1808,6 +1812,7 @@
if(QCBOREncode_Finish(&EC, &Encoded2) != QCBOR_ERR_TOO_MANY_CLOSES) {
return -2;
}
+#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
// --------------- test nesting too deep ----------------------------------
QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
@@ -2358,13 +2363,13 @@
// Second verify error from an array in encoded output too large
// Also test fetching the error code before finish
- QCBOREncode_Init(&EC, Buffer);
+ QCBOREncode_Init(&EC, (UsefulBuf){NULL, UINT32_MAX});
QCBOREncode_OpenArray(&EC);
- QCBOREncode_AddBytes(&EC, (UsefulBufC){NULL, UINT32_MAX-6});
+ QCBOREncode_AddBytes(&EC, (UsefulBufC){NULL, UINT32_MAX-10});
QCBOREncode_OpenArray(&EC); // Where QCBOR internally encounters and records error
if(QCBOREncode_GetErrorState(&EC) != QCBOR_ERR_BUFFER_TOO_LARGE) {
// Error fetch failed.
- return -12;
+ return -122;
}
QCBOREncode_CloseArray(&EC);
QCBOREncode_CloseArray(&EC);
@@ -2435,6 +2440,7 @@
}
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
// ------ QCBOR_ERR_TOO_MANY_CLOSES --------
QCBOREncode_Init(&EC, Large);
for(int i = QCBOR_MAX_ARRAY_NESTING; i > 0; i--) {
@@ -2471,6 +2477,7 @@
// One more level to cause error
return -9;
}
+#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
/* QCBOR_ERR_ARRAY_TOO_LONG is not tested here as
it would require a 64KB of RAM to test */
@@ -2482,6 +2489,7 @@
return -11;
}
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
// ------ QCBOR_ERR_UNSUPPORTED --------
QCBOREncode_Init(&EC, Large);
QCBOREncode_OpenArray(&EC);
@@ -2496,6 +2504,8 @@
if(QCBOREncode_FinishGetSize(&EC, &xx) != QCBOR_ERR_ENCODE_UNSUPPORTED) {
return -13;
}
+#endif /* #ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
return 0;
}
diff --git a/test/run_tests.c b/test/run_tests.c
index 0609736..0383b21 100644
--- a/test/run_tests.c
+++ b/test/run_tests.c
@@ -73,7 +73,9 @@
TEST_ENTRY(MapEncodeTest),
TEST_ENTRY(ArrayNestingTest1),
TEST_ENTRY(ArrayNestingTest2),
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
TEST_ENTRY(ArrayNestingTest3),
+#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
TEST_ENTRY(EncodeDateTest),
TEST_ENTRY(SimpleValuesTest1),
TEST_ENTRY(IntegerValuesTest1),