diff --git a/src/libknot/dname.c b/src/libknot/dname.c index cd434a4f27441172ee83281d346509fde76a214a..a075397ff046f5812d6d3f2c90d8c1292b2953e1 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 18c5376f39b3c7324e67036f78092a048504856b..45bfb0755133f3fc26d9138633ba8687c1078a9a 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(); }