mirror of
https://github.com/systemd/systemd.git
synced 2025-02-04 21:47:31 +03:00
Merge pull request #34405 from poettering/dns-domain-validate-fix
dns-domain: fix validation check for max name
This commit is contained in:
commit
d97c672be0
@ -395,9 +395,9 @@ int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded,
|
||||
}
|
||||
#endif
|
||||
|
||||
int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **_ret) {
|
||||
_cleanup_free_ char *ret = NULL;
|
||||
size_t n = 0;
|
||||
int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **ret) {
|
||||
_cleanup_free_ char *result = NULL;
|
||||
size_t n_result = 0, n_unescaped = 0;
|
||||
const char *p;
|
||||
bool first = true;
|
||||
int r;
|
||||
@ -427,17 +427,18 @@ int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **_r
|
||||
|
||||
break;
|
||||
}
|
||||
n_unescaped += r + !first; /* Count unescaped length to make max length determination below */
|
||||
|
||||
if (_ret) {
|
||||
if (!GREEDY_REALLOC(ret, n + !first + DNS_LABEL_ESCAPED_MAX))
|
||||
if (ret) {
|
||||
if (!GREEDY_REALLOC(result, n_result + !first + DNS_LABEL_ESCAPED_MAX))
|
||||
return -ENOMEM;
|
||||
|
||||
r = dns_label_escape(label, r, ret + n + !first, DNS_LABEL_ESCAPED_MAX);
|
||||
r = dns_label_escape(label, r, result + n_result + !first, DNS_LABEL_ESCAPED_MAX);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!first)
|
||||
ret[n] = '.';
|
||||
result[n_result] = '.';
|
||||
} else {
|
||||
char escaped[DNS_LABEL_ESCAPED_MAX];
|
||||
|
||||
@ -446,28 +447,34 @@ int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **_r
|
||||
return r;
|
||||
}
|
||||
|
||||
n += r + !first;
|
||||
n_result += r + !first;
|
||||
first = false;
|
||||
}
|
||||
|
||||
finish:
|
||||
if (n > DNS_HOSTNAME_MAX)
|
||||
return -EINVAL;
|
||||
if (n_unescaped == 0) {
|
||||
/* Nothing appended? If so, generate at least a single dot, to indicate the DNS root domain */
|
||||
|
||||
if (_ret) {
|
||||
if (n == 0) {
|
||||
/* Nothing appended? If so, generate at least a single dot, to indicate the DNS root domain */
|
||||
if (!GREEDY_REALLOC(ret, 2))
|
||||
if (ret) {
|
||||
if (!GREEDY_REALLOC(result, 2)) /* Room for dot, and already pre-allocate space for the trailing NUL byte at the same time */
|
||||
return -ENOMEM;
|
||||
|
||||
ret[n++] = '.';
|
||||
} else {
|
||||
if (!GREEDY_REALLOC(ret, n + 1))
|
||||
return -ENOMEM;
|
||||
result[n_result++] = '.';
|
||||
}
|
||||
|
||||
ret[n] = 0;
|
||||
*_ret = TAKE_PTR(ret);
|
||||
n_unescaped++;
|
||||
}
|
||||
|
||||
if (n_unescaped > DNS_HOSTNAME_MAX) /* Enforce max length check on unescaped length */
|
||||
return -EINVAL;
|
||||
|
||||
if (ret) {
|
||||
/* Suffix with a NUL byte */
|
||||
if (!GREEDY_REALLOC(result, n_result + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
result[n_result] = 0;
|
||||
*ret = TAKE_PTR(result);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -375,6 +375,9 @@ static void test_dns_name_is_valid_one(const char *s, int ret, int ret_ldh) {
|
||||
}
|
||||
|
||||
TEST(dns_name_is_valid) {
|
||||
test_dns_name_is_valid_one("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[._qotd._tcp.local", 1, 0);
|
||||
test_dns_name_is_valid_one("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]._qotd._tcp.local", 0, 0);
|
||||
|
||||
test_dns_name_is_valid_one("foo", 1, 1);
|
||||
test_dns_name_is_valid_one("foo.", 1, 1);
|
||||
test_dns_name_is_valid_one("foo..", 0, 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user