Allow disabling of indefinite length array/map decoding to save object code

Allows defining of QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS to save 200 bytes of object code for the smallest decode configuration.

Added a few more tests related to bstr-wrapped CBOR.

Some code tidiness fixes (that don't change semantics)

Co-authored-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index f524849..f78ee8d 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -60,7 +60,7 @@
 
    fflush(stdout);
 }
-#endif
+#endif /* PRINT_FUNCTIONS_FOR_DEBUGGING */
 
 
 static const uint8_t spExpectedEncodedInts[] = {
@@ -544,6 +544,8 @@
    0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63,
    0x73 };
 
+
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
 // Same as above, but with indefinite lengths.
 static const uint8_t pValidMapIndefEncoded[] = {
 0xbf, 0x6d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x69, 0x6e,
@@ -562,6 +564,7 @@
 0x6e, 0x20, 0x6c, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64,
 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63,
 0x73, 0xff, 0xff};
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
 
 
 static int32_t ParseOrderedArray(const uint8_t *pEncoded,
@@ -677,6 +680,7 @@
 static uint8_t sEmpties[] = {0x83, 0x00, 0x80, 0x84, 0x80, 0x81, 0x00, 0xa0,
                              0xa3, 0x01, 0xa0, 0x02, 0xa0, 0x03, 0x80};
 
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
 /* Same as above, but with indefinte lengths */
 static uint8_t sEmptiesIndef[] = {
 0x9F,
@@ -704,7 +708,7 @@
          0xFF,
       0xFF,
    0xFF};
-
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
 
 
 static int32_t CheckEmpties(UsefulBufC input, bool bCheckCounts)
@@ -840,12 +844,14 @@
       return nResult;
    }
 
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
    nResult = CheckEmpties(UsefulBuf_FROM_BYTE_ARRAY_LITERAL(sEmptiesIndef),
                      false);
 
    if(nResult) {
       return nResult -100;
    }
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
 
    return 0;
 }
@@ -1801,7 +1807,7 @@
    // A definte length map that is supposed to have s item, but has only 1
    { {(uint8_t[]){0xa2, 0x01, 0x02}, 3}, QCBOR_ERR_NO_MORE_ITEMS },
 
-
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
    // Indefinte length maps and arrays must be ended by a break
    // Indefinite length array with zero items and no break
    { {(uint8_t[]){0x9f}, 1}, QCBOR_ERR_NO_MORE_ITEMS },
@@ -1844,7 +1850,7 @@
    { {(uint8_t[]){0x81, 0x82, 0xbf, 0xff, 0xbf}, 5}, QCBOR_ERR_NO_MORE_ITEMS},
    // Unclosed definite length map in indefinite length arrays
    { {(uint8_t[]){0x9f, 0x9f, 0xa1}, 3}, QCBOR_ERR_NO_MORE_ITEMS},
-
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
 
    // The "argument" for the data item is incomplete
    // Positive integer missing 1 byte argument
@@ -1908,12 +1914,14 @@
    { {(uint8_t[]){0xff}, 1}, QCBOR_ERR_BAD_BREAK },
    // A bare break after a zero length definite length array
    { {(uint8_t[]){0x80, 0xff}, 2}, QCBOR_ERR_BAD_BREAK },
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
    // A bare break after a zero length indefinite length map
    { {(uint8_t[]){0x9f, 0xff, 0xff}, 3}, QCBOR_ERR_BAD_BREAK },
    // A break inside a definite length array inside an indefenite length array
    { {(uint8_t[]){0x9f, 0x81, 0xff}, 3}, QCBOR_ERR_BAD_BREAK },
    // Complicated mixed nesting with break outside indefinite length array
    { {(uint8_t[]){0x9f, 0x82, 0x9f, 0x81, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff}, 10}, QCBOR_ERR_BAD_BREAK },
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
 
 
    // Forbidden two byte encodings of simple types
@@ -2065,10 +2073,12 @@
    { {(uint8_t[]){0xa1, 0x00}, 2}, QCBOR_ERR_HIT_END },
    // Map with 3 item when it should have 4
    { {(uint8_t[]){0xa2, 0x00, 0x00, 0x00}, 2}, QCBOR_ERR_HIT_END },
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
    // Map with 1 item when it should have 2
    { {(uint8_t[]){0xbf, 0x00, 0xff}, 3}, QCBOR_ERR_BAD_BREAK },
    // Map with 3 item when it should have 4
    { {(uint8_t[]){0xbf, 0x00, 0x00, 0x00, 0xff}, 5}, QCBOR_ERR_BAD_BREAK },
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
 
 
    // In addition to not-well-formed, some invalid CBOR
