mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-07 17:17:44 +03:00
resolved: fix "in-between" logic when boundaries are equal (#7590)
This changes dns_name_between() to deal properly with checking whether B is between A and C if A and C are equal. Previously we simply returned -EINVAL in this case, refusing checking. With this change we correct behaviour: if A and C are equal, then B is "between" both if it is different from them. That's logical, since we do < and > comparisons, not <= and >=, and that means that anything "right of A" and "left of C" lies in between with wrap-around at the ends. And if A and C are equal that means everything lies between, except for A itself. This fixes handling of domains using NSEC3 "white lies", for example the .it TLD. Fixes: #7421
This commit is contained in:
parent
1bb8d1fce8
commit
59f2725cc8
@ -693,23 +693,26 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
|
||||
}
|
||||
|
||||
int dns_name_between(const char *a, const char *b, const char *c) {
|
||||
int n;
|
||||
|
||||
/* Determine if b is strictly greater than a and strictly smaller than c.
|
||||
We consider the order of names to be circular, so that if a is
|
||||
strictly greater than c, we consider b to be between them if it is
|
||||
either greater than a or smaller than c. This is how the canonical
|
||||
DNS name order used in NSEC records work. */
|
||||
|
||||
n = dns_name_compare_func(a, c);
|
||||
if (n == 0)
|
||||
return -EINVAL;
|
||||
else if (n < 0)
|
||||
/* a<---b--->c */
|
||||
if (dns_name_compare_func(a, c) < 0)
|
||||
/*
|
||||
a and c are properly ordered:
|
||||
a<---b--->c
|
||||
*/
|
||||
return dns_name_compare_func(a, b) < 0 &&
|
||||
dns_name_compare_func(b, c) < 0;
|
||||
else
|
||||
/* <--b--c a--b--> */
|
||||
/*
|
||||
a and c are equal or 'reversed':
|
||||
<--b--c a----->
|
||||
or:
|
||||
<-----c a--b-->
|
||||
*/
|
||||
return dns_name_compare_func(b, c) < 0 ||
|
||||
dns_name_compare_func(a, b) < 0;
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ static void test_dns_name_between_one(const char *a, const char *b, const char *
|
||||
|
||||
r = dns_name_between(c, b, a);
|
||||
if (ret >= 0)
|
||||
assert_se(r == 0);
|
||||
assert_se(r == 0 || dns_name_equal(a, c) > 0);
|
||||
else
|
||||
assert_se(r == ret);
|
||||
}
|
||||
@ -249,7 +249,8 @@ static void test_dns_name_between(void) {
|
||||
test_dns_name_between_one("*.z.example", "\\200.z.example", "example", true);
|
||||
test_dns_name_between_one("\\200.z.example", "example", "a.example", true);
|
||||
|
||||
test_dns_name_between_one("example", "a.example", "example", -EINVAL);
|
||||
test_dns_name_between_one("example", "a.example", "example", true);
|
||||
test_dns_name_between_one("example", "example", "example", false);
|
||||
test_dns_name_between_one("example", "example", "yljkjljk.a.example", false);
|
||||
test_dns_name_between_one("example", "yljkjljk.a.example", "yljkjljk.a.example", false);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user