net: don't return non-nil interface values as Source, Addr in OpError

Fixes #10992.

Change-Id: Ia376e4de118993b43e5813da57ab25fea8122048
Reviewed-on: https://go-review.googlesource.com/10476
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Mikio Hara 2015-05-30 07:33:16 +09:00
parent 38e3427b2f
commit 22829bd766
14 changed files with 208 additions and 76 deletions

View file

@ -23,12 +23,38 @@ func (e *OpError) isValid() error {
return fmt.Errorf("OpError.Net is empty: %v", e)
}
for _, addr := range []Addr{e.Source, e.Addr} {
if addr != nil {
switch addr.(type) {
case *TCPAddr, *UDPAddr, *IPAddr, *IPNet, *UnixAddr, *pipeAddr, fileAddr:
default:
return fmt.Errorf("OpError.Source or Addr is unknown type: %T, %v", addr, e)
switch addr := addr.(type) {
case nil:
case *TCPAddr:
if addr == nil {
return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
}
case *UDPAddr:
if addr == nil {
return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
}
case *IPAddr:
if addr == nil {
return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
}
case *IPNet:
if addr == nil {
return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
}
case *UnixAddr:
if addr == nil {
return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
}
case *pipeAddr:
if addr == nil {
return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
}
case fileAddr:
if addr == "" {
return fmt.Errorf("OpError.Source or Addr is empty: %#v, %v", addr, e)
}
default:
return fmt.Errorf("OpError.Source or Addr is unknown type: %T, %v", addr, e)
}
}
if e.Err == nil {
@ -133,6 +159,35 @@ func TestDialError(t *testing.T) {
}
}
func TestProtocolDialError(t *testing.T) {
switch runtime.GOOS {
case "nacl":
t.Skipf("not supported on %s", runtime.GOOS)
}
for _, network := range []string{"tcp", "udp", "ip:4294967296", "unix", "unixpacket", "unixgram"} {
var err error
switch network {
case "tcp":
_, err = DialTCP(network, nil, &TCPAddr{Port: 1 << 16})
case "udp":
_, err = DialUDP(network, nil, &UDPAddr{Port: 1 << 16})
case "ip:4294967296":
_, err = DialIP(network, nil, nil)
case "unix", "unixpacket", "unixgram":
_, err = DialUnix(network, nil, &UnixAddr{Name: "//"})
}
if err == nil {
t.Errorf("%s: should fail", network)
continue
}
if err = parseDialError(err); err != nil {
t.Errorf("%s: %v", network, err)
continue
}
}
}
var listenErrorTests = []struct {
network, address string
}{
@ -222,6 +277,37 @@ func TestListenPacketError(t *testing.T) {
}
}
func TestProtocolListenError(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9":
t.Skipf("not supported on %s", runtime.GOOS)
}
for _, network := range []string{"tcp", "udp", "ip:4294967296", "unix", "unixpacket", "unixgram"} {
var err error
switch network {
case "tcp":
_, err = ListenTCP(network, &TCPAddr{Port: 1 << 16})
case "udp":
_, err = ListenUDP(network, &UDPAddr{Port: 1 << 16})
case "ip:4294967296":
_, err = ListenIP(network, nil)
case "unix", "unixpacket":
_, err = ListenUnix(network, &UnixAddr{Name: "//"})
case "unixgram":
_, err = ListenUnixgram(network, &UnixAddr{Name: "//"})
}
if err == nil {
t.Errorf("%s: should fail", network)
continue
}
if err = parseDialError(err); err != nil {
t.Errorf("%s: %v", network, err)
continue
}
}
}
// parseReadError parses nestedErr and reports whether it is a valid
// error value from Read functions.
// It returns nil when nestedErr is valid.