1
0
mirror of https://github.com/golang/go synced 2024-10-01 20:28:33 -06:00

net: make SplitHostPort return an empty host on error

This change also refactors SplitHostPort to avoid using gotos and
naked returns.

Fixes #14827

Change-Id: I4dca528936757fd06da76c23af8a0f6175bbedd1
Reviewed-on: https://go-review.googlesource.com/20726
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Dave Day 2016-03-16 10:24:03 +11:00
parent 8edb72587f
commit 5630cb7518
2 changed files with 21 additions and 26 deletions

View File

@ -421,13 +421,16 @@ func TestSplitHostPort(t *testing.T) {
} }
} }
for _, tt := range splitFailureTests { for _, tt := range splitFailureTests {
if _, _, err := SplitHostPort(tt.hostPort); err == nil { if host, port, err := SplitHostPort(tt.hostPort); err == nil {
t.Errorf("SplitHostPort(%q) should have failed", tt.hostPort) t.Errorf("SplitHostPort(%q) should have failed", tt.hostPort)
} else { } else {
e := err.(*AddrError) e := err.(*AddrError)
if e.Err != tt.err { if e.Err != tt.err {
t.Errorf("SplitHostPort(%q) = _, _, %q; want %q", tt.hostPort, e.Err, tt.err) t.Errorf("SplitHostPort(%q) = _, _, %q; want %q", tt.hostPort, e.Err, tt.err)
} }
if host != "" || port != "" {
t.Errorf("SplitHostPort(%q) = %q, %q, err; want %q, %q, err on failure", tt.hostPort, host, port, "", "")
}
} }
} }
} }

View File

@ -110,69 +110,61 @@ func ipv6only(addr IPAddr) bool {
// must be enclosed in square brackets, as in "[::1]:80", // must be enclosed in square brackets, as in "[::1]:80",
// "[ipv6-host]:http" or "[ipv6-host%zone]:80". // "[ipv6-host]:http" or "[ipv6-host%zone]:80".
func SplitHostPort(hostport string) (host, port string, err error) { func SplitHostPort(hostport string) (host, port string, err error) {
const (
missingPort = "missing port in address"
tooManyColons = "too many colons in address"
)
addrErr := func(addr, why string) (host, port string, err error) {
return "", "", &AddrError{Err: why, Addr: addr}
}
j, k := 0, 0 j, k := 0, 0
// The port starts after the last colon. // The port starts after the last colon.
i := last(hostport, ':') i := last(hostport, ':')
if i < 0 { if i < 0 {
goto missingPort return addrErr(hostport, missingPort)
} }
if hostport[0] == '[' { if hostport[0] == '[' {
// Expect the first ']' just before the last ':'. // Expect the first ']' just before the last ':'.
end := byteIndex(hostport, ']') end := byteIndex(hostport, ']')
if end < 0 { if end < 0 {
err = &AddrError{Err: "missing ']' in address", Addr: hostport} return addrErr(hostport, "missing ']' in address")
return
} }
switch end + 1 { switch end + 1 {
case len(hostport): case len(hostport):
// There can't be a ':' behind the ']' now. // There can't be a ':' behind the ']' now.
goto missingPort return addrErr(hostport, missingPort)
case i: case i:
// The expected result. // The expected result.
default: default:
// Either ']' isn't followed by a colon, or it is // Either ']' isn't followed by a colon, or it is
// followed by a colon that is not the last one. // followed by a colon that is not the last one.
if hostport[end+1] == ':' { if hostport[end+1] == ':' {
goto tooManyColons return addrErr(hostport, tooManyColons)
} }
goto missingPort return addrErr(hostport, missingPort)
} }
host = hostport[1:end] host = hostport[1:end]
j, k = 1, end+1 // there can't be a '[' resp. ']' before these positions j, k = 1, end+1 // there can't be a '[' resp. ']' before these positions
} else { } else {
host = hostport[:i] host = hostport[:i]
if byteIndex(host, ':') >= 0 { if byteIndex(host, ':') >= 0 {
goto tooManyColons return addrErr(hostport, tooManyColons)
} }
if byteIndex(host, '%') >= 0 { if byteIndex(host, '%') >= 0 {
goto missingBrackets return addrErr(hostport, "missing brackets in address")
} }
} }
if byteIndex(hostport[j:], '[') >= 0 { if byteIndex(hostport[j:], '[') >= 0 {
err = &AddrError{Err: "unexpected '[' in address", Addr: hostport} return addrErr(hostport, "unexpected '[' in address")
return
} }
if byteIndex(hostport[k:], ']') >= 0 { if byteIndex(hostport[k:], ']') >= 0 {
err = &AddrError{Err: "unexpected ']' in address", Addr: hostport} return addrErr(hostport, "unexpected ']' in address")
return
} }
port = hostport[i+1:] port = hostport[i+1:]
return return host, port, nil
missingPort:
err = &AddrError{Err: "missing port in address", Addr: hostport}
return
tooManyColons:
err = &AddrError{Err: "too many colons in address", Addr: hostport}
return
missingBrackets:
err = &AddrError{Err: "missing brackets in address", Addr: hostport}
return
} }
func splitHostZone(s string) (host, zone string) { func splitHostZone(s string) (host, zone string) {