From 25bc41253036f579c24f41c38d5d006125c8ef53 Mon Sep 17 00:00:00 2001
From: Marek Vavrusa <marek.vavrusa@nic.cz>
Date: Mon, 17 Jun 2013 12:44:11 +0200
Subject: [PATCH] Fixed dname concatenation and added unit tests.

When concatenating FQDNs, the first name \0 label must be cut.
---
 src/libknot/dname.c             |  8 +++++---
 src/tests/libknot/dname_tests.c | 18 ++++++++++++++++--
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/src/libknot/dname.c b/src/libknot/dname.c
index cd434a4f27..a075397ff0 100644
--- a/src/libknot/dname.c
+++ b/src/libknot/dname.c
@@ -714,7 +714,8 @@ knot_dname_t *knot_dname_cat(knot_dname_t *d1, const knot_dname_t *d2)
 	}
 
 	// allocate new space
-	uint8_t *new_dname = (uint8_t *)malloc(d1->size + d2->size);
+	size_t new_size = d1->size + d2->size - 1; /* Trim the d1 \0 label */
+	uint8_t *new_dname = (uint8_t *)malloc(new_size);
 	CHECK_ALLOC_LOG(new_dname, NULL);
 
 	dbg_dname_detail("1: copying %d bytes from adress %p to %p\n",
@@ -725,13 +726,14 @@ knot_dname_t *knot_dname_cat(knot_dname_t *d1, const knot_dname_t *d2)
 	dbg_dname_detail("2: copying %d bytes from adress %p to %p\n",
 	                 d2->size, d2->name, new_dname + d1->size);
 
-	memcpy(new_dname + d1->size, d2->name, d2->size);
+	/* Overwrite the d1 \0 label. */
+	memcpy(new_dname + d1->size - 1, d2->name, d2->size);
 
 	uint8_t *old_name = d1->name;
 	d1->name = new_dname;
 	free(old_name);
 
-	d1->size += d2->size;
+	d1->size = new_size;
 
 	return d1;
 }
diff --git a/src/tests/libknot/dname_tests.c b/src/tests/libknot/dname_tests.c
index 18c5376f39..45bfb07551 100644
--- a/src/tests/libknot/dname_tests.c
+++ b/src/tests/libknot/dname_tests.c
@@ -35,7 +35,7 @@ unit_api dname_tests_api = {
 
 static int dname_tests_count(int argc, char *argv[])
 {
-	return 15;
+	return 17;
 }
 
 static int dname_tests_run(int argc, char *argv[])
@@ -120,5 +120,19 @@ static int dname_tests_run(int argc, char *argv[])
 	knot_dname_free(&d);
 	knot_dname_free(&d2);
 
-	return 0;
+	/* 16-17. dname cat (valid) */
+	w = "\x03""cat";
+	len = 5;
+	d = knot_dname_new_from_wire((const uint8_t *)w, len, NULL);
+	t = "*";
+	d2 = knot_dname_new_from_str(t, strlen(t), NULL);
+	d2 = knot_dname_cat(d2, d);
+	t = "\x01""*""\x03""cat";
+	len = 2 + 4 + 1;
+	ok (d2 && len == d2->size, "dname_cat: valid concatenation size");
+	ok(memcmp(d2->name, t, len) == 0, "dname_cat: valid concatenation");
+	knot_dname_free(&d);
+	knot_dname_free(&d2);
+
+	done_testing();
 }
-- 
GitLab