コード例 #1
0
ファイル: util.cpp プロジェクト: Tmplt/libircppclient
/*
 * Validates the syntax of hostnames, ipv4-, and ipv6-addresses.
 * Returns an empty string on success, non-empty on failure.
 *
 * TODO: Implement support for internationalized domain names.
 */
const std::string util::valid_addr(const std::experimental::string_view &addr)
{
    if (!valid_ipv46_addr(addr)) {

        if (string_contains(addr, ipv6_sep))
            return "invalid ipv6 address.";

        if (addr.length() > addr_max_length)
            return "the address is too long; it's illegal to exceed 255 characters.";

        /*
         * Split the hostname into its multiple sub-domains
         * (seperated by periods) and check them.
         */
        std::vector<std::string> tokens = split_string(addr, period);

        for (const std::experimental::string_view &s: tokens) {

            /*
             * In case of "irc..hostname.tld", where the token between '..',
             * would be empty.
             */
            if (s.empty())
                return "a token is empty; does the address contain \"..\" somewhere?";

            /* Also as per RFC 1035. */
            if (s.front() == hyphen || s.back() ==  hyphen) {
                std::string element = s.data();
                return "first or last character in the element \"" +
                       element + "\" is a hyphen; that's not allowed.";
            }

            /*
             * O̶n̶l̶y̶ ̶[̶A̶-̶Z̶a̶-̶z̶0̶-̶9̶]̶ ̶a̶r̶e̶ ̶a̶l̶l̶o̶w̶e̶d̶.̶
             * Okey, no. International domain names is a thing:
             * <https://en.wikipedia.org/wiki/Domain_name>
             *
             * s[first] and s[last] are checked again, but they
             * must be checked for non-[A-Za-z0-9], anyway. A check for
             * periods could be implemented here, but then we'd lose a specified
             * error message and we'd need more checks than what we remove.
             */
            if (std::find_if(s.begin(), s.end(),
                [](char c) {
                    return !std::isdigit(c) &&
                           !std::isalpha(c) &&
                           c != hyphen;     }) != s.end()) {

                std::string element = s.data();
                return "the element \"" + element +
                       "\" contains an illegal character (not a [A-Za-z0-9\\-]).";
            }
        }
    }

    return "";
}