Improve error handling for not well-formed CBOR

diff --git a/QCBOR.xcodeproj/project.pbxproj b/QCBOR.xcodeproj/project.pbxproj
index cc2614c..d14ed86 100644
--- a/QCBOR.xcodeproj/project.pbxproj
+++ b/QCBOR.xcodeproj/project.pbxproj
@@ -33,6 +33,7 @@
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
+		0F8BADA722EF40FC008B6513 /* not_well_formed_cbor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = not_well_formed_cbor.h; path = test/not_well_formed_cbor.h; sourceTree = "<group>"; };
 		0FA9BEB5216CE6CA00BA646B /* qcbor_decode_tests.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.c; name = qcbor_decode_tests.c; path = test/qcbor_decode_tests.c; sourceTree = "<group>"; tabWidth = 3; };
 		0FA9BEB6216CE6CA00BA646B /* qcbor_decode_tests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qcbor_decode_tests.h; path = test/qcbor_decode_tests.h; sourceTree = "<group>"; };
 		0FA9BEB8216DC7AD00BA646B /* qcbor_encode_tests.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.c; name = qcbor_encode_tests.c; path = test/qcbor_encode_tests.c; sourceTree = "<group>"; tabWidth = 3; };
@@ -124,6 +125,7 @@
 				E73B575C2161CA7C0080D658 /* float_tests.h */,
 				E73B575D2161CA7C0080D658 /* half_to_double_from_rfc7049.c */,
 				E73B575B2161CA7C0080D658 /* half_to_double_from_rfc7049.h */,
+				0F8BADA722EF40FC008B6513 /* not_well_formed_cbor.h */,
 			);
 			name = test;
 			sourceTree = "<group>";
diff --git a/inc/qcbor.h b/inc/qcbor.h
index 4c96b51..18ed472 100644
--- a/inc/qcbor.h
+++ b/inc/qcbor.h
@@ -43,7 +43,9 @@
 
  when       who             what, where, why
  --------   ----            ---------------------------------------------------
- 7/25/19    janjongboom     Add indefinite length encoding for maps and arrays
+ 08/7/19    llundblade      Better handling of not well-formed encode and decode.
+ 07/31/19   llundblade      New error code for better end of data handling.
+ 7/25/19    janjongboom     Add indefinite length encoding for maps and arrays.
  05/26/19   llundblade      Add QCBOREncode_GetErrorState() and _IsBufferNULL().
  04/26/19   llundblade      Big documentation & style update. No interface change.
  02/16/19   llundblade      Redesign MemPool to fix memory access alignment bug.
@@ -395,6 +397,8 @@
 #define SINGLE_PREC_FLOAT    26
 #define DOUBLE_PREC_FLOAT    27
 #define CBOR_SIMPLE_BREAK    31
+#define CBOR_SIMPLEV_RESERVED_START  CBOR_SIMPLEV_ONEBYTE
+#define CBOR_SIMPLEV_RESERVED_END    CBOR_SIMPLE_BREAK
 
 
 
@@ -683,13 +687,16 @@
 
    /** During decoding, some CBOR construct was encountered that this
        decoder doesn't support, primarily this is the reserved
-       additional info values, 28 through 30. */
+       additional info values, 28 through 30. During encoding,
+       an attempt to create simple value between 24 and 31. */
    QCBOR_ERR_UNSUPPORTED = 5,
 
    /** During decoding, hit the end of the given data to decode. For
        example, a byte string of 100 bytes was expected, but the end
        of the input was hit before finding those 100 bytes.  Corrupted
-       CBOR input will often result in this error. */
+       CBOR input will often result in this error. See also @ref
+       QCBOR_ERR_NO_MORE_ITEMS.
+     */
    QCBOR_ERR_HIT_END = 6,
 
    /** During encoding, the length of the encoded CBOR exceeded @c
@@ -753,6 +760,13 @@
    /** An integer type is encoded with a bad length (an indefinite length) */
    QCBOR_ERR_BAD_INT = 21,
 
+   /** All well-formed data items have been consumed and there are no
+       more. If parsing a CBOR stream this indicates the non-error
+       end of the stream. If parsing a CBOR stream / sequence, this
+       probably indicates that some data items expected are not present.
+       See also @ref QCBOR_ERR_HIT_END. */
+   QCBOR_ERR_NO_MORE_ITEMS = 22
+
 } QCBORError;
 
 
@@ -2088,6 +2102,10 @@
  @retval QCBOR_ERR_NO_STRING_ALLOCATOR  Configuration error, encountered
                                         indefinite-length string with no
                                         allocator configured.
+ @retval QCBOR_ERR_NO_MORE_ITEMS   No more bytes to decode. The previous
+                                   item was successfully decoded. This
+                                   is usually how the non-error end of
+                                   a CBOR stream / sequence is detected.
 
  @c pDecodedItem is filled in with the value parsed. Generally, the
  following data is returned in the structure:
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 0c1eda9..9599b07 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -42,6 +42,8 @@
 
  when               who             what, where, why
  --------           ----            ---------------------------------------------------
+ 07/31/19           llundblade      Decode error fixes for some not-well-formed CBOR
+ 07/31/19           llundblade      New error code for better end of data handling
  02/17/19           llundblade      Fixed: QCBORItem.u{Data|Label}Alloc when bAllStrings set
  02/16/19           llundblade      Redesign MemPool to fix memory access alignment bug
  01/10/19           llundblade      Clever type and argument decoder is 250 bytes smaller
