Skip to content

Commit dcfbb04

Browse files
committed
nat: ParsePortRange, ParsePortRangeToInt: reimplement with parsePortNumber
- Split the implementations from the exported ParsePortRange function. - The implementation returns an int for ports (instead of an uint64), which we cast to the right type in ParsePortRange. - The parsePortNumber gives more informative errors. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent 0c490f1 commit dcfbb04

3 files changed

Lines changed: 34 additions & 31 deletions

File tree

nat/nat.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,12 @@ func ParsePort(rawPort string) (int, error) {
5555
}
5656

5757
// ParsePortRangeToInt parses the port range string and returns start/end ints
58-
func ParsePortRangeToInt(rawPort string) (int, int, error) {
58+
func ParsePortRangeToInt(rawPort string) (startPort, endPort int, _ error) {
5959
if rawPort == "" {
60+
// TODO(thaJeztah): consider making this an error; this was kept to keep existing behavior.
6061
return 0, 0, nil
6162
}
62-
start, end, err := ParsePortRange(rawPort)
63-
if err != nil {
64-
return 0, 0, err
65-
}
66-
return int(start), int(end), nil
63+
return parsePortRange(rawPort)
6764
}
6865

6966
// Proto returns the protocol of a Port

nat/parse.go

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,40 @@ package nat
22

33
import (
44
"errors"
5+
"fmt"
56
"strconv"
67
"strings"
78
)
89

9-
// ParsePortRange parses and validates the specified string as a port-range (8000-9000)
10-
func ParsePortRange(ports string) (uint64, uint64, error) {
10+
// ParsePortRange parses and validates the specified string as a port range (e.g., "8000-9000").
11+
func ParsePortRange(ports string) (startPort, endPort uint64, _ error) {
12+
start, end, err := parsePortRange(ports)
13+
return uint64(start), uint64(end), err
14+
}
15+
16+
// parsePortRange parses and validates the specified string as a port range (e.g., "8000-9000").
17+
func parsePortRange(ports string) (startPort, endPort int, _ error) {
1118
if ports == "" {
1219
return 0, 0, errors.New("empty string specified for ports")
1320
}
14-
if !strings.Contains(ports, "-") {
15-
start, err := strconv.ParseUint(ports, 10, 16)
16-
end := start
17-
return start, end, err
18-
}
21+
start, end, ok := strings.Cut(ports, "-")
1922

20-
parts := strings.Split(ports, "-")
21-
start, err := strconv.ParseUint(parts[0], 10, 16)
23+
startPort, err := parsePortNumber(start)
2224
if err != nil {
23-
return 0, 0, err
25+
return 0, 0, fmt.Errorf("invalid start port '%s': %w", start, err)
2426
}
25-
end, err := strconv.ParseUint(parts[1], 10, 16)
27+
if !ok || start == end {
28+
return startPort, startPort, nil
29+
}
30+
31+
endPort, err = parsePortNumber(end)
2632
if err != nil {
27-
return 0, 0, err
33+
return 0, 0, fmt.Errorf("invalid end port '%s': %w", end, err)
2834
}
29-
if end < start {
30-
return 0, 0, errors.New("invalid range specified for port: " + ports)
35+
if endPort < startPort {
36+
return 0, 0, errors.New("invalid port range: " + ports)
3137
}
32-
return start, end, nil
38+
return startPort, endPort, nil
3339
}
3440

3541
// parsePortNumber parses rawPort into an int, unwrapping strconv errors

nat/parse_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,52 +50,52 @@ func TestParsePortRange(t *testing.T) {
5050
{
5151
doc: "non-numeric port",
5252
input: "asdf",
53-
expErr: `strconv.ParseUint: parsing "asdf": invalid syntax`,
53+
expErr: `invalid start port 'asdf': invalid syntax`,
5454
},
5555
{
5656
doc: "reversed range",
5757
input: "9000-8000",
58-
expErr: `invalid range specified for port: 9000-8000`,
58+
expErr: `invalid port range: 9000-8000`,
5959
},
6060
{
6161
doc: "range missing end",
6262
input: "8000-",
63-
expErr: `strconv.ParseUint: parsing "": invalid syntax`,
63+
expErr: `invalid end port '': value is empty`,
6464
},
6565
{
6666
doc: "range missing start",
6767
input: "-9000",
68-
expErr: `strconv.ParseUint: parsing "": invalid syntax`,
68+
expErr: `invalid start port '': value is empty`,
6969
},
7070
{
7171
doc: "invalid range end",
7272
input: "8000-a",
73-
expErr: `strconv.ParseUint: parsing "a": invalid syntax`,
73+
expErr: `invalid end port 'a': invalid syntax`,
7474
},
7575
{
7676
doc: "invalid range end port",
7777
input: "8000-9000a",
78-
expErr: `strconv.ParseUint: parsing "9000a": invalid syntax`,
78+
expErr: `invalid end port '9000a': invalid syntax`,
7979
},
8080
{
8181
doc: "range range start",
8282
input: "a-9000",
83-
expErr: `strconv.ParseUint: parsing "a": invalid syntax`,
83+
expErr: `invalid start port 'a': invalid syntax`,
8484
},
8585
{
8686
doc: "range range start port",
8787
input: "8000a-9000",
88-
expErr: `strconv.ParseUint: parsing "8000a": invalid syntax`,
88+
expErr: `invalid start port '8000a': invalid syntax`,
8989
},
9090
{
9191
doc: "range with trailing hyphen",
9292
input: "-8000-",
93-
expErr: `strconv.ParseUint: parsing "": invalid syntax`,
93+
expErr: `invalid start port '': value is empty`,
9494
},
9595
{
9696
doc: "range without ports",
9797
input: "-",
98-
expErr: `strconv.ParseUint: parsing "": invalid syntax`,
98+
expErr: `invalid start port '': value is empty`,
9999
},
100100
}
101101

0 commit comments

Comments
 (0)