[geary/wip/728002-webkit2] Add Geary.Inet::is_valid_display_host and tests.



commit b0f856df4eb0382ab2526d9506d1fb6082cadc24
Author: Michael James Gratton <mike vee net>
Date:   Thu Jan 19 01:23:33 2017 +1100

    Add Geary.Inet::is_valid_display_host and tests.

 src/engine/util/util-inet.vala  |   54 ++++++++++++++++++++++++++++++++++
 test/CMakeLists.txt             |    1 +
 test/engine/util-inet-test.vala |   61 +++++++++++++++++++++++++++++++++++++++
 test/main.vala                  |    1 +
 4 files changed, 117 insertions(+), 0 deletions(-)
---
diff --git a/src/engine/util/util-inet.vala b/src/engine/util/util-inet.vala
index a8437f4..c3d776f 100644
--- a/src/engine/util/util-inet.vala
+++ b/src/engine/util/util-inet.vala
@@ -6,9 +6,63 @@
 
 namespace Geary.Inet {
 
+private const string HOST_PART_REGEX = """^(?!-)[\p{L}\p{N}-]{1,63}(?<!-)$""";
+private const string IPv6_REGEX = 
"""^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\
 
d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$""";
+
+/**
+ * Formats a socket address as a "name:port" string.
+ */
 public string address_to_string(InetSocketAddress addr) {
     return "%s:%u".printf(addr.address.to_string(), addr.port);
 }
 
+/**
+ * Determines if a string represents a valid host name or IP address.
+ *
+ * This function validates a host name or IP address for display,
+ * i.e. without IDN or URI encoding. It simply performs a syntactic
+ * check, it does not attempt to resolve the host name. Note that both
+ * valid IPv4 addresses (such as "123.0.10.100") and invalid IPv4
+ * addresses (such as "123" or "555.123.456.789") are valid host
+ * names, so it is not possible to determine if an IPv4 address is
+ * invalid.
+ */
+public bool is_valid_display_host(owned string? name) {
+    bool is_valid = false;
+    if (!Geary.String.is_empty(name)) {
+        // Check for a valid host name validation here is a modified version of:
+        // http://stackoverflow.com/questions/2532053/validate-a-hostname-string
+        if (name.length <= 253) {
+            if (name[name.length - 1] == '.')
+                name = name[0:-1];
+            try {
+                Regex part_regex = new Regex(HOST_PART_REGEX);
+                is_valid = true;
+                foreach (string part in name.split(".")) {
+                    if (!part_regex.match(part)) {
+                        is_valid = false;
+                        break;
+                    }
+                }
+            } catch (Error err) {
+                debug("Error validating as host name: %s", err.message);
+            }
+        }
+
+        // Check for a IPv6 address
+        if (!is_valid) {
+            try {
+                Regex address_regex = new Regex(
+                    IPv6_REGEX, RegexCompileFlags.CASELESS
+                );
+                is_valid = address_regex.match(name);
+            } catch (Error err) {
+                debug("Error validating as IPv6 address: %s", err.message);
+            }
+        }
+    }
+    return is_valid;
+}
+
 }
 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 92af56e..363fa52 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -11,6 +11,7 @@ set(TEST_SRC
   engine/rfc822-message-data-test.vala
   engine/rfc822-utils-test.vala
   engine/util-html-test.vala
+  engine/util-inet-test.vala
   engine/util-timeout-manager-test.vala
 
   client/application/geary-configuration-test.vala
diff --git a/test/engine/util-inet-test.vala b/test/engine/util-inet-test.vala
new file mode 100644
index 0000000..cae052d
--- /dev/null
+++ b/test/engine/util-inet-test.vala
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2017 Michael Gratton <mike vee net>
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+class Geary.Inet.Test : Gee.TestCase {
+
+    public Test() {
+        base("Geary.Inet.Test");
+        add_test("is_valid_display_host_dns", is_valid_display_host_dns);
+        add_test("is_valid_display_host_ipv4", is_valid_display_host_ipv4);
+        add_test("is_valid_display_host_ipv6", is_valid_display_host_ipv6);
+    }
+
+    public void is_valid_display_host_dns() {
+        assert(is_valid_display_host("foo"));
+        assert(is_valid_display_host("Foo"));
+        assert(is_valid_display_host("Ƒoo"));
+        assert(is_valid_display_host("2oo"));
+        assert(is_valid_display_host("foo."));
+        assert(is_valid_display_host("foo.bar"));
+        assert(is_valid_display_host("foo.bar."));
+        assert(is_valid_display_host("foo-bar"));
+
+        assert(!is_valid_display_host(""));
+        assert(!is_valid_display_host(" "));
+        assert(!is_valid_display_host(" foo"));
+        assert(!is_valid_display_host(" foo "));
+        assert(!is_valid_display_host("foo bar"));
+        assert(!is_valid_display_host("-foo"));
+        assert(!is_valid_display_host("foo-"));
+    }
+
+    public void is_valid_display_host_ipv4() {
+        assert(is_valid_display_host("123.123.123.123"));
+        assert(is_valid_display_host("127.0.0.1"));
+
+        // These are valid host names
+        //assert(!is_valid_display_host("123"));
+        //assert(!is_valid_display_host("123.123"));
+        //assert(!is_valid_display_host("123.123.123"));
+        //assert(is_valid_display_host("666.123.123.123"));
+    }
+
+    public void is_valid_display_host_ipv6() {
+        assert(is_valid_display_host("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210"));
+        assert(is_valid_display_host("1080:0:0:0:8:800:200C:4171"));
+        assert(is_valid_display_host("3ffe:2a00:100:7031::1"));
+        assert(is_valid_display_host("1080::8:800:200C:417A"));
+        assert(is_valid_display_host("::1"));
+        assert(is_valid_display_host("::192.9.5.5"));
+        assert(is_valid_display_host("::FFFF:129.144.52.38"));
+        assert(is_valid_display_host("2010:836B:4179::836B:4179"));
+
+        assert(!is_valid_display_host("1200::AB00:1234::2552:7777:1313"));
+        assert(!is_valid_display_host("1200:0000:AB00:1234:O000:2552:7777:1313"));
+    }
+
+}
diff --git a/test/main.vala b/test/main.vala
index 7fb7842..fe7f6e5 100644
--- a/test/main.vala
+++ b/test/main.vala
@@ -38,6 +38,7 @@ int main(string[] args) {
     TestSuite engine = new TestSuite("engine");
 
     engine.add_suite(new Geary.HTML.UtilTest().get_suite());
+    engine.add_suite(new Geary.Inet.Test().get_suite());
     engine.add_suite(new Geary.RFC822.MailboxAddressTest().get_suite());
     engine.add_suite(new Geary.RFC822.MessageTest().get_suite());
     engine.add_suite(new Geary.RFC822.MessageDataTest().get_suite());


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]