From ac5c928cb926aa3e704a3954e2b9fcd468486bf8 Mon Sep 17 00:00:00 2001 From: Tyler <122291810+0xTylerHolmes@users.noreply.github.com> Date: Wed, 24 Jan 2024 11:26:26 -0500 Subject: [PATCH] fix: correctly parse ports as uint16 and explicitely fail on overflows (#228) --- multiaddr_test.go | 1 + transcoders.go | 35 ++++++++++++++++------------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/multiaddr_test.go b/multiaddr_test.go index 2455a26..25dbf9d 100644 --- a/multiaddr_test.go +++ b/multiaddr_test.go @@ -83,6 +83,7 @@ func TestConstructFails(t *testing.T) { "/ip4/127.0.0.1/p2p/tcp", "/unix", "/ip4/1.2.3.4/tcp/80/unix", + "/ip4/1.2.3.4/tcp/-1", "/ip4/127.0.0.1/tcp/9090/http/p2p-webcrt-direct", "/", "", diff --git a/transcoders.go b/transcoders.go index 5477feb..0030145 100644 --- a/transcoders.go +++ b/transcoders.go @@ -132,13 +132,10 @@ func ip4BtS(b []byte) (string, error) { var TranscoderPort = NewTranscoderFromFunctions(portStB, portBtS, nil) func portStB(s string) ([]byte, error) { - i, err := strconv.Atoi(s) + i, err := strconv.ParseUint(s, 10, 16) if err != nil { return nil, fmt.Errorf("failed to parse port addr: %s", err) } - if i >= 65536 { - return nil, fmt.Errorf("failed to parse port addr: %s", "greater than 65536") - } b := make([]byte, 2) binary.BigEndian.PutUint16(b, uint16(i)) return b, nil @@ -146,7 +143,7 @@ func portStB(s string) ([]byte, error) { func portBtS(b []byte) (string, error) { i := binary.BigEndian.Uint16(b) - return strconv.Itoa(int(i)), nil + return strconv.FormatUint(uint64(i), 10), nil } var TranscoderOnion = NewTranscoderFromFunctions(onionStB, onionBtS, nil) @@ -168,15 +165,12 @@ func onionStB(s string) ([]byte, error) { } // onion port number - i, err := strconv.Atoi(addr[1]) + i, err := strconv.ParseUint(addr[1], 10, 16) if err != nil { return nil, fmt.Errorf("failed to parse onion addr: %s", err) } - if i >= 65536 { - return nil, fmt.Errorf("failed to parse onion addr: %s", "port greater than 65536") - } - if i < 1 { - return nil, fmt.Errorf("failed to parse onion addr: %s", "port less than 1") + if i == 0 { + return nil, fmt.Errorf("failed to parse onion addr: %s", "non-zero port") } onionPortBytes := make([]byte, 2) @@ -190,7 +184,10 @@ func onionStB(s string) ([]byte, error) { func onionBtS(b []byte) (string, error) { addr := strings.ToLower(base32.StdEncoding.EncodeToString(b[0:10])) port := binary.BigEndian.Uint16(b[10:12]) - return addr + ":" + strconv.Itoa(int(port)), nil + if port == 0 { + return "", fmt.Errorf("failed to parse onion addr: %s", "non-zero port") + } + return addr + ":" + strconv.FormatUint(uint64(port), 10), nil } var TranscoderOnion3 = NewTranscoderFromFunctions(onion3StB, onion3BtS, nil) @@ -211,15 +208,12 @@ func onion3StB(s string) ([]byte, error) { } // onion port number - i, err := strconv.Atoi(addr[1]) + i, err := strconv.ParseUint(addr[1], 10, 16) if err != nil { return nil, fmt.Errorf("failed to parse onion addr: %s", err) } - if i >= 65536 { - return nil, fmt.Errorf("failed to parse onion addr: %s", "port greater than 65536") - } - if i < 1 { - return nil, fmt.Errorf("failed to parse onion addr: %s", "port less than 1") + if i == 0 { + return nil, fmt.Errorf("failed to parse onion addr: %s", "non-zero port") } onionPortBytes := make([]byte, 2) @@ -233,7 +227,10 @@ func onion3StB(s string) ([]byte, error) { func onion3BtS(b []byte) (string, error) { addr := strings.ToLower(base32.StdEncoding.EncodeToString(b[0:35])) port := binary.BigEndian.Uint16(b[35:37]) - str := addr + ":" + strconv.Itoa(int(port)) + if port < 1 { + return "", fmt.Errorf("failed to parse onion addr: %s", "port less than 1") + } + str := addr + ":" + strconv.FormatUint(uint64(port), 10) return str, nil }