Fix bug in some uses of QCBORDecode_GetNthTagOfLast
QCBORDecode_GetNthTagOfLast() now works correctly for all spiffy decode and similar decode operations. Before it was not filling in the tag values for some spiffy decode operations. Better test coverage for QCBORDecode_GetNthTagOfLast().
Some refactoring and code size reduction for spiffy decode functions like QCBORDecode_GetBool().
QCBORDecode_GetItemInMapN() and QCBORDecode_GetItemInMapSZ() set the label and data types to QCBOR_TYPE_NONE when the decode is in error.
Minor internal restructure of QCBORDecode_Private_ExpMantissa(). Error codes from it will be more accurate.
Adresses #113
* Fix LastTag; optimize spiffy error handling
* documentation, fix tests for #ifdef fan out
* Error handling improvements
---------
Co-authored-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 9bd518e..020981a 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -2359,7 +2359,7 @@
*/
static QCBORError
QCBORDecode_Private_ExpMantissa(QCBORDecodeContext *pMe,
- QCBORItem *pDecodedItem)
+ QCBORItem *pDecodedItem)
{
QCBORError uReturn;
@@ -2370,7 +2370,7 @@
}
/* A check for pDecodedItem->val.uCount == 2 would work for
- * definite-length arrays, but not for indefinite. Instead remember
+ * definite-length arrays, but not for indefinite. Instead remember
* the nesting level the two integers must be at, which is one
* deeper than that of the array.
*/
@@ -2378,7 +2378,7 @@
/* --- Get the exponent --- */
QCBORItem exponentItem;
- uReturn = QCBORDecode_Private_GetNextMapOrArray(pMe, NULL, &exponentItem);
+ uReturn = QCBORDecode_GetNext(pMe, &exponentItem);
if(uReturn != QCBOR_SUCCESS) {
goto Done;
}
@@ -2403,7 +2403,7 @@
/* --- Get the mantissa --- */
QCBORItem mantissaItem;
- uReturn = QCBORDecode_Private_GetNextTagContent(pMe, &mantissaItem);
+ uReturn = QCBORDecode_GetNext(pMe, &mantissaItem);
if(uReturn != QCBOR_SUCCESS) {
goto Done;
}
@@ -2709,7 +2709,7 @@
QCBORDecode_GetNext(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
{
QCBORError uErr;
- uErr = QCBORDecode_Private_GetNextTagContent(pMe, pDecodedItem);
+ uErr = QCBORDecode_Private_GetNextTagContent(pMe, pDecodedItem);
if(uErr != QCBOR_SUCCESS) {
pDecodedItem->uDataType = QCBOR_TYPE_NONE;
pDecodedItem->uLabelType = QCBOR_TYPE_NONE;
@@ -2752,6 +2752,17 @@
}
+static void
+QCBORDecode_Private_CopyTags(QCBORDecodeContext *pMe, const QCBORItem *pItem)
+{
+#ifndef QCBOR_DISABLE_TAGS
+ memcpy(pMe->uLastTags, pItem->uTags, sizeof(pItem->uTags));
+#else
+ (void)pMe;
+ (void)pItem;
+#endif
+}
+
/*
* Public function, see header qcbor/qcbor_decode.h file
*/
@@ -2765,6 +2776,7 @@
}
pMe->uLastError = (uint8_t)QCBORDecode_GetNext(pMe, pDecodedItem);
+ QCBORDecode_Private_CopyTags(pMe, pDecodedItem);
}
@@ -3133,17 +3145,6 @@
-static void
-QCBORDecode_Private_CopyTags(QCBORDecodeContext *pMe, const QCBORItem *pItem)
-{
-#ifndef QCBOR_DISABLE_TAGS
- memcpy(pMe->uLastTags, pItem->uTags, sizeof(pItem->uTags));
-#else
- (void)pMe;
- (void)pItem;
-#endif
-}
-
/**
* @brief Consume an entire map or array including its contents.
@@ -3414,6 +3415,9 @@
/* Get the item */
QCBORItem Item;
+ /* QCBORDecode_Private_GetNextTagContent() rather than GetNext()
+ * because a label match is performed on recoverable errors to
+ * be able to return the the error code for the found item. */
QCBORError uResult = QCBORDecode_Private_GetNextTagContent(pMe, &Item);
if(QCBORDecode_IsUnrecoverableError(uResult)) {
/* The map/array can't be decoded when unrecoverable errors occur */
@@ -3437,8 +3441,8 @@
}
if(uResult != QCBOR_SUCCESS) {
/* The label matches, but the data item is in error.
- * It is OK to have recoverable errors on items that are not
- * matched. */
+ * It is OK to have recoverable errors on items that
+ * are not matched. */
uReturn = uResult;
goto Done;
}
@@ -3543,15 +3547,19 @@
QCBORError uReturn = QCBORDecode_Private_MapSearch(pMe, OneItemSeach, NULL, NULL);
- *pItem = OneItemSeach[0];
-
if(uReturn != QCBOR_SUCCESS) {
+ pItem->uDataType = QCBOR_TYPE_NONE;
+ pItem->uLabelType = QCBOR_TYPE_NONE;
goto Done;
}
+
if(OneItemSeach[0].uDataType == QCBOR_TYPE_NONE) {
uReturn = QCBOR_ERR_LABEL_NOT_FOUND;
}
+ *pItem = OneItemSeach[0];
+ QCBORDecode_Private_CopyTags(pMe, pItem);
+
Done:
pMe->uLastError = (uint8_t)uReturn;
}
@@ -3580,6 +3588,8 @@
QCBORError uReturn = QCBORDecode_Private_MapSearch(pMe, OneItemSeach, NULL, NULL);
if(uReturn != QCBOR_SUCCESS) {
+ pItem->uDataType = QCBOR_TYPE_NONE;
+ pItem->uLabelType = QCBOR_TYPE_NONE;
goto Done;
}
if(OneItemSeach[0].uDataType == QCBOR_TYPE_NONE) {
@@ -3588,8 +3598,9 @@
}
*pItem = OneItemSeach[0];
-Done:
+ QCBORDecode_Private_CopyTags(pMe, pItem);
+Done:
#else
(void)pMe;
(void)szLabel;
@@ -4532,7 +4543,6 @@
pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
break;
}
- QCBORDecode_Private_CopyTags(pMe, pItem);
}
@@ -4542,15 +4552,8 @@
void
QCBORDecode_GetBool(QCBORDecodeContext *pMe, bool *pValue)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- /* Already in error state, do nothing */
- return;
- }
-
QCBORItem Item;
-
- pMe->uLastError = (uint8_t)QCBORDecode_GetNext(pMe, &Item);
-
+ QCBORDecode_VGetNext(pMe, &Item);
QCBORDecode_Private_ProcessBool(pMe, &Item, pValue);
}
@@ -4565,7 +4568,6 @@
{
QCBORItem Item;
QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
-
QCBORDecode_Private_ProcessBool(pMe, &Item, pValue);
}
@@ -4580,7 +4582,6 @@
{
QCBORItem Item;
QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
-
QCBORDecode_Private_ProcessBool(pMe, &Item, pValue);
}
@@ -4633,7 +4634,6 @@
pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
return;
}
- QCBORDecode_Private_CopyTags(pMe, pItem);
}
/*
@@ -4643,7 +4643,6 @@
QCBORDecode_GetSimple(QCBORDecodeContext *pMe, uint8_t *puSimple)
{
QCBORItem Item;
-
QCBORDecode_VGetNext(pMe, &Item);
QCBORDecode_Private_ProcessSimple(pMe, &Item, puSimple);
}
@@ -4658,7 +4657,6 @@
{
QCBORItem Item;
QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
-
QCBORDecode_Private_ProcessSimple(pMe, &Item, puSimpleValue);
}
@@ -4672,7 +4670,6 @@
{
QCBORItem Item;
QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
-
QCBORDecode_Private_ProcessSimple(pMe, &Item, puSimpleValue);
}
@@ -4721,10 +4718,6 @@
}
}
- // Save the tags in the last item's tags in the decode context
- // for QCBORDecode_GetNthTagOfLast()
- QCBORDecode_Private_CopyTags(pMe, pItem);
-
*pnTime = pItem->val.epochDate.nSeconds;
Done:
@@ -4741,14 +4734,8 @@
uint8_t uTagRequirement,
int64_t *pnTime)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- // Already in error state, do nothing
- return;
- }
-
QCBORItem Item;
- pMe->uLastError = (uint8_t)QCBORDecode_GetNext(pMe, &Item);
-
+ QCBORDecode_VGetNext(pMe, &Item);
QCBORDecode_Private_ProcessEpochDate(pMe, &Item, uTagRequirement, pnTime);
}
@@ -4828,11 +4815,6 @@
}
}
- /* Save the tags in the last item's tags in the decode context
- * for QCBORDecode_GetNthTagOfLast()
- */
- QCBORDecode_Private_CopyTags(pMe, pItem);
-
*pnDays = pItem->val.epochDays;
Done:
@@ -4848,14 +4830,8 @@
uint8_t uTagRequirement,
int64_t *pnDays)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- /* Already in error state, do nothing */
- return;
- }
-
QCBORItem Item;
- pMe->uLastError = (uint8_t)QCBORDecode_GetNext(pMe, &Item);
-
+ QCBORDecode_VGetNext(pMe, &Item);
QCBORDecode_Private_ProcessEpochDays(pMe, &Item, uTagRequirement, pnDays);
}
@@ -4899,17 +4875,10 @@
const QCBOR_Private_TagSpec TagSpec,
UsefulBufC *pBstr)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- /* Already in error state, do nothing */
- return;
- }
-
- QCBORError uError;
QCBORItem Item;
- uError = QCBORDecode_GetNext(pMe, &Item);
- if(uError != QCBOR_SUCCESS) {
- pMe->uLastError = (uint8_t)uError;
+ QCBORDecode_VGetNext(pMe, &Item);
+ if(pMe->uLastError) {
return;
}
@@ -4976,15 +4945,9 @@
UsefulBufC *pValue,
bool *pbIsNegative)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- // Already in error state, do nothing
- return;
- }
-
QCBORItem Item;
- QCBORError uError = QCBORDecode_GetNext(pMe, &Item);
- if(uError != QCBOR_SUCCESS) {
- pMe->uLastError = (uint8_t)uError;
+ QCBORDecode_VGetNext(pMe, &Item);
+ if(pMe->uLastError) {
return;
}
@@ -5579,13 +5542,8 @@
int64_t *pnValue,
QCBORItem *pItem)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
- QCBORError uError = QCBORDecode_GetNext(pMe, pItem);
- if(uError) {
- pMe->uLastError = (uint8_t)uError;
+ QCBORDecode_VGetNext(pMe, pItem);
+ if(pMe->uLastError) {
return;
}
@@ -5994,23 +5952,12 @@
uint64_t *puValue,
QCBORItem *pItem)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
+ QCBORDecode_VGetNext(pMe, pItem);
+ if(pMe->uLastError) {
return;
}
- QCBORItem Item;
-
- QCBORError uError = QCBORDecode_GetNext(pMe, &Item);
- if(uError) {
- pMe->uLastError = (uint8_t)uError;
- return;
- }
-
- if(pItem) {
- *pItem = Item;
- }
-
- pMe->uLastError = (uint8_t)QCBOR_Private_ConvertUInt64(&Item,
+ pMe->uLastError = (uint8_t)QCBOR_Private_ConvertUInt64(pItem,
uConvertTypes,
puValue);
}
@@ -6063,10 +6010,6 @@
uint64_t *puValue,
QCBORItem *pItem)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, pItem);
if(pMe->uLastError != QCBOR_SUCCESS) {
return;
@@ -6388,13 +6331,8 @@
double *pdValue,
QCBORItem *pItem)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
- QCBORError uError = QCBORDecode_GetNext(pMe, pItem);
- if(uError) {
- pMe->uLastError = (uint8_t)uError;
+ QCBORDecode_VGetNext(pMe, pItem);
+ if(pMe->uLastError) {
return;
}
@@ -6451,10 +6389,6 @@
double *pdValue,
QCBORItem *pItem)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, pItem);
if(pMe->uLastError != QCBOR_SUCCESS) {
return;
@@ -6869,6 +6803,10 @@
{
QCBORError uErr;
+ if(pMe->uLastError) {
+ return;
+ }
+
uErr = QCBOR_Private_ExpMantissaTypeHandler(pMe, TagSpec, pItem);
if(uErr != QCBOR_SUCCESS) {
goto Done;
@@ -6932,6 +6870,10 @@
{
QCBORError uErr;
+ if(pMe->uLastError != QCBOR_SUCCESS) {
+ return;
+ }
+
uErr = QCBOR_Private_ExpMantissaTypeHandler(pMe, TagSpec, pItem);
if(uErr != QCBOR_SUCCESS) {
goto Done;
@@ -6994,16 +6936,8 @@
int64_t *pnMantissa,
int64_t *pnExponent)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
QCBORItem Item;
- QCBORError uError = QCBORDecode_GetNext(pMe, &Item);
- if(uError) {
- pMe->uLastError = (uint8_t)uError;
- return;
- }
+ QCBORDecode_VGetNext(pMe, &Item);
const QCBOR_Private_TagSpec TagSpec =
{
@@ -7031,10 +6965,6 @@
int64_t *pnMantissa,
int64_t *pnExponent)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
QCBORItem Item;
QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
@@ -7064,10 +6994,6 @@
int64_t *pnMantissa,
int64_t *pnExponent)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
QCBORItem Item;
QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
@@ -7098,16 +7024,8 @@
bool *pbMantissaIsNegative,
int64_t *pnExponent)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
QCBORItem Item;
- QCBORError uError = QCBORDecode_GetNext(pMe, &Item);
- if(uError) {
- pMe->uLastError = (uint8_t)uError;
- return;
- }
+ QCBORDecode_VGetNext(pMe, &Item);
const QCBOR_Private_TagSpec TagSpec =
{
@@ -7139,15 +7057,9 @@
bool *pbIsNegative,
int64_t *pnExponent)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
QCBORItem Item;
QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
const QCBOR_Private_TagSpec TagSpec =
{
@@ -7179,15 +7091,8 @@
bool *pbIsNegative,
int64_t *pnExponent)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
QCBORItem Item;
QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
const QCBOR_Private_TagSpec TagSpec =
{
@@ -7216,16 +7121,9 @@
int64_t *pnMantissa,
int64_t *pnExponent)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
QCBORItem Item;
- QCBORError uError = QCBORDecode_GetNext(pMe, &Item);
- if(uError) {
- pMe->uLastError = (uint8_t)uError;
- return;
- }
+ QCBORDecode_VGetNext(pMe, &Item);
+
const QCBOR_Private_TagSpec TagSpec =
{
uTagRequirement,
@@ -7252,15 +7150,8 @@
int64_t *pnMantissa,
int64_t *pnExponent)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
QCBORItem Item;
QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
const QCBOR_Private_TagSpec TagSpec =
{
@@ -7288,15 +7179,8 @@
int64_t *pnMantissa,
int64_t *pnExponent)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
QCBORItem Item;
QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
const QCBOR_Private_TagSpec TagSpec =
{
@@ -7325,16 +7209,8 @@
bool *pbMantissaIsNegative,
int64_t *pnExponent)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
QCBORItem Item;
- QCBORError uError = QCBORDecode_GetNext(pMe, &Item);
- if(uError) {
- pMe->uLastError = (uint8_t)uError;
- return;
- }
+ QCBORDecode_VGetNext(pMe, &Item);
const QCBOR_Private_TagSpec TagSpec =
{
@@ -7366,15 +7242,8 @@
bool *pbIsNegative,
int64_t *pnExponent)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
QCBORItem Item;
QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
const QCBOR_Private_TagSpec TagSpec =
{
@@ -7406,15 +7275,8 @@
bool *pbIsNegative,
int64_t *pnExponent)
{
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
-
QCBORItem Item;
QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
- if(pMe->uLastError != QCBOR_SUCCESS) {
- return;
- }
const QCBOR_Private_TagSpec TagSpec =
{