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/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
index 387d3af..2d5fa6d 100644
--- a/inc/qcbor/qcbor_decode.h
+++ b/inc/qcbor/qcbor_decode.h
@@ -1126,7 +1126,7 @@
  * Deep tag nesting is rare so this implementation imposes a limit of
  * @ref QCBOR_MAX_TAGS_PER_ITEM on nesting and returns @ref
  * QCBOR_ERR_TOO_MANY_TAGS if there are more. This is a limit of this
- * imple* mentation, not of CBOR. (To be able to handle deeper
+ * implementation, not of CBOR. (To be able to handle deeper
  * nesting, the constant can be increased and the library
  * recompiled. It will use more memory).
  *
@@ -1145,19 +1145,23 @@
 
 
 /**
- * @brief Returns the tag numbers for last-fetched item.
+ * @brief Returns the tag numbers for last-decoded 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.
+ * @returns The nth tag number or CBOR_TAG_INVALID64.
  *
- * See QCBORDecode_GetNthTag(). This is the same but works with spiffy
- * decoding functions that do not return a QCBORItem with a
- * list of recorded tag numbers.  This gets the tags for the most
- * recently decoded item.
+ * This returns tags of the most recently decoded item.  See
+ * QCBORDecode_GetNthTag(). This is particularly of use for spiffy
+ * decode functions that don't return a @ref QCBORItem.
  *
- * If a decoding error set then this returns CBOR_TAG_INVALID64.
+ * This does not work for QCBORDecode_GetNext(),
+ * QCBORDecode_PeekNext(), QCBORDecode_VPeekNext() or
+ * QCBORDecode_VGetNextConsume() but these all return a
+ * @ref QCBORItem, so it is not necessary.
+ *
+ * If a decoding error is set, then this returns CBOR_TAG_INVALID64.
  */
 uint64_t
 QCBORDecode_GetNthTagOfLast(const QCBORDecodeContext *pCtx, uint32_t uIndex);
diff --git a/inc/qcbor/qcbor_spiffy_decode.h b/inc/qcbor/qcbor_spiffy_decode.h
index cfa1b80..d236392 100644
--- a/inc/qcbor/qcbor_spiffy_decode.h
+++ b/inc/qcbor/qcbor_spiffy_decode.h
@@ -980,11 +980,11 @@
  * if there is more than one occurance of the label being searched
  * for.
  *
- * Duplicate label detection is performed for the item being sought,
- * but only for the item being sought.
+ * Duplicate label detection is performed for the item being sought
+ * and only for the item being sought.
  *
  * This performs a full decode of every item in the map being
- * searched, which involves a full traversal of every item. For maps
+ * searched which involves a full traversal of every item. For maps
  * with little nesting, this is of little consequence, but may be of
  * consequence for large deeply nested CBOR structures on slow CPUs.
  *
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 =
    {
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index b79772d..aacde23 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -2446,6 +2446,7 @@
    if(QCBORDecode_GetError(&DCtx) || uSimple != 32) {
       return 26;
    }
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
    QCBORDecode_GetSimple(&DCtx, &uSimple);
    if(QCBORDecode_GetError(&DCtx) || uSimple != 255) {
       return 27;
@@ -2482,6 +2483,7 @@
    if(QCBORDecode_GetAndResetError(&DCtx) != QCBOR_ERR_UNEXPECTED_TYPE) {
       return 34;
    }
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
 
    return 0;
 }
@@ -2560,19 +2562,19 @@
       }
 #endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
 
-      if(nIndex == 8) {
+      if(nIndex == 4) {
          uCBORError = 9; /* For setting break points */
       }
 
-      /* Iterate until there is an error of some sort of error */
+      /* Iterate until there is an error of some sort */
       do {
-         /* Set to something none-zero, something other than QCBOR_TYPE_NONE */
+         /* Set to something non-zero, something other than QCBOR_TYPE_NONE */
          memset(&Item, 0x33, sizeof(Item));
 
          uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
       } while(uCBORError == QCBOR_SUCCESS);
 
-      /* Must get the expected error or the this test fails
+      /* Must get the expected error or the this test fails.
        * The data and label type must also be QCBOR_TYPE_NONE.
        */
       if(uCBORError != pF->nError ||
@@ -4464,6 +4466,86 @@
 
 
    QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags),
+                    QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_EnterMap(&DCtx, NULL);
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 0) != 55799) {
+      return 200;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 1) != 55799) {
+      return 202;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 2) != 55799) {
+      return 203;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 3) != CBOR_TAG_INVALID64) {
+      return 204;
+   }
+
+   QCBORDecode_EnterMap(&DCtx, NULL);
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 0) != 7) {
+      return 210;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 1) != 5859837686836516696) {
+      return 212;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 2) != CBOR_TAG_INVALID64) {
+      return 213;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 3) != CBOR_TAG_INVALID64) {
+      return 214;
+   }
+
+
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags),
+                    QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_EnterMap(&DCtx, NULL);
+   QCBORDecode_EnterMapFromMapN(&DCtx, -23);
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 0) != 7) {
+      return 220;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 1) != 5859837686836516696) {
+      return 221;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 2) != CBOR_TAG_INVALID64) {
+      return 222;
+   }
+
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags),
+                    QCBOR_DECODE_MODE_MAP_AS_ARRAY);
+   QCBORDecode_EnterArray(&DCtx, NULL);
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 0) != 55799) {
+      return 230;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 1) != 55799) {
+      return 231;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 2) != 55799) {
+      return 232;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 3) != CBOR_TAG_INVALID64) {
+      return 234;
+   }
+   int64_t nInt;
+   QCBORDecode_GetInt64(&DCtx, &nInt);
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 0) != 7) {
+      return 240;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 1) != 6) {
+      return 241;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 2) != CBOR_TAG_INVALID64) {
+      return 242;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 3) != CBOR_TAG_INVALID64) {
+      return 243;
+   }
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+
+   QCBORDecode_Init(&DCtx,
                     UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spSpiffyTagInput),
                     QCBOR_DECODE_MODE_NORMAL);
 