@@ -2374,9 +2384,9 @@
    if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_HALF_PRECISION_DISABLED) {
       return -18;
    }
-#endif
+#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
 
-#else
+#else /* QCBOR_DISABLE_FLOAT_HW_USE */
    if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
       return -19;
    }
@@ -2403,9 +2413,9 @@
    if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_HALF_PRECISION_DISABLED) {
       return -26;
    }
-#endif
+#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
 
-#endif
+#endif /* QCBOR_DISABLE_FLOAT_HW_USE */
 
    return 0;
 }
@@ -2438,7 +2448,7 @@
 
    Untagged values
  */
-static uint8_t spSpiffyDateTestInput[] = {
+static const uint8_t spSpiffyDateTestInput[] = {
    0x86,
 
    0xc1,
@@ -2451,12 +2461,12 @@
    0xf9, 0xfc, 0x00, // Half-precision -Infinity
 
    0xc1, // tag for epoch date
-   0x9f, 0xff, // Erroneous empty array as content for date
+   0x80, // Erroneous empty array as content for date
 
    0xc0, // tag for string date
-   0xbf, 0xff, // Erroneous empty map as content for date
+   0xa0, // Erroneous empty map as content for date
 
-   0xbf, // Open a map for tests involving labels.
+   0xa9, // Open a map for tests involving labels.
 
    0x00,
    0xc0, // tag for string date
@@ -2495,8 +2505,6 @@
    // Untagged half-precision float with value -2
    0x09,
    0xF9, 0xC0, 0x00,
-
-   0xff,
 };
 
 int32_t SpiffyDateDecodeTest()
@@ -2525,7 +2533,7 @@
    if(uError != QCBOR_ERR_FLOAT_DATE_DISABLED) {
       return 1112;
    }
-#endif
+#endif /* QCBOR_DISABLE_FLOAT_HW_USE */
 
    // Too-large integer
    QCBORDecode_GetEpochDate(&DC, QCBOR_TAG_REQUIREMENT_TAG, &nEpochDateFail);
@@ -2862,7 +2870,7 @@
 
 
 static uint8_t spSpiffyTagInput[] = {
-   0x9f, // Open indefinite array
+   0x85, // Open array
 
    0xc0, // tag for string date
    0x6a, '1','9','8','5','-','0','4','-','1','2', // Date string
@@ -2876,8 +2884,6 @@
 
    0xc0, // tag for string date
    0x4a, '1','9','8','5','-','0','4','-','1','2', // Date string in byte string
-
-   0xff
 };
 
 
@@ -2927,7 +2933,7 @@
    uError = QCBORDecode_GetNext(&DCtx, &Item);
    uError = QCBORDecode_GetNext(&DCtx, &Item);
 
-#else
+#else /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
    if(uError != QCBOR_SUCCESS ||
       Item.uDataType != QCBOR_TYPE_DECIMAL_FRACTION ||
       QCBORDecode_GetNthTag(&DCtx, &Item, 0) != CBOR_TAG_INVALID64 ||
@@ -2937,7 +2943,7 @@
       QCBORDecode_GetNthTag(&DCtx, &Item, 4) != CBOR_TAG_INVALID64 ) {
       return -5;
    }
-#endif
+#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
 
    /*
     More than 4 tags on an item 225(226(227(228(229([])))))
@@ -4655,8 +4661,13 @@
    { {(uint8_t[]){0xC4, 0x82, 0x1f, 0x01}, 4}, QCBOR_ERR_BAD_INT},
    // 3 items in array
    { {(uint8_t[]){0xC4, 0x83, 0x03, 0x01, 02}, 5}, QCBOR_ERR_BAD_EXP_AND_MANTISSA},
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
    // unterminated indefinite length array
    { {(uint8_t[]){0xC4, 0x9f, 0x03, 0x01, 0x02}, 5}, QCBOR_ERR_BAD_EXP_AND_MANTISSA},
+#else /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
+   // unterminated indefinite length array
+   { {(uint8_t[]){0xC4, 0x9f, 0x03, 0x01, 0x02}, 5}, QCBOR_ERR_INDEF_LEN_ARRAYS_DISABLED},
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
    // Empty array
    { {(uint8_t[]){0xC4, 0x80}, 2}, QCBOR_ERR_NO_MORE_ITEMS},
    // Second is not an integer
@@ -4973,12 +4984,16 @@
    0x48, 0x67, 0x61, 0x6C, 0x61, 0x63, 0x74, 0x69, 0x63,
    0x4B, 0x68, 0x61, 0x76, 0x65, 0x6E, 0x20, 0x74, 0x6F, 0x6B, 0x65, 0x6E};
 
+static const uint8_t spArrayOfEmpty[] = {0x84, 0x40, 0xa0, 0x80, 0x00};
+
 
 static const uint8_t spEmptyMap[] = {0xa0};
 
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
 static const uint8_t spEmptyInDefinteLengthMap[] = {0xbf, 0xff};
 
-static const uint8_t spArrayOfEmpty[] = {0x84, 0x40, 0xa0, 0x80, 0x00};
+
+
 
 /*
    {
@@ -5006,6 +5021,9 @@
    0x80, 0x02, 0xa0, 0x03, 0x80, 0x04, 0xa0, 0x05, 0x9f, 0xff,
    0x06, 0x9f, 0x80, 0x9f, 0xff, 0xff};
 
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
+
+
 /*
  Too many tags
  Invalid tag content
@@ -5020,7 +5038,7 @@
   5: 0, 8: 8}
  */
 static const uint8_t spRecoverableMapErrors[] = {
-   0xbf,
+   0xa7,
    0x01, 0xd8, 0xe0, 0xd8, 0xe1, 0xd8, 0xe2, 0xd8, 0xe3, 0xd8, 0x04, 0x00,
    0x02, 0xc1, 0x40,
    0x03, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -5028,7 +5046,6 @@
    0x05, 0x00,
    0x05, 0x00,
    0x08, 0x08,
-   0xff
 };
 
 // Bad break
@@ -5036,6 +5053,7 @@
    0xa2, 0xff, 0x01, 0x00, 0x02, 0x00
 };
 
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
 // No more items
 static const uint8_t spUnRecoverableMapError2[] = {
    0xbf, 0x02, 0xbf, 0xff, 0x01, 0x00, 0x02, 0x00
@@ -5055,6 +5073,7 @@
             0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff
 };
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
 
 
 int32_t EnterMapTest()
