Have std/cbor reject tags before an 0xFF stop code
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 12b0edf..dd48c0d 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -5761,6 +5761,7 @@
       uint64_t v_string_length;
       uint32_t v_depth;
       uint32_t v_token_length;
+      bool v_tagged;
       uint8_t v_indefinite_string_major_type;
     } s_decode_tokens[1];
   } private_data;
@@ -16759,6 +16760,7 @@
   uint8_t v_c = 0;
   uint8_t v_c_major = 0;
   uint8_t v_c_minor = 0;
+  bool v_tagged = false;
   uint8_t v_indefinite_string_major_type = 0;
 
   wuffs_base__token* iop_a_dst = NULL;
@@ -16790,6 +16792,7 @@
     v_string_length = self->private_data.s_decode_tokens[0].v_string_length;
     v_depth = self->private_data.s_decode_tokens[0].v_depth;
     v_token_length = self->private_data.s_decode_tokens[0].v_token_length;
+    v_tagged = self->private_data.s_decode_tokens[0].v_tagged;
     v_indefinite_string_major_type = self->private_data.s_decode_tokens[0].v_indefinite_string_major_type;
   }
   switch (coro_susp_point) {
@@ -17089,6 +17092,7 @@
             self->private_data.f_stack[v_stack_byte] &= (4294967295 ^ (((uint32_t)(3)) << v_stack_bit));
             self->private_data.f_container_num_remaining[v_depth] = v_string_length;
             v_depth += 1;
+            v_tagged = false;
             goto label__outer__continue;
           } else if (v_c_major == 5) {
             if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0) {
@@ -17124,6 +17128,7 @@
             self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(3)) << v_stack_bit);
             self->private_data.f_container_num_remaining[v_depth] = v_string_length;
             v_depth += 1;
+            v_tagged = false;
             goto label__outer__continue;
           } else if (v_c_major == 6) {
             if (v_c_minor >= 28) {
@@ -17144,6 +17149,7 @@
                   (~(v_string_length & 70368744177663) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
             }
+            v_tagged = true;
             goto label__outer__continue;
           } else if (v_c_major == 7) {
             if (v_c_minor < 20) {
@@ -17172,7 +17178,7 @@
                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
               goto label__goto_parsed_a_leaf_value__break;
             } else if (v_c_minor == 31) {
-              if (v_depth <= 0) {
+              if (v_tagged || (v_depth <= 0)) {
                 goto label__goto_fail__break;
               }
               v_depth -= 1;
@@ -17219,6 +17225,7 @@
         goto exit;
       }
       label__goto_parsed_a_leaf_value__break:;
+      v_tagged = false;
       while (v_depth > 0) {
         v_stack_byte = ((v_depth - 1) / 16);
         v_stack_bit = (((v_depth - 1) & 15) * 2);
@@ -17280,6 +17287,7 @@
   self->private_data.s_decode_tokens[0].v_string_length = v_string_length;
   self->private_data.s_decode_tokens[0].v_depth = v_depth;
   self->private_data.s_decode_tokens[0].v_token_length = v_token_length;
+  self->private_data.s_decode_tokens[0].v_tagged = v_tagged;
   self->private_data.s_decode_tokens[0].v_indefinite_string_major_type = v_indefinite_string_major_type;
 
   goto exit;
diff --git a/std/cbor/decode_cbor.wuffs b/std/cbor/decode_cbor.wuffs
index 7153384..f28d4c1 100644
--- a/std/cbor/decode_cbor.wuffs
+++ b/std/cbor/decode_cbor.wuffs
@@ -112,6 +112,7 @@
 	var c            : base.u8
 	var c_major      : base.u8[..= 0x07]
 	var c_minor      : base.u8[..= 0x1F]
+	var tagged       : base.bool
 
 	// indefinite_string_major_type is 2 or 3 when we are in an
 	// indefinite-length byte string or text string. It is 0 otherwise.
@@ -484,6 +485,7 @@
 			this.stack[stack_byte] &= 0xFFFF_FFFF ^ ((3 as base.u32) << stack_bit)
 			this.container_num_remaining[depth] = string_length
 			depth += 1
+			tagged = false
 			continue.outer
 			// -------- END   Major type 4: an array of data items.
 
@@ -545,6 +547,7 @@
 			this.stack[stack_byte] |= (3 as base.u32) << stack_bit
 			this.container_num_remaining[depth] = string_length
 			depth += 1
+			tagged = false
 			continue.outer
 			// -------- END   Major type 5: a map of pairs of data items.
 
@@ -573,6 +576,7 @@
 					continued: 0,
 					length: TOKEN_LENGTHS[c_minor] as base.u32)
 			}
+			tagged = true
 			continue.outer
 			// -------- END   Major type 6: tags.
 
@@ -621,7 +625,7 @@
 			} else if c_minor == 0x1F {
 				// Indefinite-length strings were dealt with separately, above.
 				// Here, we expect to be in an indefinite-length container.
-				if depth <= 0 {
+				if tagged or (depth <= 0) {
 					break.goto_fail
 				}
 				depth -= 1
@@ -683,6 +687,7 @@
 
 		// We've just parsed a leaf (non-container) value, or the (explicit or
 		// implicit) close of a container (array or object).
+		tagged = false
 		while depth > 0 {
 			// Toggle the key/value bit for object containers. This bit is
 			// ignored for array containers.
diff --git a/test/c/std/cbor.c b/test/c/std/cbor.c
index cc7076e..fdf6603 100644
--- a/test/c/std/cbor.c
+++ b/test/c/std/cbor.c
@@ -103,10 +103,16 @@
   char* test_cases[] = {
       // Truncated (integer; major type 0) value.
       "\x18",
+      // Tag in array, immediately before an 0xFF stop code. Some discussion is
+      // at https://github.com/cbor/cbor.github.io/issues/65
+      "\x9F\xD0\xFF",
       // Map with 1 element (an odd number).
       "\xA1\x01",
       // Map with 3 elements (an odd number).
       "\xBF\x01\x02\x03\xFF",
+      // Tag in map, immediately before an 0xFF stop code. Some discussion is
+      // at https://github.com/cbor/cbor.github.io/issues/65
+      "\xBF\xD0\xFF",
       // Unused opcode.
       "\xFE",
   };
@@ -147,6 +153,10 @@
   char* test_cases[] = {
       // Map with 2 elements (an even number).
       "\xA1\x01\x02",
+      // Tag immediately before an empty array.
+      "\xD0\x9F\xFF",
+      // Tag immediately before an empty map.
+      "\xD0\xBF\xFF",
   };
 
   int tc;