mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-12 09:17:44 +03:00
shared: add new dns_name_startswith() call
dns_name_startswith() is to dns_name_endswith() as startswith() is to endswith().
This commit is contained in:
parent
522d85ae0a
commit
eb241cdbee
@ -263,7 +263,6 @@ int dns_label_escape(const char *p, size_t l, char *dest, size_t sz) {
|
|||||||
*(q++) = '0' + (char) ((uint8_t) *p % 10);
|
*(q++) = '0' + (char) ((uint8_t) *p % 10);
|
||||||
|
|
||||||
sz -= 4;
|
sz -= 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
@ -653,6 +652,54 @@ int dns_name_endswith(const char *name, const char *suffix) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dns_label_unescape_undo_idna(const char **name, char *dest, size_t sz) {
|
||||||
|
int r, k;
|
||||||
|
|
||||||
|
/* Clobbers all arguments on failure... */
|
||||||
|
|
||||||
|
r = dns_label_unescape(name, dest, sz);
|
||||||
|
if (r <= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
k = dns_label_undo_idna(dest, r, dest, sz);
|
||||||
|
if (k < 0)
|
||||||
|
return k;
|
||||||
|
if (k == 0) /* not an IDNA name */
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dns_name_startswith(const char *name, const char *prefix) {
|
||||||
|
const char *n, *p;
|
||||||
|
int r, q;
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
assert(prefix);
|
||||||
|
|
||||||
|
n = name;
|
||||||
|
p = prefix;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
char ln[DNS_LABEL_MAX], lp[DNS_LABEL_MAX];
|
||||||
|
|
||||||
|
r = dns_label_unescape_undo_idna(&p, lp, sizeof(lp));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (r == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
q = dns_label_unescape_undo_idna(&n, ln, sizeof(ln));
|
||||||
|
if (q < 0)
|
||||||
|
return q;
|
||||||
|
|
||||||
|
if (r != q)
|
||||||
|
return false;
|
||||||
|
if (ascii_strcasecmp_n(ln, lp, r) != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret) {
|
int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret) {
|
||||||
const char *n, *s, *saved_before = NULL, *saved_after = NULL, *prefix;
|
const char *n, *s, *saved_before = NULL, *saved_after = NULL, *prefix;
|
||||||
int r, q, k, w;
|
int r, q, k, w;
|
||||||
|
@ -83,6 +83,7 @@ extern const struct hash_ops dns_name_hash_ops;
|
|||||||
int dns_name_between(const char *a, const char *b, const char *c);
|
int dns_name_between(const char *a, const char *b, const char *c);
|
||||||
int dns_name_equal(const char *x, const char *y);
|
int dns_name_equal(const char *x, const char *y);
|
||||||
int dns_name_endswith(const char *name, const char *suffix);
|
int dns_name_endswith(const char *name, const char *suffix);
|
||||||
|
int dns_name_startswith(const char *name, const char *prefix);
|
||||||
|
|
||||||
int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret);
|
int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret);
|
||||||
|
|
||||||
|
@ -276,6 +276,25 @@ static void test_dns_name_endswith(void) {
|
|||||||
test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL);
|
test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_dns_name_startswith_one(const char *a, const char *b, int ret) {
|
||||||
|
assert_se(dns_name_startswith(a, b) == ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_dns_name_startswith(void) {
|
||||||
|
test_dns_name_startswith_one("", "", true);
|
||||||
|
test_dns_name_startswith_one("", "xxx", false);
|
||||||
|
test_dns_name_startswith_one("xxx", "", true);
|
||||||
|
test_dns_name_startswith_one("x", "x", true);
|
||||||
|
test_dns_name_startswith_one("x", "y", false);
|
||||||
|
test_dns_name_startswith_one("x.y", "x.y", true);
|
||||||
|
test_dns_name_startswith_one("x.y", "y.x", false);
|
||||||
|
test_dns_name_startswith_one("x.y", "x", true);
|
||||||
|
test_dns_name_startswith_one("x.y", "X", true);
|
||||||
|
test_dns_name_startswith_one("x.y", "y", false);
|
||||||
|
test_dns_name_startswith_one("x.y", "", true);
|
||||||
|
test_dns_name_startswith_one("x.y", "X", true);
|
||||||
|
}
|
||||||
|
|
||||||
static void test_dns_name_is_root(void) {
|
static void test_dns_name_is_root(void) {
|
||||||
assert_se(dns_name_is_root(""));
|
assert_se(dns_name_is_root(""));
|
||||||
assert_se(dns_name_is_root("."));
|
assert_se(dns_name_is_root("."));
|
||||||
@ -567,6 +586,7 @@ int main(int argc, char *argv[]) {
|
|||||||
test_dns_name_normalize();
|
test_dns_name_normalize();
|
||||||
test_dns_name_equal();
|
test_dns_name_equal();
|
||||||
test_dns_name_endswith();
|
test_dns_name_endswith();
|
||||||
|
test_dns_name_startswith();
|
||||||
test_dns_name_between();
|
test_dns_name_between();
|
||||||
test_dns_name_is_root();
|
test_dns_name_is_root();
|
||||||
test_dns_name_is_single_label();
|
test_dns_name_is_single_label();
|
||||||
|
Loading…
Reference in New Issue
Block a user