Merge branch 'master' into AdvancedDecode
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 39a5c7a..b18d40b 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -3974,3 +3974,133 @@
 
    return 0;
 }
+
+
+int32_t CBORSequenceDecodeTests(void)
+{
+   QCBORDecodeContext DCtx;
+   QCBORItem Item;
+   QCBORError uCBORError;
+
+   // --- Test a sequence with extra bytes ---
+   
+   // The input for the date test happens to be a sequence so it
+   // is reused. It is a sequence because it doesn't start as
+   // an array or map.
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDateTestInput),
+                    QCBOR_DECODE_MODE_NORMAL);
+   
+   // Get the first item
+   uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 1;
+   }
+   if(Item.uDataType != QCBOR_TYPE_DATE_STRING) {
+      return 2;
+   }
+   
+   // Get a second item
+   uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 2;
+   }
+   if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH) {
+      return 3;
+   }
+   
+   // A sequence can have stuff at the end that may
+   // or may not be valid CBOR. The protocol decoder knows
+   // when to stop by definition of the protocol, not
+   // when the top-level map or array is ended.
+   // Finish still has to be called to know that
+   // maps and arrays (if there were any) were closed
+   // off correctly. When called like this it
+   // must return the error QCBOR_ERR_EXTRA_BYTES.
+   uCBORError = QCBORDecode_Finish(&DCtx);
+   if(uCBORError != QCBOR_ERR_EXTRA_BYTES) {
+      return 4;
+   }
+   
+   
+   // --- Test an empty input ----
+   uint8_t empty[1];
+   UsefulBufC Empty = {empty, 0};
+   QCBORDecode_Init(&DCtx,
+                    Empty,
+                    QCBOR_DECODE_MODE_NORMAL);
+   
+   uCBORError = QCBORDecode_Finish(&DCtx);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 5;
+   }
+   
+   
+   // --- Sequence with unclosed indefinite length array ---
+   static const uint8_t xx[] = {0x01, 0x9f, 0x02};
+   
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(xx),
+                    QCBOR_DECODE_MODE_NORMAL);
+   
+   // Get the first item
+   uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 7;
+   }
+   if(Item.uDataType != QCBOR_TYPE_INT64) {
+      return 8;
+   }
+   
+   // Get a second item
+   uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 9;
+   }
+   if(Item.uDataType != QCBOR_TYPE_ARRAY) {
+      return 10;
+   }
+
+   // Try to finish before consuming all bytes to confirm
+   // that the still-open error is returned.
+   uCBORError = QCBORDecode_Finish(&DCtx);
+   if(uCBORError != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
+      return 11;
+   }
+
+   
+   // --- Sequence with a closed indefinite length array ---
+   static const uint8_t yy[] = {0x01, 0x9f, 0xff};
+   
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(yy),
+                    QCBOR_DECODE_MODE_NORMAL);
+   
+   // Get the first item
+   uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 12;
+   }
+   if(Item.uDataType != QCBOR_TYPE_INT64) {
+      return 13;
+   }
+   
+   // Get a second item
+   uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 14;
+   }
+   if(Item.uDataType != QCBOR_TYPE_ARRAY) {
+      return 15;
+   }
+
+   // Try to finish before consuming all bytes to confirm
+   // that the still-open error is returned.
+   uCBORError = QCBORDecode_Finish(&DCtx);
+   if(uCBORError != QCBOR_SUCCESS) {
+      return 16;
+   }
+
+   
+   return 0;
+}