Skip to content

Commit 8d45c1c

Browse files
authored
fix(mapper): prevent index out of bounds in ToEndpointName with multi-dot suffix (#6433)
When a multi-dot txt-suffix (e.g. ".foo.bar") is configured, ToEndpointName panics on DNS names with fewer labels than the suffix expects: 1. parts[:1+dc] panics when len(parts) <= dc 2. parts[1+dc] panics when len(parts) == 1+dc Add bounds checks before both slice accesses and return ("", "") directly for the too-few-labels case, with a debug log for operator visibility. Return the correct result when the name has exactly enough labels to match the suffix but no trailing labels. This generalizes the single-label fix from #4885, which only guarded the zero-dot case via strings.Contains. Signed-off-by: Jathavedhan M <jathavedhan.m@ibm.com>
1 parent 8290548 commit 8d45c1c

2 files changed

Lines changed: 38 additions & 13 deletions

File tree

registry/mapper/mapper.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ package mapper
1919
import (
2020
"strings"
2121

22+
log "github.com/sirupsen/logrus"
23+
2224
"sigs.k8s.io/external-dns/endpoint"
2325
)
2426

@@ -74,40 +76,42 @@ func (a AffixNameMapper) ToEndpointName(dns string) (string, string) {
7476
// drop suffix
7577
if a.isSuffix() {
7678
dc := strings.Count(a.suffix, ".")
77-
DNSName := strings.SplitN(lowerDNSName, ".", 2+dc)
78-
domainWithSuffix := strings.Join(DNSName[:1+dc], ".")
79-
80-
r, rType := a.dropAffixExtractType(domainWithSuffix)
81-
if !strings.Contains(lowerDNSName, ".") {
79+
parts := strings.SplitN(lowerDNSName, ".", 2+dc)
80+
if len(parts) <= dc {
81+
log.Debugf("skipping TXT record %q: too few labels for suffix %q", dns, a.suffix)
82+
return "", ""
83+
}
84+
r, rType := a.dropAffixExtractType(strings.Join(parts[:1+dc], "."))
85+
if len(parts) <= 1+dc {
8286
return r, rType
8387
}
84-
return r + "." + DNSName[1+dc], rType
88+
return r + "." + parts[1+dc], rType
8589
}
8690
return "", ""
8791
}
8892

8993
func (a AffixNameMapper) ToTXTName(dns, recordType string) string {
90-
DNSName := strings.SplitN(dns, ".", 2)
94+
parts := strings.SplitN(dns, ".", 2)
9195
recordType = strings.ToLower(recordType)
9296
recordT := recordType + "-"
9397

9498
prefix := a.normalizeAffixTemplate(a.prefix, recordType)
9599
suffix := a.normalizeAffixTemplate(a.suffix, recordType)
96100

97101
// If specified, replace a leading asterisk in the generated txt record name with some other string
98-
if a.wildcardReplacement != "" && DNSName[0] == "*" {
99-
DNSName[0] = a.wildcardReplacement
102+
if a.wildcardReplacement != "" && parts[0] == "*" {
103+
parts[0] = a.wildcardReplacement
100104
}
101105

102106
if !a.recordTypeInAffix() {
103-
DNSName[0] = recordT + DNSName[0]
107+
parts[0] = recordT + parts[0]
104108
}
105109

106-
if len(DNSName) < 2 {
107-
return prefix + DNSName[0] + suffix
110+
if len(parts) < 2 {
111+
return prefix + parts[0] + suffix
108112
}
109113

110-
return prefix + DNSName[0] + suffix + "." + DNSName[1]
114+
return prefix + parts[0] + suffix + "." + parts[1]
111115
}
112116

113117
func (a AffixNameMapper) recordTypeInAffix() bool {

registry/mapper/mapper_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,27 @@ func TestAffixNameMapper_ToEndpointName(t *testing.T) {
107107
wantEndpointName: "foo.example.com",
108108
wantRecordType: endpoint.RecordTypeCNAME,
109109
},
110+
{
111+
name: "suffix with multiple dots and trailing labels",
112+
mapper: NewAffixNameMapper("", ".foo.bar", ""),
113+
input: "a-example.foo.bar.com",
114+
wantEndpointName: "example.com",
115+
wantRecordType: endpoint.RecordTypeA,
116+
},
117+
{
118+
name: "suffix with multiple dots and no trailing labels",
119+
mapper: NewAffixNameMapper("", ".foo.bar", ""),
120+
input: "a-example.foo.bar",
121+
wantEndpointName: "example",
122+
wantRecordType: endpoint.RecordTypeA,
123+
},
124+
{
125+
name: "suffix with multiple dots and too few labels does not panic",
126+
mapper: NewAffixNameMapper("", ".foo.bar", ""),
127+
input: "a-example.foo",
128+
wantEndpointName: "",
129+
wantRecordType: "",
130+
},
110131
{
111132
name: "no affix with A record",
112133
mapper: NewAffixNameMapper("", "", ""),

0 commit comments

Comments
 (0)