int dns_name_normalize(const char *s, char **_ret) {
        _cleanup_free_ char *ret = NULL;
        size_t n = 0, allocated = 0;
        const char *p = s;
        bool first = true;
        int r;

        assert(s);

        for (;;) {
                _cleanup_free_ char *t = NULL;
                char label[DNS_LABEL_MAX];
                int k;

                r = dns_label_unescape(&p, label, sizeof(label));
                if (r < 0)
                        return r;
                if (r == 0) {
                        if (*p != 0)
                                return -EINVAL;
                        break;
                }

                k = dns_label_undo_idna(label, r, label, sizeof(label));
                if (k < 0)
                        return k;
                if (k > 0)
                        r = k;

                r = dns_label_escape(label, r, &t);
                if (r < 0)
                        return r;

                if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1))
                        return -ENOMEM;

                if (!first)
                        ret[n++] = '.';
                else
                        first = false;

                memcpy(ret + n, t, r);
                n += r;
        }

        if (n > DNS_NAME_MAX)
                return -EINVAL;

        if (!GREEDY_REALLOC(ret, allocated, n + 1))
                return -ENOMEM;

        ret[n] = 0;

        if (_ret) {
                *_ret = ret;
                ret = NULL;
        }

        return 0;
}
Beispiel #2
0
static void test_dns_label_escape_one(const char *what, size_t l, const char *expect, int ret) {
        _cleanup_free_ char *t = NULL;
        int r;

        r = dns_label_escape(what, l, &t);
        assert_se(r == ret);

        if (r < 0)
                return;

        assert_se(streq_ptr(expect, t));
}