@@ -4473,27 +4555,27 @@
    // untagged date string
    QCBORDecode_GetDateString(&DCtx, QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG, &DateString);
    if(QCBORDecode_GetAndResetError(&DCtx) != QCBOR_SUCCESS) {
-      return 200;
+      return 250;
    }
    // untagged byte string
    QCBORDecode_GetDateString(&DCtx, QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG, &DateString);
    if(QCBORDecode_GetAndResetError(&DCtx) != QCBOR_ERR_UNEXPECTED_TYPE) {
-      return 201;
+      return 251;
    }
    // tagged regex
    QCBORDecode_GetDateString(&DCtx, QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG, &DateString);
    if(QCBORDecode_GetAndResetError(&DCtx) != QCBOR_ERR_UNEXPECTED_TYPE) {
-      return 202;
+      return 252;
    }
    // tagged date string with a byte string
    QCBORDecode_GetDateString(&DCtx, QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG, &DateString);
    if(QCBORDecode_GetAndResetError(&DCtx) != QCBOR_ERR_UNRECOVERABLE_TAG_CONTENT) {
-      return 203;
+      return 253;
    }
    // See comments above
    QCBORDecode_ExitArray(&DCtx);
    if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_UNRECOVERABLE_TAG_CONTENT) {
-      return 204;
+      return 254;
    }
 
    QCBORDecode_Init(&DCtx,
@@ -6216,8 +6298,8 @@
    },
    {"bad content for big num",
       QCBOR_DECODE_MODE_NORMAL,
-      {"\xC4\x82\xc2\x01\x1f", 5},
-      QCBOR_ERR_BAD_INT
+      {"\xC4\x82\xC2\x01\x1F", 5},
+      QCBOR_ERR_UNRECOVERABLE_TAG_CONTENT
    },
    {"Bad integer for exponent",
       QCBOR_DECODE_MODE_NORMAL,
@@ -9459,6 +9541,16 @@
 };
 
 
+#ifndef QCBOR_DISABLE_TAGS
+static const uint8_t spTaggedSimples[] =
+{
+   0xd8, 0x58, 0xd8, 0x2c, 0xd6, 0xf5,
+   0xd9, 0x0f, 0xA0, 0xf7
+};
+#endif /* ! QCBOR_DISABLE_TAGS */
+
+
+
 int32_t BoolTest(void)
 {
    QCBORDecodeContext DCtx;
@@ -9598,6 +9690,36 @@
       return 15;
    }
 
+#ifndef QCBOR_DISABLE_TAGS
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTaggedSimples),
+                    0);
+   QCBORDecode_GetBool(&DCtx, &b);
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 0) != 22) {
+      return 401;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 1) != 44) {
+      return 402;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 2) != 88) {
+      return 403;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 3) != CBOR_TAG_INVALID64) {
+      return 404;
+   }
+   QCBORDecode_GetUndefined(&DCtx);
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 0) != 4000) {
+      return 405;
+   }
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 1) != CBOR_TAG_INVALID64) {
+      return 406;
+   }
+   QCBORDecode_GetNull(&DCtx); /* Off the end */
+   if(QCBORDecode_GetNthTagOfLast(&DCtx, 0) != CBOR_TAG_INVALID64) {
+      return 407;
+   }
+#endif /* ! QCBOR_DISABLE_TAGS */
+
    return 0;
 }