]> Cypherpunks repositories - gostls13.git/commitdiff
net: SplitHostPort: adjust error message for missing port in IPv6 addresses
authorMichael Teichgräber <mteichgraeber@gmx.de>
Wed, 30 Jan 2013 17:25:16 +0000 (09:25 -0800)
committerRuss Cox <rsc@golang.org>
Wed, 30 Jan 2013 17:25:16 +0000 (09:25 -0800)
An hostport of "[::1]" now results in the same error message
"missing port in address" as the hostport value "127.0.0.1",
so SplitHostPort won't complain about "too many colons
in address" anymore for an IPv6 address missing a port.

Added tests checking the error values.

Fixes #4526.

R=dave, rsc, mikioh.mikioh
CC=golang-dev
https://golang.org/cl/7038045

src/pkg/net/ip_test.go
src/pkg/net/ipsock.go

index 8324d2a327c1b22c835f4b73953edd142f199a8e..f8b7f067fab2e75a0dbaddeade9497f9f20a84cd 100644 (file)
@@ -269,6 +269,28 @@ var splitjointests = []struct {
        {"127.0.0.1", "1234", "127.0.0.1:1234"},
        {"::1", "80", "[::1]:80"},
        {"google.com", "https%foo", "google.com:https%foo"}, // Go 1.0 behavior
+       {"", "0", ":0"},
+       {"127.0.0.1", "", "127.0.0.1:"},           // Go 1.0 behaviour
+       {"www.google.com", "", "www.google.com:"}, // Go 1.0 behaviour
+}
+
+var splitfailuretests = []struct {
+       HostPort string
+       Err      string
+}{
+       {"www.google.com", "missing port in address"},
+       {"127.0.0.1", "missing port in address"},
+       {"[::1]", "missing port in address"},
+       {"::1", "too many colons in address"},
+
+       // Test cases that didn't fail in Go 1.0
+       {"[foo:bar]", "missing port in address"},
+       {"[foo:bar]baz", "missing port in address"},
+       {"[foo]:[bar]:baz", "too many colons in address"},
+       {"[foo]bar:baz", "missing port in address"},
+       {"[foo]:[bar]baz", "unexpected '[' in address"},
+       {"foo[bar]:baz", "unexpected '[' in address"},
+       {"foo]bar:baz", "unexpected ']' in address"},
 }
 
 func TestSplitHostPort(t *testing.T) {
@@ -277,6 +299,16 @@ func TestSplitHostPort(t *testing.T) {
                        t.Errorf("SplitHostPort(%q) = %q, %q, %v; want %q, %q, nil", tt.Join, host, port, err, tt.Host, tt.Port)
                }
        }
+       for _, tt := range splitfailuretests {
+               if _, _, err := SplitHostPort(tt.HostPort); err == nil {
+                       t.Errorf("SplitHostPort(%q) should have failed", tt.HostPort)
+               } else {
+                       e := err.(*AddrError)
+                       if e.Err != tt.Err {
+                               t.Errorf("SplitHostPort(%q) = _, _, %q; want %q", tt.HostPort, e.Err, tt.Err)
+                       }
+               }
+       }
 }
 
 func TestJoinHostPort(t *testing.T) {
index 5636c85b4ffb91ede85f514e76bee76ecb057a47..1ef4892896627dcc0a0d292bc0a1d42e38c15477 100644 (file)
@@ -77,23 +77,62 @@ func SplitHostPort(hostport string) (host, port string, err error) {
 }
 
 func splitHostPort(hostport string) (host, port, zone string, err error) {
+       j, k := 0, 0
+
        // The port starts after the last colon.
        i := last(hostport, ':')
        if i < 0 {
-               err = &AddrError{"missing port in address", hostport}
-               return
+               goto missingPort
        }
-       host, port = hostport[:i], hostport[i+1:]
-       // Can put brackets around host ...
-       if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
-               host = host[1 : len(host)-1]
+
+       if hostport[0] == '[' {
+               // Expect the first ']' just before the last ':'.
+               end := byteIndex(hostport, ']')
+               if end < 0 {
+                       err = &AddrError{"missing ']' in address", hostport}
+                       return
+               }
+               switch end + 1 {
+               case len(hostport):
+                       // There can't be a ':' behind the ']' now.
+                       goto missingPort
+               case i:
+                       // The expected result.
+               default:
+                       // Either ']' isn't followed by a colon, or it is
+                       // followed by a colon that is not the last one.
+                       if hostport[end+1] == ':' {
+                               goto tooManyColons
+                       }
+                       goto missingPort
+               }
+               host = hostport[1:end]
+               j, k = 1, end+1 // there can't be a '[' resp. ']' before these positions
        } else {
-               // ... but if there are no brackets, no colons.
+               host = hostport[:i]
+
                if byteIndex(host, ':') >= 0 {
-                       err = &AddrError{"too many colons in address", hostport}
-                       return
+                       goto tooManyColons
                }
        }
+       if byteIndex(hostport[j:], '[') >= 0 {
+               err = &AddrError{"unexpected '[' in address", hostport}
+               return
+       }
+       if byteIndex(hostport[k:], ']') >= 0 {
+               err = &AddrError{"unexpected ']' in address", hostport}
+               return
+       }
+
+       port = hostport[i+1:]
+       return
+
+missingPort:
+       err = &AddrError{"missing port in address", hostport}
+       return
+
+tooManyColons:
+       err = &AddrError{"too many colons in address", hostport}
        return
 }