diff --git a/src/lib/ares_search.c b/src/lib/ares_search.c index d9e65910..402b52d6 100644 --- a/src/lib/ares_search.c +++ b/src/lib/ares_search.c @@ -223,6 +223,11 @@ int ares__cat_domain(const char *name, const char *domain, char **s) return ARES_ENOMEM; memcpy(*s, name, nlen); (*s)[nlen] = '.'; + if (strcmp(domain, ".") == 0) { + /* Avoid appending the root domain to the separator, which would set *s to + an ill-formed value (ending in two consequtive dots). */ + dlen = 0; + } memcpy(*s + nlen + 1, domain, dlen); (*s)[nlen + 1 + dlen] = 0; return ARES_SUCCESS; diff --git a/test/ares-test-internal.cc b/test/ares-test-internal.cc index 9bc32d68..bf50d3ab 100644 --- a/test/ares-test-internal.cc +++ b/test/ares-test-internal.cc @@ -525,6 +525,22 @@ TEST(Misc, OnionDomain) { EXPECT_EQ(1, ares__is_onion_domain("YES.ONION")); EXPECT_EQ(1, ares__is_onion_domain("YES.ONION.")); } + +TEST_F(LibraryTest, CatDomain) { + char *s; + + ares__cat_domain("foo", "example.net", &s); + EXPECT_STREQ("foo.example.net", s); + ares_free(s); + + ares__cat_domain("foo", ".", &s); + EXPECT_STREQ("foo.", s); + ares_free(s); + + ares__cat_domain("foo", "example.net.", &s); + EXPECT_STREQ("foo.example.net.", s); + ares_free(s); +} #endif #ifdef CARES_EXPOSE_STATICS