@@ -536,11 +538,7 @@
    pDecodedItem->uDataType = uAdditionalInfo;
 
    switch(uAdditionalInfo) {
-      case ADDINFO_RESERVED1:  // 28
-      case ADDINFO_RESERVED2:  // 29
-      case ADDINFO_RESERVED3:  // 30
-         nReturn = QCBOR_ERR_UNSUPPORTED;
-         break;
+      // No check for ADDINFO_RESERVED1 - ADDINFO_RESERVED3 as it is caught before this is called.
 
       case HALF_PREC_FLOAT:
          pDecodedItem->val.dfnum = IEEE754_HalfToDouble((uint16_t)uNumber);
@@ -783,8 +781,12 @@
          break;
 
       case CBOR_MAJOR_TYPE_OPTIONAL: // Major type 6, optional prepended tags
-         pDecodedItem->val.uTagV = uNumber;
-         pDecodedItem->uDataType = QCBOR_TYPE_OPTTAG;
+         if(uAdditionalInfo == LEN_IS_INDEFINITE) {
+            nReturn = QCBOR_ERR_BAD_INT;
+         } else {
+            pDecodedItem->val.uTagV = uNumber;
+            pDecodedItem->uDataType = QCBOR_TYPE_OPTTAG;
+         }
          break;
 
       case CBOR_MAJOR_TYPE_SIMPLE: // Major type 7, float, double, true, false, null...
@@ -869,7 +871,8 @@
 
       // Match data type of chunk to type at beginning.
       // Also catches error of other non-string types that don't belong.
-      if(StringChunkItem.uDataType != uStringType) {
+      // Also catches indefinite length strings inside indefinite length strings
+      if(StringChunkItem.uDataType != uStringType || StringChunkItem.val.string.len == SIZE_MAX) {
          nReturn = QCBOR_ERR_INDEFINITE_STRING_CHUNK;
          break;
       }
@@ -1065,6 +1068,12 @@
    // All the CBOR parsing work is here and in subordinate calls.
    QCBORError nReturn;
 
+   // Check if there are an
+   if(UsefulInputBuf_BytesUnconsumed(&(me->InBuf)) == 0 && !DecodeNesting_IsNested(&(me->nesting))) {
+      nReturn = QCBOR_ERR_NO_MORE_ITEMS;
+      goto Done;
+   }
+
    nReturn = GetNext_MapEntry(me, pDecodedItem, pTags);
    if(nReturn) {
       goto Done;
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index 20c6a47..28fb225 100644
--- a/src/qcbor_encode.c
+++ b/src/qcbor_encode.c
@@ -42,6 +42,7 @@
 
  when               who             what, where, why
  --------           ----            ---------------------------------------------------
+ 8/7/19             llundblade      Prevent encoding simple type reserved values 24..31
  7/25/19            janjongboom     Add indefinite length encoding for maps and arrays
  4/6/19             llundblade      Wrapped bstr returned now includes the wrapping bstr
  12/30/18           llundblade      Small efficient clever encode of type & argument.
@@ -189,7 +190,7 @@
  structures like array/map nesting resulting in some stack memory
  savings.
 
- Errors returned here fall into two categories:
+ Errors returned here fall into three categories:
 
  Sizes
    QCBOR_ERR_BUFFER_TOO_LARGE -- Encoded output exceeded UINT32_MAX
@@ -202,6 +203,9 @@
    QCBOR_ERR_TOO_MANY_CLOSES -- more close calls than opens
    QCBOR_ERR_CLOSE_MISMATCH -- Type of close does not match open
    QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN -- Finish called without enough closes
+
+ Would generate not-well-formed CBOR
+   QCBOR_ERR_UNSUPPORTED -- Simple type between 24 and 31
  */
 
 
@@ -463,18 +467,22 @@
 void QCBOREncode_AddType7(QCBOREncodeContext *me, size_t uSize, uint64_t uNum)
 {
    if(me->uError == QCBOR_SUCCESS) {
-      // This function call takes care of endian swapping for the float / double
-      InsertEncodedTypeAndNumber(me,
-                                 // The major type for floats and doubles
-                                 CBOR_MAJOR_TYPE_SIMPLE,
-                                 // size makes sure floats with zeros encode correctly
-                                 (int)uSize,
-                                 // Bytes of the floating point number as a uint
-                                 uNum,
-                                 // end position because this is append
-                                 UsefulOutBuf_GetEndPosition(&(me->OutBuf)));
+      if(uNum >= CBOR_SIMPLEV_RESERVED_START && uNum <= CBOR_SIMPLEV_RESERVED_END) {
+         me->uError = QCBOR_ERR_UNSUPPORTED;
+      } else {
+         // This function call takes care of endian swapping for the float / double
+         InsertEncodedTypeAndNumber(me,
+                                    // The major type for floats and doubles
+                                    CBOR_MAJOR_TYPE_SIMPLE,
+                                    // size makes sure floats with zeros encode correctly
+                                    (int)uSize,
+                                    // Bytes of the floating point number as a uint
+                                    uNum,
+                                    // end position because this is append
+                                    UsefulOutBuf_GetEndPosition(&(me->OutBuf)));
 
-      me->uError = Nesting_Increment(&(me->nesting));
+         me->uError = Nesting_Increment(&(me->nesting));
+      }
    }
 }
 
diff --git a/test/not_well_formed_cbor.h b/test/not_well_formed_cbor.h
new file mode 100644
index 0000000..fa5ebde
--- /dev/null
+++ b/test/not_well_formed_cbor.h
@@ -0,0 +1,325 @@
+/*==============================================================================
+ not_well_formed_cbor.h -- vectors to test for handling of not-well-formed CBOR
+
+ This is part of QCBOR -- https://github.com/laurencelundblade/QCBOR
+
+ Copyright (c) 2019, Laurence Lundblade. All rights reserved.
+
+ SPDX-License-Identifier: BSD-3-Clause
+
+ See BSD-3-Clause license in README.md
+
+ Created on 7/27/19
+ ==============================================================================*/
+
+#ifndef not_well_formed_cbor_h
+#define not_well_formed_cbor_h
+
+#include <stdint.h> // for size_t and uint8_t
+
+
+struct someBinaryBytes {
+    const uint8_t *p; // Pointer to the bytes
+    size_t         n; // Length of the bytes
+};
+
+
+static const struct someBinaryBytes paNotWellFormedCBOR[] = {
+
+    // Indefinite length strings must be closed off
+
+    // An indefinite length byte string not closed off
+    {(uint8_t[]){0x5f, 0x41, 0x00}, 3},
+    // An indefinite length text string not closed off
+    {(uint8_t[]){0x7f, 0x61, 0x00}, 3},
+
+
+    // All the chunks in an indefinite length string must be of the
+    // type of indefinite length string and indefinite
+
+    // indefinite length byte string with text string chunk
+    {(uint8_t[]){0x5f, 0x61, 0x00, 0xff}, 4},
+    // indefinite length text string with a byte string chunk
+    {(uint8_t[]){0x7f, 0x41, 0x00, 0xff}, 4},
+    // indefinite length byte string with an positive integer chunk
+    {(uint8_t[]){0x5f, 0x00, 0xff}, 3},
+    // indefinite length byte string with an negative integer chunk
+    {(uint8_t[]){0x5f, 0x21, 0xff}, 3},
+    // indefinite length byte string with an array chunk
+    {(uint8_t[]){0x5f, 0x80, 0xff}, 3},
+    // indefinite length byte string with an map chunk
+    {(uint8_t[]){0x5f, 0xa0, 0xff}, 3},
+    // indefinite length byte string with tagged integer chunk
+    {(uint8_t[]){0x5f, 0xc0, 0x00, 0xff}, 4},
+    // indefinite length byte string with an simple type chunk
+    {(uint8_t[]){0x5f, 0xe0, 0xff}, 3},
+    // indefinite length byte string with indefinite string inside
+    {(uint8_t[]){0x5f, 0x5f, 0x41, 0x00, 0xff, 0xff}, 6},
+    // indefinite length text string with indefinite string inside
+    {(uint8_t[]){0x7f, 0x7f, 0x61, 0x00, 0xff, 0xff}, 6},
+
+    // Definte length maps and arrays must be closed by having the
+    // right number of items
+
+    // A definte length array that is supposed to have 1 item, but has none
+    {(uint8_t[]){0x81}, 1},
+    // A definte length array that is supposed to have 2 items, but has only 1
+    {(uint8_t[]){0x82, 0x00}, 2},
+    // A definte length array that is supposed to have 511 items, but has only 1
+    {(uint8_t[]){0x9a, 0x01, 0xff, 0x00}, 4},
+    // A definte length map that is supposed to have 1 item, but has none
+    {(uint8_t[]){0xa1}, 1},
+    // A definte length map that is supposed to have s item, but has only 1
+    {(uint8_t[]){0xa2, 0x01, 0x02}, 3},
+
+
+    // Indefinte length maps and arrays must be ended by a break
+
+    // Indefinite length array with zero items and no break
+    {(uint8_t[]){0x9f}, 1},
+    // Indefinite length array with two items and no break
+    {(uint8_t[]){0x9f, 0x01, 0x02}, 3},
+    // Indefinite length map with zero items and no break
+    {(uint8_t[]){0xbf}, 1},
+    // Indefinite length map with two items and no break
+    {(uint8_t[]){0xbf, 0x01, 0x02, 0x01, 0x02}, 5},
+
+
+    // Some extra test vectors for unclosed arrays and maps
+
+    // Unclosed indefinite array containing a close definite array
+    {(uint8_t[]){0x9f, 0x80, 0x00}, 3},
+    // Definite length array containing an unclosed indefinite array
+    {(uint8_t[]){0x81, 0x9f}, 2},
+    // Deeply nested definite length arrays with deepest one unclosed
+    {(uint8_t[]){0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81}, 9},
+    // Deeply nested indefinite length arrays with deepest one unclosed
+    {(uint8_t[]){0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff}, 9},
+    // Mixed nesting with indefinite unclosed
+    {(uint8_t[]){0x9f, 0x81, 0x9f, 0x81, 0x9f, 0x9f, 0xff, 0xff, 0xff}, 9},
+    // Mixed nesting with definite unclosed
+    {(uint8_t[]){0x9f, 0x82, 0x9f, 0x81, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff}, 10},
+
+
+    // The "argument" for the data item is missing bytes
+
+    // Positive integer missing 1 byte argument
+    {(uint8_t[]){0x18}, 1},
+    // Positive integer missing 2 byte argument
+    {(uint8_t[]){0x19}, 1},
+    // Positive integer missing 4 byte argument
+    {(uint8_t[]){0x1a}, 1},
+    // Positive integer missing 8 byte argument
+    {(uint8_t[]){0x1b}, 1},
+    // Positive integer missing 1 byte of 2 byte argument
+    {(uint8_t[]){0x19, 0x01}, 2},
+    // Positive integer missing 2 bytes of 4 byte argument
+    {(uint8_t[]){0x1a, 0x01, 0x02}, 3},
+    // Positive integer missing 1 bytes of 7 byte argument
+    {(uint8_t[]){0x1b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 8},
+    // Negative integer missing 1 byte argument
+    {(uint8_t[]){0x38}, 1},
+    // Binary string missing 1 byte argument
+    {(uint8_t[]){0x58}, 1},
+    // Text string missing 1 byte argument
+    {(uint8_t[]){0x78}, 1},
+    // Array missing 1 byte argument
+    {(uint8_t[]){0x98}, 1},
+    // Map missing 1 byte argument
+    {(uint8_t[]){0xb8}, 1},
+    // Tag missing 1 byte argument
+    {(uint8_t[]){0xd8}, 1},
+    // Simple missing 1 byte argument
+    {(uint8_t[]){0xf8}, 1},
+    // Half-precision missing 1 byte
+    {(uint8_t[]){0xf9, 0x00}, 2},
+    // Float missing 2 bytes
+    {(uint8_t[]){0xfa, 0x00, 0x00}, 3},
+    // Double missing 5 bytes
+    {(uint8_t[]){0xfb, 0x00, 0x00, 0x00}, 4},
+
+    // Breaks must not occur in definite length arrays and maps
+
+    // Array of length 1 with sole member replaced by a break
+    {(uint8_t[]){0x81, 0xff}, 2},
+    // Array of length 2 with 2nd member replaced by a break
+    {(uint8_t[]){0x82, 0x00, 0xff}, 3},
+    // Map of length 1 with sole member label replaced by a break
+    {(uint8_t[]){0xa1, 0xff}, 2},
+    // Map of length 1 with sole member label replaced by break
+    // Alternate representation that some decoders handle difference
+    {(uint8_t[]){0xa1, 0xff, 0x00}, 3},
+    // Array of length 1 with 2nd member value replaced by a break
+    {(uint8_t[]){0xa1, 0x00, 0xff}, 3},
+    // Map of length 2 with 2nd member replaced by a break
+    {(uint8_t[]){0xa2, 0x00, 0x00, 0xff}, 4},
+
+
+    // Breaks must not occur on their own out of an indefinite length
+    // data item
+
+    // A bare break is not well formed
+    {(uint8_t[]){0xff}, 1},
+    // A bare break after a zero length definite length array
+    {(uint8_t[]){0x80, 0xff}, 2},
+    // A bare break after a zero length indefinite length map
+    {(uint8_t[]){0x9f, 0xff, 0xff}, 3},
+
+
+    // Forbidden two-byte encodings of simple types
+
+    // Must use 0xe0 instead
+    {(uint8_t[]){0xf8, 0x00}, 2},
+    // Should use 0xe1 instead
+    {(uint8_t[]){0xf8, 0x01}, 2},
+    // Should use 0xe2 instead
+    {(uint8_t[]){0xf8, 0x02}, 2},
+    // Should use 0xe3 instead
+    {(uint8_t[]){0xf8, 0x03}, 2},
+    // Should use 0xe4 instead
+    {(uint8_t[]){0xf8, 0x04}, 2},
+    // Should use 0xe5 instead
+    {(uint8_t[]){0xf8, 0x05}, 2},
+    // Should use 0xe6 instead
+    {(uint8_t[]){0xf8, 0x06}, 2},
+    // Should use 0xe7 instead
+    {(uint8_t[]){0xf8, 0x07}, 2},
+    // Should use 0xe8 instead
+    {(uint8_t[]){0xf8, 0x08}, 2},
+    // Should use 0xe9 instead
+    {(uint8_t[]){0xf8, 0x09}, 2},
+    // Should use 0xea instead
+    {(uint8_t[]){0xf8, 0x0a}, 2},
+    // Should use 0xeb instead
+    {(uint8_t[]){0xf8, 0x0b}, 2},
+    // Should use 0xec instead
+    {(uint8_t[]){0xf8, 0x0c}, 2},
+    // Should use 0xed instead
+    {(uint8_t[]){0xf8, 0x0d}, 2},
+    // Should use 0xee instead
+    {(uint8_t[]){0xf8, 0x0e}, 2},
+    // Should use 0xef instead
+    {(uint8_t[]){0xf8, 0x0f}, 2},
+    // Should use 0xf0 instead
+    {(uint8_t[]){0xf8, 0x10}, 2},
+    // Should use 0xf1 instead
+    {(uint8_t[]){0xf8, 0x11}, 2},
+    // Should use 0xf2 instead
+    {(uint8_t[]){0xf8, 0x12}, 2},
+    // Must use 0xf3 instead
+    {(uint8_t[]){0xf8, 0x13}, 2},
+    // Must use 0xf4 instead
+    {(uint8_t[]){0xf8, 0x14}, 2},
+    // Must use 0xf5 instead
+    {(uint8_t[]){0xf8, 0x15}, 2},
+    // Must use 0xf6 instead
+    {(uint8_t[]){0xf8, 0x16}, 2},
+    // Must use 0xf7 instead
+    {(uint8_t[]){0xf8, 0x17}, 2},
+    // Reserved (as defined in RFC 8126), considered not-well-formed
+    {(uint8_t[]){0xf8, 0x18}, 2},
+    // Reserved (as defined in RFC 8126), considered not-well-formed
+    {(uint8_t[]){0xf8, 0x19}, 2},
+    // Reserved (as defined in RFC 8126), considered not-well-formed
+    {(uint8_t[]){0xf8, 0x1a}, 2},
+    // Reserved (as defined in RFC 8126), considered not-well-formed
+    {(uint8_t[]){0xf8, 0x1b}, 2},
+    // Reserved (as defined in RFC 8126), considered not-well-formed
+    {(uint8_t[]){0xf8, 0x1c}, 2},
+    // Reserved (as defined in RFC 8126), considered not-well-formed
+    {(uint8_t[]){0xf8, 0x1d}, 2},
+    // Reserved (as defined in RFC 8126), considered not-well-formed
+    {(uint8_t[]){0xf8, 0x1e}, 2},
+    // Reserved (as defined in RFC 8126), considered not-well-formed
+    {(uint8_t[]){0xf8, 0x1f}, 2},
+
+    // Integers with "argument" equal to an indefinite length
+
+    // Positive integer with "argument" an indefinite length
+    {(uint8_t[]){0x1f}, 1},
+    // Negative integer with "argument" an indefinite length
+    {(uint8_t[]){0x3f}, 1},
+    // CBOR tag with "argument" an indefinite length
+    {(uint8_t[]){0xdf, 0x00}, 2},
+    // CBOR tag with "argument" an indefinite length alternate vector
+    {(uint8_t[]){0xdf}, 1},
+
+
+    // Missing content bytes from a definite length string
+
+    // A byte string is of length 1 without the 1 byte
+    {(uint8_t[]){0x41}, 1},
+    // A text string is of length 1 without the 1 byte
+    {(uint8_t[]){0x61}, 1},
+    // Byte string should have 2^32-1 bytes, but has one
+    {(uint8_t[]){0x5a, 0xff, 0xff, 0xff, 0xff, 0x00}, 6},
+    // Byte string should have 2^32-1 bytes, but has one
+    {(uint8_t[]){0x7a, 0xff, 0xff, 0xff, 0xff, 0x00}, 6},
+
+
+    // Use of unassigned additional information values
+
+    // Major type positive integer with reserved value 28
+    {(uint8_t[]){0x1c}, 1},
+    // Major type positive integer with reserved value 29
+    {(uint8_t[]){0x1d}, 1},
+    // Major type positive integer with reserved value 30
+    {(uint8_t[]){0x1e}, 1},
+    // Major type negative integer with reserved value 28
+    {(uint8_t[]){0x3c}, 1},
+    // Major type negative integer with reserved value 29
+    {(uint8_t[]){0x3d}, 1},
+    // Major type negative integer with reserved value 30
+    {(uint8_t[]){0x3e}, 1},
+    // Major type byte string with reserved value 28 length
+    {(uint8_t[]){0x5c}, 1},
+    // Major type byte string with reserved value 29 length
+    {(uint8_t[]){0x5d}, 1},
+    // Major type byte string with reserved value 30 length
+    {(uint8_t[]){0x5e}, 1},
+    // Major type text string with reserved value 28 length
+    {(uint8_t[]){0x7c}, 1},
+    // Major type text string with reserved value 29 length
+    {(uint8_t[]){0x7d}, 1},
+    // Major type text string with reserved value 30 length
+    {(uint8_t[]){0x7e}, 1},
+    // Major type array with reserved value 28 length
+    {(uint8_t[]){0x9c}, 1},
+    // Major type array with reserved value 29 length
+    {(uint8_t[]){0x9d}, 1},
+    // Major type array with reserved value 30 length
+    {(uint8_t[]){0x9e}, 1},
+    // Major type map with reserved value 28 length
+    {(uint8_t[]){0xbc}, 1},
+    // Major type map with reserved value 29 length
+    {(uint8_t[]){0xbd}, 1},
+    // Major type map with reserved value 30 length
+    {(uint8_t[]){0xbe}, 1},
+    // Major type tag with reserved value 28 length
+    {(uint8_t[]){0xdc}, 1},
+    // Major type tag with reserved value 29 length
+    {(uint8_t[]){0xdd}, 1},
+    // Major type tag with reserved value 30 length
+    {(uint8_t[]){0xde}, 1},
+    // Major type simple with reserved value 28 length
+    {(uint8_t[]){0xfc}, 1},
+    // Major type simple with reserved value 29 length
+    {(uint8_t[]){0xfd}, 1},
+    // Major type simple with reserved value 30 length
+    {(uint8_t[]){0xfe}, 1},
+
+
+    // Maps must have an even number of data items (key & value)
+
+    // Map with 1 item when it should have 2
+    {(uint8_t[]){0xa1, 0x00}, 2},
+    // Map with 3 item when it should have 4
+    {(uint8_t[]){0xa2, 0x00, 0x00, 0x00}, 2},
+    // Map with 1 item when it should have 2
+    {(uint8_t[]){0xbf, 0x00, 0xff}, 3},
+    // Map with 3 item when it should have 4
+    {(uint8_t[]){0xbf, 0x00, 0x00, 0x00, 0xff}, 5},
+
+};
+
+#endif /* not_well_formed_cbor_h */
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 2f2614d..8a79bd8 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -34,6 +34,7 @@
 #include "qcbor.h"
 #include <string.h>
 #include <math.h> // for fabs()
+#include "not_well_formed_cbor.h"
 
 
 #ifdef  PRINT_FUNCTIONS_FOR_DEBUGGING
@@ -654,20 +655,16 @@
 
 int ShortBufferParseTest()
 {
-   int nResult  = 0;
-   QCBORDecodeContext DCtx;
-   int num;
+   int nResult = 0;
 
-   for(num = sizeof(spExpectedEncodedInts)-1; num; num--) {
-      int n;
+   for(int nNum = sizeof(spExpectedEncodedInts)-1; nNum; nNum--) {
+      QCBORDecodeContext DCtx;
 
-      QCBORDecode_Init(&DCtx, (UsefulBufC){spExpectedEncodedInts, num}, QCBOR_DECODE_MODE_NORMAL);
+      QCBORDecode_Init(&DCtx, (UsefulBufC){spExpectedEncodedInts, nNum}, QCBOR_DECODE_MODE_NORMAL);
 
-      n = IntegerValuesParseTestInternal(&DCtx);
+      const QCBORError nErr = IntegerValuesParseTestInternal(&DCtx);
 
-      //printf("Len %d, result: %d\n", num, n);
-
-      if(n != QCBOR_ERR_HIT_END) {
+      if(nErr != QCBOR_ERR_HIT_END && nErr != QCBOR_ERR_NO_MORE_ITEMS) {
          nResult = -1;
          goto Done;
       }
@@ -1329,29 +1326,330 @@
 }
 
 
+static int IsNotWellFormedError(QCBORError nErr)
+{
+   switch(nErr){
+      case QCBOR_ERR_INDEFINITE_STRING_CHUNK:
+      case QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN:
+      case QCBOR_ERR_UNSUPPORTED:
+      case QCBOR_ERR_HIT_END:
+      case QCBOR_ERR_BAD_TYPE_7:
+      case QCBOR_ERR_BAD_BREAK:
+      case QCBOR_ERR_EXTRA_BYTES:
+      case QCBOR_ERR_BAD_INT:
+         return 1;
+      default:
+         return 0;
+   }
+}
+
+
+int NotWellFormedTests()
+{
+   // Loop over all the not-well-formed instance of CBOR
+   // that are test vectors in not_well_formed_cbor.h
+   const uint16_t nArraySize = sizeof(paNotWellFormedCBOR)/sizeof(struct someBinaryBytes);
+   for(uint16_t nIterate = 0; nIterate < nArraySize; nIterate++) {
+      const struct someBinaryBytes *pBytes = &paNotWellFormedCBOR[nIterate];
+      const UsefulBufC Input = (UsefulBufC){pBytes->p, pBytes->n};
+
+      // Set up decoder context. String allocator needed for indefinite string test cases
+      QCBORDecodeContext DCtx;
+      QCBORDecode_Init(&DCtx, Input, QCBOR_DECODE_MODE_NORMAL);
+      UsefulBuf_MAKE_STACK_UB(Pool, 100);
+      QCBORDecode_SetMemPool(&DCtx, Pool, 0);
+
+      // Loop getting items until no more to get
+      QCBORError nCBORError;
+      do {
+         QCBORItem Item;
+
+         nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+      } while(nCBORError == QCBOR_SUCCESS);
+
+      // Every test vector must fail with
+      // a not-well-formed error. If not
+      // this test fails.
+      if(!IsNotWellFormedError(nCBORError)) {
+         // Return index of failure in the error code
+         return 2000 + nIterate;
+      }
+   }
+   return 0;
+}
+
+
 struct FailInput {
    UsefulBufC Input;  // CBOR to decode
    QCBORError nError; // The error expected
 };
 
 struct FailInput  Failures[] = {
-   { {(uint8_t[]){0xa1, 0x00}, 2}, QCBOR_ERR_HIT_END }, //  map with odd number of entries
-   { {(uint8_t[]){0x18}, 1}, QCBOR_ERR_HIT_END },     // 1 byte integer missing the byte
-   { {(uint8_t[]){0x1c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
-   { {(uint8_t[]){0x1d}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 29
-   { {(uint8_t[]){0x1e}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 30
-   { {(uint8_t[]){0x1f}, 1}, QCBOR_ERR_BAD_INT }, // Indefinite length integer
-   { {(uint8_t[]){0x3c}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
-   { {(uint8_t[]){0x3d}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
-   { {(uint8_t[]){0x3e}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
-   { {(uint8_t[]){0x3f}, 1}, QCBOR_ERR_BAD_INT }, // Indefinite length negative integer
-   { {(uint8_t[]){0x41}, 1}, QCBOR_ERR_HIT_END },     // Short byte string
-   { {(uint8_t[]){0x5c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
-   { {(uint8_t[]){0x61}, 1}, QCBOR_ERR_HIT_END },     // Short UTF-8 string
-   { {(uint8_t[]){0x7c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
-   { {(uint8_t[]){0xff}, 1}, QCBOR_ERR_BAD_BREAK } ,  // break
-   { {(uint8_t[]){0xf8, 0x00}, 2}, QCBOR_ERR_BAD_TYPE_7 }, // An invalid encoding of a simple type
-   { {(uint8_t[]){0xf8, 0x1f}, 2}, QCBOR_ERR_BAD_TYPE_7 },  // An invalid encoding of a simple type
+   // Most of this is copied from not_well_formed.h. Here the error code
+   // returned is also checked.
+
+   // Indefinite length strings must be closed off
+   // An indefinite length byte string not closed off
+   { {(uint8_t[]){0x5f, 0x41, 0x00}, 3}, QCBOR_ERR_HIT_END },
+   // An indefinite length text string not closed off
+   { {(uint8_t[]){0x7f, 0x61, 0x00}, 3}, QCBOR_ERR_HIT_END },
+
+
+   // All the chunks in an indefinite length string must be of the type of indefinite length string
+   // indefinite length byte string with text string chunk
+   { {(uint8_t[]){0x5f, 0x61, 0x00, 0xff}, 4}, QCBOR_ERR_INDEFINITE_STRING_CHUNK },
+   // indefinite length text string with a byte string chunk
+   { {(uint8_t[]){0x7f, 0x41, 0x00, 0xff}, 4}, QCBOR_ERR_INDEFINITE_STRING_CHUNK },
+   // indefinite length byte string with an positive integer chunk
+   { {(uint8_t[]){0x5f, 0x00, 0xff}, 3}, QCBOR_ERR_INDEFINITE_STRING_CHUNK },
+   // indefinite length byte string with an negative integer chunk
+   { {(uint8_t[]){0x5f, 0x21, 0xff}, 3}, QCBOR_ERR_INDEFINITE_STRING_CHUNK },
+   // indefinite length byte string with an array chunk
+   { {(uint8_t[]){0x5f, 0x80, 0xff}, 3}, QCBOR_ERR_INDEFINITE_STRING_CHUNK },
+   // indefinite length byte string with an map chunk
+   { {(uint8_t[]){0x5f, 0xa0, 0xff}, 3}, QCBOR_ERR_INDEFINITE_STRING_CHUNK },
+   // indefinite length byte string with tagged integer chunk
+   { {(uint8_t[]){0x5f, 0xc0, 0x00, 0xff}, 4}, QCBOR_ERR_INDEFINITE_STRING_CHUNK },
+   // indefinite length byte string with an simple type chunk
+   { {(uint8_t[]){0x5f, 0xe0, 0xff}, 3}, QCBOR_ERR_INDEFINITE_STRING_CHUNK },
+   { {(uint8_t[]){0x5f, 0x5f, 0x41, 0x00, 0xff, 0xff}, 6}, QCBOR_ERR_INDEFINITE_STRING_CHUNK},
+   // indefinite length text string with indefinite string inside
+   { {(uint8_t[]){0x7f, 0x7f, 0x61, 0x00, 0xff, 0xff}, 6}, QCBOR_ERR_INDEFINITE_STRING_CHUNK},
+
+
+   // Definte length maps and arrays must be closed by having the right number of items
+   // A definte length array that is supposed to have 1 item, but has none
+   { {(uint8_t[]){0x81}, 1}, QCBOR_ERR_HIT_END },
+   // A definte length array that is supposed to have 2 items, but has only 1
+   { {(uint8_t[]){0x82, 0x00}, 2}, QCBOR_ERR_HIT_END },
+   // A definte length array that is supposed to have 511 items, but has only 1
+   { {(uint8_t[]){0x9a, 0x01, 0xff, 0x00}, 4}, QCBOR_ERR_HIT_END },
+   // A definte length map that is supposed to have 1 item, but has none
+   { {(uint8_t[]){0xa1}, 1}, QCBOR_ERR_HIT_END },
+   // A definte length map that is supposed to have s item, but has only 1
+   { {(uint8_t[]){0xa2, 0x01, 0x02}, 3}, QCBOR_ERR_HIT_END },
+
+
+   // 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_HIT_END },
+   // Indefinite length array with two items and no break
+   { {(uint8_t[]){0x9f, 0x01, 0x02}, 3}, QCBOR_ERR_HIT_END },
+   // Indefinite length map with zero items and no break
+   { {(uint8_t[]){0xbf}, 1}, QCBOR_ERR_HIT_END },
+   // Indefinite length map with two items and no break
+   { {(uint8_t[]){0xbf, 0x01, 0x02, 0x01, 0x02}, 5}, QCBOR_ERR_HIT_END },
+
+
+   // Nested maps and arrays must be closed off (some extra nested test vectors)
+   // Unclosed indefinite array containing a close definite array
+   { {(uint8_t[]){0x9f, 0x80, 0x00}, 3}, QCBOR_ERR_HIT_END },
+   // Definite length array containing an unclosed indefinite array
+   { {(uint8_t[]){0x81, 0x9f}, 2}, QCBOR_ERR_HIT_END },
+   // Deeply nested definite length arrays with deepest one unclosed
+   { {(uint8_t[]){0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81}, 9}, QCBOR_ERR_HIT_END },
+   // Deeply nested indefinite length arrays with deepest one unclosed
+   { {(uint8_t[]){0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff}, 9}, QCBOR_ERR_HIT_END },
+   // Mixed nesting with indefinite unclosed
+   { {(uint8_t[]){0x9f, 0x81, 0x9f, 0x81, 0x9f, 0x9f, 0xff, 0xff, 0xff}, 9}, QCBOR_ERR_BAD_BREAK }, // TODO: think through this one
+   // Mixed nesting with definite unclosed
+   { {(uint8_t[]){0x9f, 0x82, 0x9f, 0x81, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff}, 10}, QCBOR_ERR_BAD_BREAK }, // TODO: think through this one
+
+
+   // The "argument" for the data item is incomplete
+   // Positive integer missing 1 byte argument
+   { {(uint8_t[]){0x18}, 1}, QCBOR_ERR_HIT_END },
+   // Positive integer missing 2 byte argument
+   { {(uint8_t[]){0x19}, 1}, QCBOR_ERR_HIT_END },
+   // Positive integer missing 4 byte argument
+   { {(uint8_t[]){0x1a}, 1}, QCBOR_ERR_HIT_END },
+   // Positive integer missing 8 byte argument
+   { {(uint8_t[]){0x1b}, 1}, QCBOR_ERR_HIT_END },
+   // Positive integer missing 1 byte of 2 byte argument
+   { {(uint8_t[]){0x19, 0x01}, 2}, QCBOR_ERR_HIT_END },
+   // Positive integer missing 2 bytes of 4 byte argument
+   { {(uint8_t[]){0x1a, 0x01, 0x02}, 3}, QCBOR_ERR_HIT_END },
+   // Positive integer missing 1 bytes of 7 byte argument
+   { {(uint8_t[]){0x1b, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 8}, QCBOR_ERR_HIT_END },
+   // Negative integer missing 1 byte argument
+   { {(uint8_t[]){0x38}, 1}, QCBOR_ERR_HIT_END },
+   // Binary string missing 1 byte argument
+   { {(uint8_t[]){0x58}, 1}, QCBOR_ERR_HIT_END },
+   // Text string missing 1 byte argument
+   { {(uint8_t[]){0x78}, 1}, QCBOR_ERR_HIT_END },
+   // Array missing 1 byte argument
+   { {(uint8_t[]){0x98}, 1}, QCBOR_ERR_HIT_END },
+   // Map missing 1 byte argument
+   { {(uint8_t[]){0xb8}, 1}, QCBOR_ERR_HIT_END },
+   // Tag missing 1 byte argument
+   { {(uint8_t[]){0xd8}, 1}, QCBOR_ERR_HIT_END },
+   // Simple missing 1 byte argument
+   { {(uint8_t[]){0xf8}, 1}, QCBOR_ERR_HIT_END },
+
+
+   // Breaks must not occur in definite length arrays and maps
+   // Array of length 1 with sole member replaced by a break
+   { {(uint8_t[]){0x81, 0xff}, 2}, QCBOR_ERR_BAD_BREAK },
+   // Array of length 2 with 2nd member replaced by a break
+   { {(uint8_t[]){0x82, 0x00, 0xff}, 3}, QCBOR_ERR_BAD_BREAK },
+   // Map of length 1 with sole member label replaced by a break
+   { {(uint8_t[]){0xa1, 0xff}, 2}, QCBOR_ERR_BAD_BREAK },
+   // Map of length 1 with sole member label replaced by break
+   // Alternate representation that some decoders handle difference
+   { {(uint8_t[]){0xa1, 0xff, 0x00}, 3}, QCBOR_ERR_BAD_BREAK },
+   // Array of length 1 with 2nd member value replaced by a break
+   { {(uint8_t[]){0xa1, 0x00, 0xff}, 3}, QCBOR_ERR_BAD_BREAK },
+   // Map of length 2 with 2nd member replaced by a break
+   { {(uint8_t[]){0xa2, 0x00, 0x00, 0xff}, 4}, QCBOR_ERR_BAD_BREAK },
+
+
+   // Breaks must not occur on their own out of an indefinite length data item
+   // A bare break is not well formed
+   { {(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 },
+   // A bare break after a zero length indefinite length map
+   { {(uint8_t[]){0x9f, 0xff, 0xff}, 3}, QCBOR_ERR_BAD_BREAK },
+
+
+   // Forbidden two byte encodings of simple types
+   // Must use 0xe0 instead
+   { {(uint8_t[]){0xf8, 0x00}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xe1 instead
+   { {(uint8_t[]){0xf8, 0x01}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xe2 instead
+   { {(uint8_t[]){0xf8, 0x02}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xe3 instead
+   { {(uint8_t[]){0xf8, 0x03}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xe4 instead
+   { {(uint8_t[]){0xf8, 0x04}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xe5 instead
+   { {(uint8_t[]){0xf8, 0x05}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xe6 instead
+   { {(uint8_t[]){0xf8, 0x06}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xe7 instead
+   { {(uint8_t[]){0xf8, 0x07}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xe8 instead
+   { {(uint8_t[]){0xf8, 0x08}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xe9 instead
+   { {(uint8_t[]){0xf8, 0x09}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xea instead
+   { {(uint8_t[]){0xf8, 0x0a}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xeb instead
+   { {(uint8_t[]){0xf8, 0x0b}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xec instead
+   { {(uint8_t[]){0xf8, 0x0c}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xed instead
+   { {(uint8_t[]){0xf8, 0x0d}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xee instead
+   { {(uint8_t[]){0xf8, 0x0e}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xef instead
+   { {(uint8_t[]){0xf8, 0x0f}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xf0 instead
+   { {(uint8_t[]){0xf8, 0x10}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xf1 instead
+   { {(uint8_t[]){0xf8, 0x11}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Should use 0xf2 instead
+   { {(uint8_t[]){0xf8, 0x12}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Must use 0xf3 instead
+   { {(uint8_t[]){0xf8, 0x13}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Must use 0xf4 instead
+   { {(uint8_t[]){0xf8, 0x14}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Must use 0xf5 instead
+   { {(uint8_t[]){0xf8, 0x15}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Must use 0xf6 instead
+   { {(uint8_t[]){0xf8, 0x16}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Must use 0xf7 instead
+   { {(uint8_t[]){0xf8, 0x17}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+   // Must use 0xf8 instead
+   { {(uint8_t[]){0xf8, 0x18}, 2}, QCBOR_ERR_BAD_TYPE_7 },
+
+
+   // Integers with additional info indefinite length
+   // Positive integer with additional info indefinite length
+   { {(uint8_t[]){0x1f}, 1}, QCBOR_ERR_BAD_INT },
+   // Negative integer with additional info indefinite length
+   { {(uint8_t[]){0x3f}, 1}, QCBOR_ERR_BAD_INT },
+   // CBOR tag with "argument" an indefinite length
+   { {(uint8_t[]){0xdf, 0x00}, 2}, QCBOR_ERR_BAD_INT },
+   // CBOR tag with "argument" an indefinite length alternate vector
+   { {(uint8_t[]){0xdf}, 1}, QCBOR_ERR_BAD_INT },
+
+
+   // Missing bytes from a deterministic length string
+   // A byte string is of length 1 without the 1 byte
+   { {(uint8_t[]){0x41}, 1}, QCBOR_ERR_HIT_END },
+   // A text string is of length 1 without the 1 byte
+   { {(uint8_t[]){0x61}, 1}, QCBOR_ERR_HIT_END },
+   // Byte string should have 2^32-1 bytes, but has one
+   { {(uint8_t[]){0x5a, 0xff, 0xff, 0xff, 0xff, 0x00}, 6}, QCBOR_ERR_HIT_END },
+   // Byte string should have 2^32-1 bytes, but has one
+   { {(uint8_t[]){0x7a, 0xff, 0xff, 0xff, 0xff, 0x00}, 6}, QCBOR_ERR_HIT_END },
+
+
+   // Use of unassigned additional information values
+   // Major type positive integer with reserved value 28
+   { {(uint8_t[]){0x1c}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type positive integer with reserved value 29
+   { {(uint8_t[]){0x1d}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type positive integer with reserved value 30
+   { {(uint8_t[]){0x1e}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type negative integer with reserved value 28
+   { {(uint8_t[]){0x3c}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type negative integer with reserved value 29
+   { {(uint8_t[]){0x3d}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type negative integer with reserved value 30
+   { {(uint8_t[]){0x3e}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type byte string with reserved value 28 length
+   { {(uint8_t[]){0x5c}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type byte string with reserved value 29 length
+   { {(uint8_t[]){0x5d}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type byte string with reserved value 30 length
+   { {(uint8_t[]){0x5e}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type text string with reserved value 28 length
+   { {(uint8_t[]){0x7c}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type text string with reserved value 29 length
+   { {(uint8_t[]){0x7d}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type text string with reserved value 30 length
+   { {(uint8_t[]){0x7e}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type array with reserved value 28 length
+   { {(uint8_t[]){0x9c}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type array with reserved value 29 length
+   { {(uint8_t[]){0x9d}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type array with reserved value 30 length
+   { {(uint8_t[]){0x9e}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type map with reserved value 28 length
+   { {(uint8_t[]){0xbc}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type map with reserved value 29 length
+   { {(uint8_t[]){0xbd}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type map with reserved value 30 length
+   { {(uint8_t[]){0xbe}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type tag with reserved value 28 length
+   { {(uint8_t[]){0xdc}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type tag with reserved value 29 length
+   { {(uint8_t[]){0xdd}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type tag with reserved value 30 length
+   { {(uint8_t[]){0xde}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type simple with reserved value 28 length
+   { {(uint8_t[]){0xfc}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type simple with reserved value 29 length
+   { {(uint8_t[]){0xfd}, 1}, QCBOR_ERR_UNSUPPORTED },
+   // Major type simple with reserved value 30 length
+   { {(uint8_t[]){0xfe}, 1}, QCBOR_ERR_UNSUPPORTED },
+
+
+   // Maps must have an even number of data items (key & value)
+   // Map with 1 item when it should have 2
+   { {(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 },
+   // 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 },
+
+
+   // In addition to not-well-formed, some invalid CBOR
    { {(uint8_t[]){0xc0, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG },  // Text-based date, with an integer
    { {(uint8_t[]){0xc1, 0x41, 0x33}, 3}, QCBOR_ERR_BAD_OPT_TAG },   // Epoch date, with an byte string
    { {(uint8_t[]){0xc1, 0xc0, 0x00}, 3}, QCBOR_ERR_BAD_OPT_TAG },   // tagged as both epoch and string dates
@@ -1363,29 +1661,29 @@
    // Loop over the failures
    const struct FailInput * const pFEnd = &Failures[0] +
                                           sizeof(Failures)/sizeof(struct FailInput);
-
    for(const struct FailInput *pF = &Failures[0]; pF < pFEnd ;pF++) {
+
+      // Set up the decoding context including a mem pool so that
+      // indefinite length items can be checked
       QCBORDecodeContext DCtx;
-      QCBORItem          Item;
-      QCBORError         nCBORError;
-
       QCBORDecode_Init(&DCtx, pF->Input, QCBOR_DECODE_MODE_NORMAL);
+      UsefulBuf_MAKE_STACK_UB(Pool, 100);
+      QCBORError nCBORError = QCBORDecode_SetMemPool(&DCtx, Pool, 0);
+      if(nCBORError) {
+         return -9;
+      }
 
-      while(1) {
+      // Iterate until there is an error of some sort
+      do {
+         QCBORItem Item;
+
          nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
-         if(QCBOR_SUCCESS == nCBORError) {
-            // Must end in an error, so if success keep going
-            continue;
-         }
+      } while(nCBORError == QCBOR_SUCCESS);
 
-         if(nCBORError != pF->nError) {
-            // Not success, nor error expected so a test failure
-            // Return code is 1000 plus index into Failures of test that failed
-            return 1000 + (int)(pF - &Failures[0]);
-         } else {
-            // Got the error expected
-            break;
-         }
+      // Must get the expected error or the this test fails
+      if(nCBORError != pF->nError) {
+         // return index of CBOR + 1000
+         return 1000 + (int)(pF - &Failures[0]);
       }
    }
 
diff --git a/test/qcbor_decode_tests.h b/test/qcbor_decode_tests.h
index 79d5e46..6159c8b 100644
--- a/test/qcbor_decode_tests.h
+++ b/test/qcbor_decode_tests.h
@@ -130,6 +130,13 @@
 int ParseSimpleTest(void);
 
 
+/*
+ This tests all the not-well-formed CBOR from the CBOR RFC.
+ (This is the CBORbis RFC which is not yet published at the
+ time this test was added).
+ */
+int NotWellFormedTests(void);
+
 
 /*
  Tests a number of failure cases on bad CBOR to get the right error code
diff --git a/test/qcbor_encode_tests.c b/test/qcbor_encode_tests.c
index ea6363b..7866b37 100644
--- a/test/qcbor_encode_tests.c
+++ b/test/qcbor_encode_tests.c
@@ -1852,7 +1852,7 @@
    }
 
    nReturn = QCBORDecode_GetNext(&DC, &Item);
-   if(nReturn == QCBOR_ERR_HIT_END) {
+   if(nReturn == QCBOR_ERR_HIT_END || nReturn == QCBOR_ERR_NO_MORE_ITEMS) {
       return 0;
    }
    if(Item.uDataType != QCBOR_TYPE_BYTE_STRING) {
@@ -2314,5 +2314,20 @@
       return -11;
    }
 
+   // ------ QCBOR_ERR_UNSUPPORTED --------
+   QCBOREncode_Init(&EC, Large);
+   QCBOREncode_OpenArray(&EC);
+   QCBOREncode_AddSimple(&EC, 24); // CBOR_SIMPLEV_RESERVED_START
+   if(QCBOREncode_FinishGetSize(&EC, &xx) != QCBOR_ERR_UNSUPPORTED) {
+      return -12;
+   }
+
+   QCBOREncode_Init(&EC, Large);
+   QCBOREncode_OpenArray(&EC);
+   QCBOREncode_AddSimple(&EC, 31); // CBOR_SIMPLEV_RESERVED_END
+   if(QCBOREncode_FinishGetSize(&EC, &xx) != QCBOR_ERR_UNSUPPORTED) {
+      return -13;
+   }
+
    return 0;
 }
diff --git a/test/run_tests.c b/test/run_tests.c
index 9094e35..374b40e 100644
--- a/test/run_tests.c
+++ b/test/run_tests.c
@@ -100,6 +100,7 @@
 
 
 test_entry s_tests[] = {
+    TEST_ENTRY(NotWellFormedTests),
     TEST_ENTRY(ParseMapAsArrayTest),
     TEST_ENTRY(AllocAllStringsTest),
     TEST_ENTRY(IndefiniteLengthNestTest),