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 =
    {