@@ -5065,7 +5084,7 @@
    int32_t            nReturn;
    QCBORError         uErr;
 
-
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spMapOfEmpty), 0);
    QCBORDecode_EnterMap(&DCtx, NULL);
 
@@ -5109,12 +5128,13 @@
       return 3011;
    }
 
-
    (void)pValidMapIndefEncoded;
    nReturn = SpiffyDecodeBasicMap(UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapIndefEncoded));
    if(nReturn) {
       return nReturn + 20000;
    }
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
+
 
    nReturn = SpiffyDecodeBasicMap(UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded));
    if(nReturn) {
@@ -5227,6 +5247,7 @@
    }
 
 
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEmptyInDefinteLengthMap), 0);
    QCBORDecode_EnterMap(&DCtx, NULL);
    // This will fail because the map is empty.
@@ -5240,6 +5261,7 @@
    if(uErr != QCBOR_SUCCESS){
       return 2013;
    }
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
 
 
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spArrayOfEmpty), 0);
@@ -5292,7 +5314,7 @@
    if(uErr != QCBOR_ERR_FLOAT_DATE_DISABLED) {
       return 2027;
    }
-#endif
+#endif /* QCBOR_DISABLE_FLOAT_HW_USE */
 
    QCBORDecode_GetInt64InMapN(&DCtx, 0x05, &nInt);
    uErr = QCBORDecode_GetAndResetError(&DCtx);
@@ -5316,6 +5338,7 @@
       return 2030;
    }
 
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spUnRecoverableMapError2), 0);
    QCBORDecode_EnterMap(&DCtx, NULL);
    QCBORDecode_GetInt64InMapN(&DCtx, 0x01, &nInt);
@@ -5339,6 +5362,8 @@
    if(uErr != QCBOR_ERR_ARRAY_DECODE_NESTING_TOO_DEEP) {
       return 2033;
    }
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
+
 
    nReturn = DecodeNestedIterate();
 
@@ -5624,7 +5649,7 @@
       -4.0,
       QCBOR_SUCCESS // Uses ieee754.h to conver, not HW
 #endif /* QCBOR_DISABLE_FLOAT_HW_USE */
-#else
+#else /* QCBOR_DISABLE_PREFERRED_FLOAT */
       // Half-precision disabled
       -4,
       QCBOR_ERR_HALF_PRECISION_DISABLED,
