From 3e238ab51d1ec75b5fad86a7ec5749475078d42b Mon Sep 17 00:00:00 2001 From: agammann <161159040+agammann@users.noreply.github.com> Date: Sun, 20 Sep 2026 14:54:27 -0700 Subject: [PATCH] Validate IP slice values before appending or replacing --- ip_slice.go | 20 ++++++++++++++++---- ip_slice_test.go | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/ip_slice.go b/ip_slice.go index 84fa4189..699f399f 100644 --- a/ip_slice.go +++ b/ip_slice.go @@ -70,8 +70,12 @@ func (s *ipSliceValue) String() string { return "[" + out + "]" } -func (s *ipSliceValue) fromString(val string) net.IP { - return net.ParseIP(strings.TrimSpace(val)) +func (s *ipSliceValue) fromString(val string) (net.IP, error) { + ip := net.ParseIP(strings.TrimSpace(val)) + if ip == nil { + return nil, fmt.Errorf("invalid string being converted to IP address: %s", val) + } + return ip, nil } func (s *ipSliceValue) toString(val net.IP) string { @@ -79,14 +83,22 @@ func (s *ipSliceValue) toString(val net.IP) string { } func (s *ipSliceValue) Append(val string) error { - *s.value = append(*s.value, s.fromString(val)) + ip, err := s.fromString(val) + if err != nil { + return err + } + *s.value = append(*s.value, ip) return nil } func (s *ipSliceValue) Replace(val []string) error { out := make([]net.IP, len(val)) for i, d := range val { - out[i] = s.fromString(d) + ip, err := s.fromString(d) + if err != nil { + return err + } + out[i] = ip } *s.value = out return nil diff --git a/ip_slice_test.go b/ip_slice_test.go index 366dc195..547178f6 100644 --- a/ip_slice_test.go +++ b/ip_slice_test.go @@ -243,3 +243,41 @@ func TestIPSBadQuoting(t *testing.T) { } } } + +func TestIPSliceValueRejectsInvalidIPs(t *testing.T) { + for _, operation := range []string{"Append", "Replace"} { + t.Run(operation, func(t *testing.T) { + var ips []net.IP + value := newIPSliceValue([]net.IP{net.ParseIP("192.0.2.1")}, &ips) + var err error + if operation == "Append" { + err = value.Append("not-an-ip") + } else { + err = value.Replace([]string{"2001:db8::1", "not-an-ip"}) + } + if err == nil { + t.Error("expected an error for an invalid IP") + } + if len(ips) != 1 || !ips[0].Equal(net.ParseIP("192.0.2.1")) { + t.Errorf("invalid input changed the slice: %v", ips) + } + }) + } +} + +func TestIPSliceValueAppendAndReplace(t *testing.T) { + var ips []net.IP + value := newIPSliceValue(nil, &ips) + if err := value.Append(" 192.0.2.1 "); err != nil { + t.Fatal(err) + } + if len(ips) != 1 || !ips[0].Equal(net.ParseIP("192.0.2.1")) { + t.Fatalf("unexpected appended IPs: %v", ips) + } + if err := value.Replace([]string{" 2001:db8::1 "}); err != nil { + t.Fatal(err) + } + if len(ips) != 1 || !ips[0].Equal(net.ParseIP("2001:db8::1")) { + t.Fatalf("unexpected replacement IPs: %v", ips) + } +}