From 9ba865f54d331c550629304cb25e77ac81455803 Mon Sep 17 00:00:00 2001
From: Juraj Vijtiuk <juraj.vijtiuk@sartura.hr>
Date: Wed, 13 Oct 2021 18:32:53 +0200
Upstream: yes
References: bsc#1196505, CVE-2022-26125
Subject: [PATCH] isisd: fix router capability TLV parsing issues

Backport of the patch to frr-7.4 by Marius Tomaschewski <mt@suse.com>

isis_tlvs.c would fail at multiple places if incorrect TLVs were
received causing stream assertion violations.
This patch fixes the issues by adding missing length checks, missing
consumed length updates and handling malformed Segment Routing subTLVs.

Signed-off-by: Juraj Vijtiuk <juraj.vijtiuk@sartura.hr>

Small adjustments by Igor Ryzhov:
- fix incorrect replacement of srgb by srlb on lines 3052 and 3054
- add length check for ISIS_SUBTLV_ALGORITHM
- fix conflict in fuzzing data during rebase

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>

diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c
index 923956fa6..e9f615c47 100644
--- a/isisd/isis_tlvs.c
+++ b/isisd/isis_tlvs.c
@@ -2721,10 +2721,11 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,
 				       void *dest, int indent)
 {
 	struct isis_tlvs *tlvs = dest;
+	struct isis_router_cap *rcap;
 	uint8_t type;
 	uint8_t length;
 	uint8_t subtlv_len;
-	uint8_t sid_len;
+	uint8_t size;
 
 	sbuf_push(log, indent, "Unpacking Router Capability TLV...\n");
 	if (tlv_len < ISIS_ROUTER_CAP_SIZE) {
@@ -2741,47 +2742,89 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,
 	}
 
 	/* Allocate router cap structure and initialize SR Algorithms */
-	tlvs->router_cap = XCALLOC(MTYPE_ISIS_TLV, sizeof(*tlvs->router_cap));
+	rcap = XCALLOC(MTYPE_ISIS_TLV, sizeof(struct isis_router_cap));
 	for (int i = 0; i < SR_ALGORITHM_COUNT; i++)
-		tlvs->router_cap->algo[i] = SR_ALGORITHM_UNSET;
+		rcap->algo[i] = SR_ALGORITHM_UNSET;
 
 	/* Get Router ID and Flags */
-	tlvs->router_cap->router_id.s_addr = stream_get_ipv4(s);
-	tlvs->router_cap->flags = stream_getc(s);
+	rcap->router_id.s_addr = stream_get_ipv4(s);
+	rcap->flags = stream_getc(s);
 
 	/* Parse remaining part of the TLV if present */
 	subtlv_len = tlv_len - ISIS_ROUTER_CAP_SIZE;
 	while (subtlv_len > 2) {
-		struct isis_router_cap *rc = tlvs->router_cap;
 		uint8_t msd_type;
 
 		type = stream_getc(s);
 		length = stream_getc(s);
+
+		if (length > STREAM_READABLE(s) || length > subtlv_len - 2) {
+			sbuf_push(
+				log, indent,
+				"WARNING: Router Capability subTLV length too large compared to expected size\n");
+			stream_forward_getp(s, STREAM_READABLE(s));
+			return 0;
+		}
+
 		switch (type) {
 		case ISIS_SUBTLV_SID_LABEL_RANGE:
-			rc->srgb.flags = stream_getc(s);
-			rc->srgb.range_size = stream_get3(s);
+			/* Check that SRGB is correctly formated */
+			if (length < SUBTLV_RANGE_LABEL_SIZE
+			    || length > SUBTLV_RANGE_INDEX_SIZE) {
+				stream_forward_getp(s, length);
+				break;
+			}
+			/* Only one SRGB is supported. Skip subsequent one */
+			if (rcap->srgb.range_size != 0) {
+				stream_forward_getp(s, length);
+				break;
+			}
+			rcap->srgb.flags = stream_getc(s);
+			rcap->srgb.range_size = stream_get3(s);
 			/* Skip Type and get Length of SID Label */
 			stream_getc(s);
-			sid_len = stream_getc(s);
-			if (sid_len == ISIS_SUBTLV_SID_LABEL_SIZE)
-				rc->srgb.lower_bound = stream_get3(s);
-			else
-				rc->srgb.lower_bound = stream_getl(s);
+			size = stream_getc(s);
+
+			if (size == ISIS_SUBTLV_SID_LABEL_SIZE
+			    && length != SUBTLV_RANGE_LABEL_SIZE) {
+				stream_forward_getp(s, length - 6);
+				break;
+			}
+			if (size == ISIS_SUBTLV_SID_INDEX_SIZE
+			    && length != SUBTLV_RANGE_INDEX_SIZE) {
+				stream_forward_getp(s, length - 6);
+				break;
+			}
+
+			if (size == ISIS_SUBTLV_SID_LABEL_SIZE) {
+				rcap->srgb.lower_bound = stream_get3(s);
+			} else if (size == ISIS_SUBTLV_SID_INDEX_SIZE) {
+				rcap->srgb.lower_bound = stream_getl(s);
+			} else {
+				stream_forward_getp(s, length - 6);
+				break;
+			}
 
 			/* SRGB sanity checks. */
-			if (rc->srgb.range_size == 0
-			    || (rc->srgb.lower_bound <= MPLS_LABEL_RESERVED_MAX)
-			    || ((rc->srgb.lower_bound + rc->srgb.range_size - 1)
+			if (rcap->srgb.range_size == 0
+			    || (rcap->srgb.lower_bound <= MPLS_LABEL_RESERVED_MAX)
+			    || ((rcap->srgb.lower_bound + rcap->srgb.range_size - 1)
 				> MPLS_LABEL_UNRESERVED_MAX)) {
 				sbuf_push(log, indent, "Invalid label range. Reset SRGB\n");
-				rc->srgb.lower_bound = 0;
-				rc->srgb.range_size = 0;
+				rcap->srgb.lower_bound = 0;
+				rcap->srgb.range_size = 0;
 			}
+			/* Only one range is supported. Skip subsequent one */
+			size = length - (size + SUBTLV_SR_BLOCK_SIZE);
+			if (size > 0)
+				stream_forward_getp(s, size);
+
 			break;
 		case ISIS_SUBTLV_ALGORITHM:
+			if (length == 0)
+				break;
 			/* Only 2 algorithms are supported: SPF & Strict SPF */
-			stream_get(&rc->algo, s,
+			stream_get(&rcap->algo, s,
 				   length > SR_ALGORITHM_COUNT
 					   ? SR_ALGORITHM_COUNT
 					   : length);
@@ -2790,11 +2833,19 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,
 					s, length - SR_ALGORITHM_COUNT);
 			break;
 		case ISIS_SUBTLV_NODE_MSD:
+			/* Check that MSD is correctly formated */
+			if (length < MSD_TLV_SIZE) {
+				stream_forward_getp(s, length);
+				break;
+			}
 			msd_type = stream_getc(s);
-			rc->msd = stream_getc(s);
+			rcap->msd = stream_getc(s);
 			/* Only BMI-MSD type has been defined in RFC 8491 */
 			if (msd_type != MSD_TYPE_BASE_MPLS_IMPOSITION)
-				rc->msd = 0;
+				rcap->msd = 0;
+			/* Only one MSD is standardized. Skip others */
+			if (length > MSD_TLV_SIZE)
+				stream_forward_getp(s, length - MSD_TLV_SIZE);
 			break;
 		default:
 			stream_forward_getp(s, length);
@@ -2802,6 +2853,7 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,
 		}
 		subtlv_len = subtlv_len - length - 2;
 	}
+	tlvs->router_cap = rcap;
 	return 0;
 }
 
diff --git a/isisd/isis_tlvs.h b/isisd/isis_tlvs.h
index f468d85bb..0278d18de 100644
--- a/isisd/isis_tlvs.h
+++ b/isisd/isis_tlvs.h
@@ -140,6 +140,9 @@ struct isis_threeway_adj {
 #define ISIS_SUBTLV_SRGB_FLAG_V		0x40
 #define IS_SR_IPV4(srgb)               (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_I)
 #define IS_SR_IPV6(srgb)               (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_V)
+#define SUBTLV_SR_BLOCK_SIZE            6
+#define SUBTLV_RANGE_INDEX_SIZE         10
+#define SUBTLV_RANGE_LABEL_SIZE         9
 
 /* Structure aggregating SRGB info */
 struct isis_srgb {
@@ -209,6 +212,9 @@ struct isis_lan_adj_sid {
 #define SR_ALGORITHM_STRICT_SPF	1
 #define SR_ALGORITHM_UNSET	255
 
+#define MSD_TYPE_BASE_MPLS_IMPOSITION  0x01
+#define MSD_TLV_SIZE            2
+
 struct isis_router_cap {
 	struct in_addr router_id;
 	uint8_t flags;
@@ -217,7 +223,6 @@ struct isis_router_cap {
 	struct isis_srgb srgb;
 	uint8_t algo[SR_ALGORITHM_COUNT];
 	/* RFC 8491 */
-#define MSD_TYPE_BASE_MPLS_IMPOSITION  0x01
 	uint8_t msd;
 };
 
@@ -433,6 +438,7 @@ enum ext_subtlv_size {
 
 	/* RFC 8667 section #2 */
 	ISIS_SUBTLV_SID_LABEL_SIZE = 3,
+	ISIS_SUBTLV_SID_INDEX_SIZE = 4,
 	ISIS_SUBTLV_SID_LABEL_RANGE_SIZE = 9,
 	ISIS_SUBTLV_ALGORITHM_SIZE = 4,
 	ISIS_SUBTLV_ADJ_SID_SIZE = 5,
#
# Extracted:
#  diff --git a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
#  index 4f59d1d7c044b4c3754c0cb077019659a045f51c..b3ed311b4178d72b719dc7ae9cca2ea451404f47 100644
#  GIT binary patch
#  delta 18831
--- a/tests/isisd/test_fuzz_isis_tlv_tests.h
+++ b/tests/isisd/test_fuzz_isis_tlv_tests.h
@@ -2731,9 +2731,9 @@
 	{
 		.input = "\xc1\x0d\x49\x10\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x0c\xfd\xd4\x80\xf2\xff\xfc\x7f\x08\xf5\xeb\x0d\xee\x97\x01\xa1\xa5\x65\x80\xf2\xf0\xe7\x21\x04\x7f\xff\x08\xf5\x54\x54\xcc\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x64\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x34\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\xcc\x54\x54\x54\x54\x54\x54\x43\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x38\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xff\xff\xf6\x00\x00\x00\x00\x00\x00\x00\x80\xff\xff\xff\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x00\x00\x00\x80\xff\xff\xff\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2c\x30\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xd8\xd8\xd8\xd8\xd8\x05\xff\xff\x05\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xf2\x00\x00\x10\xde\xff\xff\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12",
 		.input_len = 564,
-		.output = "\x43\x6f\x75\x6c\x64\x20\x6e\x6f\x74\x20\x75\x6e\x70\x61\x63\x6b\x20\x54\x4c\x56\x73\x3a\x0a\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x35\x36\x34\x20\x62\x79\x74\x65\x73\x20\x6f\x66\x20\x54\x4c\x56\x73\x2e\x2e\x2e\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x31\x39\x33\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x33\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x31\x39\x33\x20\x28\x31\x33\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x32\x34\x32\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x32\x2e\x0a\x20\x20\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x52\x6f\x75\x74\x65\x72\x20\x43\x61\x70\x61\x62\x69\x6c\x69\x74\x79\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x41\x76\x61\x69\x6c\x61\x62\x6c\x65\x20\x64\x61\x74\x61\x20\x31\x20\x74\x6f\x6f\x20\x73\x68\x6f\x72\x74\x20\x74\x6f\x20\x63\x6f\x6e\x74\x61\x69\x6e\x20\x61\x20\x54\x4c\x56\x20\x68\x65\x61\x64\x65\x72\x2e\x0a\x0a",
-		.output_len = 1415,
-		.ret = 2
+		.output = "\x55\x6e\x70\x61\x63\x6b\x20\x6c\x6f\x67\x3a\x0a\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x35\x36\x34\x20\x62\x79\x74\x65\x73\x20\x6f\x66\x20\x54\x4c\x56\x73\x2e\x2e\x2e\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x31\x39\x33\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x33\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x31\x39\x33\x20\x28\x31\x33\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x32\x34\x32\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x32\x2e\x0a\x20\x20\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x52\x6f\x75\x74\x65\x72\x20\x43\x61\x70\x61\x62\x69\x6c\x69\x74\x79\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x57\x41\x52\x4e\x49\x4e\x47\x3a\x20\x52\x6f\x75\x74\x65\x72\x20\x43\x61\x70\x61\x62\x69\x6c\x69\x74\x79\x20\x73\x75\x62\x54\x4c\x56\x20\x6c\x65\x6e\x67\x74\x68\x20\x74\x6f\x6f\x20\x6c\x61\x72\x67\x65\x20\x63\x6f\x6d\x70\x61\x72\x65\x64\x20\x74\x6f\x20\x65\x78\x70\x65\x63\x74\x65\x64\x20\x73\x69\x7a\x65\x0a\x55\x6e\x70\x61\x63\x6b\x65\x64\x20\x54\x4c\x56\x73\x3a\x0a",
+		.output_len = 514,
+		.ret = 0
 	},
 
 	{
@@ -3003,9 +3003,9 @@
 	{
 		.input = "\x81\x0d\x49\x10\xff\xff\xff\x65\x0a\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x54\x54\x08\xf5\xeb\x0d\x97\x80\xf2\x0c\xfd\xd4\x80\xf2\xff\xfc\x7f\x08\xf5\xeb\x0d\xee\x97\x01\xa1\xa7\x65\x80\xf2\xf0\xf5\x21\x04\x7f\xff\x08\xf5\x54\x54\xcc\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x00\xfd\x0a\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x54\x54\x6b\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\xcc\x54\x54\x54\x54\x54\x54\x41\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x00\x00\x2c\x2c\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x00\x0b\x00\x00\x00\x05\xff\xff\x05\x00\x00\x00\x00\x00\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x36\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x54\x54\x54\x54\x54\x00\x00\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\x00\x00\x00\x00\x00\x00\x00\x52\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfb\x00\x00\x04\x00\x00\x00\x00\x00\xff\x00\x00\xff\xf2\x00\x00\x00\xde\xff\xff\x00\xff\xff\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x12",
 		.input_len = 403,
-		.output = "\x43\x6f\x75\x6c\x64\x20\x6e\x6f\x74\x20\x75\x6e\x70\x61\x63\x6b\x20\x54\x4c\x56\x73\x3a\x0a\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x34\x30\x33\x20\x62\x79\x74\x65\x73\x20\x6f\x66\x20\x54\x4c\x56\x73\x2e\x2e\x2e\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x31\x32\x39\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x33\x2e\x0a\x20\x20\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x50\x72\x6f\x74\x6f\x63\x6f\x6c\x73\x20\x53\x75\x70\x70\x6f\x72\x74\x65\x64\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x20\x20\x50\x72\x6f\x74\x6f\x63\x6f\x6c\x73\x20\x53\x75\x70\x70\x6f\x72\x74\x65\x64\x3a\x20\x37\x33\x2c\x20\x31\x36\x2c\x20\x32\x35\x35\x2c\x20\x32\x35\x35\x2c\x20\x32\x35\x35\x2c\x20\x31\x30\x31\x2c\x20\x31\x30\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x31\x31\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x31\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x31\x31\x20\x28\x31\x31\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x32\x34\x32\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x32\x2e\x0a\x20\x20\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x52\x6f\x75\x74\x65\x72\x20\x43\x61\x70\x61\x62\x69\x6c\x69\x74\x79\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x30\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x30\x20\x28\x30\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x30\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x32\x35\x35\x2e\x0a\x20\x20\x20\x20\x41\x76\x61\x69\x6c\x61\x62\x6c\x65\x20\x64\x61\x74\x61\x20\x39\x31\x20\x74\x6f\x6f\x20\x73\x68\x6f\x72\x74\x20\x66\x6f\x72\x20\x63\x6c\x61\x69\x6d\x65\x64\x20\x54\x4c\x56\x20\x6c\x65\x6e\x20\x32\x35\x35\x2e\x0a\x0a",
-		.output_len = 1176,
-		.ret = 2
+		.output = "\x55\x6e\x70\x61\x63\x6b\x20\x6c\x6f\x67\x3a\x0a\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x34\x30\x33\x20\x62\x79\x74\x65\x73\x20\x6f\x66\x20\x54\x4c\x56\x73\x2e\x2e\x2e\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x31\x32\x39\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x33\x2e\x0a\x20\x20\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x50\x72\x6f\x74\x6f\x63\x6f\x6c\x73\x20\x53\x75\x70\x70\x6f\x72\x74\x65\x64\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x20\x20\x50\x72\x6f\x74\x6f\x63\x6f\x6c\x73\x20\x53\x75\x70\x70\x6f\x72\x74\x65\x64\x3a\x20\x37\x33\x2c\x20\x31\x36\x2c\x20\x32\x35\x35\x2c\x20\x32\x35\x35\x2c\x20\x32\x35\x35\x2c\x20\x31\x30\x31\x2c\x20\x31\x30\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x31\x31\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x31\x2e\x0a\x20\x20\x20\x20\x53\x6b\x69\x70\x70\x69\x6e\x67\x20\x75\x6e\x6b\x6e\x6f\x77\x6e\x20\x54\x4c\x56\x20\x31\x31\x20\x28\x31\x31\x20\x62\x79\x74\x65\x73\x29\x0a\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x46\x6f\x75\x6e\x64\x20\x54\x4c\x56\x20\x6f\x66\x20\x74\x79\x70\x65\x20\x32\x34\x32\x20\x61\x6e\x64\x20\x6c\x65\x6e\x20\x31\x32\x2e\x0a\x20\x20\x20\x20\x55\x6e\x70\x61\x63\x6b\x69\x6e\x67\x20\x52\x6f\x75\x74\x65\x72\x20\x43\x61\x70\x61\x62\x69\x6c\x69\x74\x79\x20\x54\x4c\x56\x2e\x2e\x2e\x0a\x20\x20\x20\x20\x57\x41\x52\x4e\x49\x4e\x47\x3a\x20\x52\x6f\x75\x74\x65\x72\x20\x43\x61\x70\x61\x62\x69\x6c\x69\x74\x79\x20\x73\x75\x62\x54\x4c\x56\x20\x6c\x65\x6e\x67\x74\x68\x20\x74\x6f\x6f\x20\x6c\x61\x72\x67\x65\x20\x63\x6f\x6d\x70\x61\x72\x65\x64\x20\x74\x6f\x20\x65\x78\x70\x65\x63\x74\x65\x64\x20\x73\x69\x7a\x65\x0a\x55\x6e\x70\x61\x63\x6b\x65\x64\x20\x54\x4c\x56\x73\x3a\x0a\x50\x72\x6f\x74\x6f\x63\x6f\x6c\x73\x20\x53\x75\x70\x70\x6f\x72\x74\x65\x64\x3a\x20\x37\x33\x2c\x20\x31\x36\x2c\x20\x32\x35\x35\x2c\x20\x32\x35\x35\x2c\x20\x32\x35\x35\x2c\x20\x31\x30\x31\x2c\x20\x31\x30\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x2c\x20\x31\x31\x0a",
+		.output_len = 586,
+		.ret = 0
 	},
 
 	{
