From ed277d56f84fe116ba4e5cc9f7484736c4f8962e Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Fri, 9 Jan 2015 05:30:33 -0800 Subject: [PATCH] better errs, and test parsing --- codec.go | 36 ++++++++++++++++++++++-------- multiaddr_test.go | 57 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 9 deletions(-) diff --git a/codec.go b/codec.go index cc8a2ed..22e65c0 100644 --- a/codec.go +++ b/codec.go @@ -32,7 +32,13 @@ func stringToBytes(s string) ([]byte, error) { sp = sp[1:] if p.Size > 0 { - a := addressStringToBytes(p, sp[0]) + if len(sp) < 1 { + return nil, fmt.Errorf("protocol requires address, none given: %s", sp) + } + a, err := addressStringToBytes(p, sp[0]) + if err != nil { + return nil, fmt.Errorf("failed to parse %s: %s %s", p.Name, sp[0], err) + } b = append(b, a...) sp = sp[1:] } @@ -98,26 +104,38 @@ func bytesSplit(b []byte) (ret [][]byte, err error) { return ret, nil } -func addressStringToBytes(p *Protocol, s string) []byte { +func addressStringToBytes(p *Protocol, s string) ([]byte, error) { switch p.Code { case P_IP4: // ipv4 - return net.ParseIP(s).To4() + i := net.ParseIP(s).To4() + if i == nil { + return nil, fmt.Errorf("failed to parse ip4 addr: %s", s) + } + return i, nil case P_IP6: // ipv6 - return net.ParseIP(s).To16() + i := net.ParseIP(s).To16() + if i == nil { + return nil, fmt.Errorf("failed to parse ip6 addr: %s", s) + } + return i, nil // tcp udp dccp sctp case P_TCP, P_UDP, P_DCCP, P_SCTP: - b := make([]byte, 2) i, err := strconv.Atoi(s) - if err == nil { - binary.BigEndian.PutUint16(b, uint16(i)) + if err != nil { + return nil, fmt.Errorf("failed to parse %s addr: %s", p.Name, err) } - return b + if i >= 65536 { + return nil, fmt.Errorf("failed to parse %s addr: %s", p.Name, "greater than 65536") + } + b := make([]byte, 2) + binary.BigEndian.PutUint16(b, uint16(i)) + return b, nil } - return []byte{} + return []byte{}, fmt.Errorf("failed to parse %s addr: unknown", p.Name) } func addressBytesToString(p *Protocol, b []byte) string { diff --git a/multiaddr_test.go b/multiaddr_test.go index 15e2be0..2c848a2 100644 --- a/multiaddr_test.go +++ b/multiaddr_test.go @@ -14,6 +14,63 @@ func newMultiaddr(t *testing.T, a string) Multiaddr { return m } +func TestConstructFails(t *testing.T) { + cases := []string{ + "/ip4", + "/ip4/::1", + "/ip4/fdpsofodsajfdoisa", + "/ip6", + "/udp", + "/tcp", + "/sctp", + "/udp/65536", + "/tcp/65536", + "/udp/1234/sctp", + "/udp/1234/udt/1234", + "/udp/1234/utp/1234", + "/ip4/127.0.0.1/udp/jfodsajfidosajfoidsa", + "/ip4/127.0.0.1/udp", + "/ip4/127.0.0.1/tcp/jfodsajfidosajfoidsa", + "/ip4/127.0.0.1/tcp", + } + + for _, a := range cases { + if _, err := NewMultiaddr(a); err == nil { + t.Errorf("should have failed: %s", a) + } + } +} + +func TestConstructSucceeds(t *testing.T) { + cases := []string{ + "/ip4/1.2.3.4", + "/ip4/0.0.0.0", + "/ip6/::1", + "/ip6/2601:9:4f81:9700:803e:ca65:66e8:c21", + "/udp/0", + "/tcp/0", + "/sctp/0", + "/udp/1234", + "/tcp/1234", + "/sctp/1234", + "/udp/65535", + "/tcp/65535", + "/udp/1234/sctp/1234", + "/udp/1234/udt", + "/udp/1234/utp", + "/ip4/127.0.0.1/udp/1234", + "/ip4/127.0.0.1/udp/0", + "/ip4/127.0.0.1/tcp/1234", + "/ip4/127.0.0.1/tcp/1234/", + } + + for _, a := range cases { + if _, err := NewMultiaddr(a); err != nil { + t.Errorf("should have succeeded: %s", a) + } + } +} + func TestEqual(t *testing.T) { m1 := newMultiaddr(t, "/ip4/127.0.0.1/udp/1234") m2 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234")