@@ -5632,7 +5657,7 @@
       QCBOR_ERR_HALF_PRECISION_DISABLED,
       -4.0,
       QCBOR_ERR_HALF_PRECISION_DISABLED
-#endif
+#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
    },
    {
       "Decimal fraction 3/10",
@@ -6028,6 +6053,7 @@
 
    // Get a second item
    uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
    if(uCBORError != QCBOR_SUCCESS) {
       return 9;
    }
@@ -6041,6 +6067,11 @@
    if(uCBORError != QCBOR_ERR_ARRAY_OR_MAP_UNCONSUMED) {
       return 11;
    }
+#else /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
+   if(uCBORError != QCBOR_ERR_INDEF_LEN_ARRAYS_DISABLED) {
+      return 20;
+   }
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
 
 
    // --- Sequence with a closed indefinite length array ---
@@ -6061,6 +6092,8 @@
 
    // Get a second item
    uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
+
    if(uCBORError != QCBOR_SUCCESS) {
       return 14;
    }
@@ -6074,6 +6107,11 @@
    if(uCBORError != QCBOR_SUCCESS) {
       return 16;
    }
+#else /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
+   if(uCBORError != QCBOR_ERR_INDEF_LEN_ARRAYS_DISABLED) {
+      return 20;
+   }
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
 
 
    return 0;
@@ -6329,6 +6367,10 @@
    return Encoded;
 }
 
+static const uint8_t spBreakInByteString[] = {
+   0x41, 0xff
+};
+
 
 int32_t EnterBstrTest()
 {
@@ -6363,8 +6405,43 @@
    QCBORDecode_ExitArray(&DC);
 
    QCBORError uErr = QCBORDecode_Finish(&DC);
+   if(uErr) {
+      return (int32_t)uErr;
+   }
 
-   return (int32_t)uErr;
+
+   /* Enter and exit byte string wrapped CBOR that is bad. It has just a break.
+    * Successful because no items are fetched from byte string.
+    */
+   QCBORDecode_Init(&DC,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBreakInByteString),
+                    0);
+   QCBORDecode_EnterBstrWrapped(&DC, QCBOR_TAG_REQUIREMENT_NOT_A_TAG, NULL);
+   uErr = QCBORDecode_GetError(&DC);
+   if(uErr) {
+      return 100 + (int32_t)uErr;
+   }
+
+   QCBORDecode_ExitBstrWrapped(&DC);
+   uErr = QCBORDecode_GetError(&DC);
+   if(uErr) {
+      return 200 + (int32_t)uErr;
+   }
+
+   /* Try to get item that is a break out of a byte string wrapped CBOR.
+    * It fails because there should be no break.
+    */
+   QCBORDecode_Init(&DC,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBreakInByteString),
+                    0);
+   QCBORDecode_EnterBstrWrapped(&DC, QCBOR_TAG_REQUIREMENT_NOT_A_TAG, NULL);
+   QCBORItem Item;
+   uErr = QCBORDecode_GetNext(&DC, &Item);
+   if(uErr != QCBOR_ERR_BAD_BREAK) {
+      return 300 + (int32_t)uErr;
+   }
+
+   return 0;
 }
 
 
@@ -6748,7 +6825,7 @@
 #ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS
 
 static const uint8_t spMapWithIndefLenStrings[] = {
-   0xbf,
+   0xa3,
       0x7f, 0x61, 'l', 0x64, 'a', 'b', 'e', 'l' , 0x61, '1', 0xff,
       0x5f, 0x42, 0x01, 0x02, 0x43, 0x03, 0x04, 0x05, 0xff,
       0x7f, 0x62, 'd', 'y', 0x61, 'm', 0x61, 'o', 0xff,
@@ -6756,7 +6833,6 @@
       0x7f, 0x62, 'l', 'a', 0x63, 'b', 'e', 'l', 0x61, '2', 0xff,
       0xc3,
           0x5f, 0x42, 0x00, 0x01, 0x42, 0x00, 0x01, 0x41, 0x01, 0xff,
-   0xff
 };
 
 int32_t SpiffyIndefiniteLengthStringsTests()
@@ -6803,11 +6879,11 @@
    if(uDouble != -16777474) {
       return 6;
    }
-#else
+#else /* QCBOR_DISABLE_FLOAT_HW_USE */
    if(QCBORDecode_GetAndResetError(&DCtx) != QCBOR_ERR_HW_FLOAT_DISABLED) {
       return 7;
    }
-#endif
+#endif /* QCBOR_DISABLE_FLOAT_HW_USE */
 
 
    QCBORDecode_ExitMap(&DCtx);