Skip to content

Commit 0849a0a

Browse files
committed
#334: protect against empty answers
1 parent b0e7170 commit 0849a0a

File tree

2 files changed

+68
-45
lines changed

2 files changed

+68
-45
lines changed

ns1/resource_record.go

Lines changed: 51 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -370,47 +370,51 @@ func resourceDataToRecord(r *dns.Record, d *schema.ResourceData) error {
370370

371371
if shortAnswers := d.Get("short_answers").([]interface{}); len(shortAnswers) > 0 {
372372
for _, answerRaw := range shortAnswers {
373-
answer := answerRaw.(string)
374-
switch d.Get("type") {
375-
case "TXT", "SPF":
376-
r.AddAnswer(dns.NewTXTAnswer(answer))
377-
case "CAA":
378-
r.AddAnswer(dns.NewAnswer(strings.SplitN(answer, " ", 3)))
379-
default:
380-
r.AddAnswer(dns.NewAnswer(strings.Split(answer, " ")))
373+
if answerRaw != nil {
374+
answer := answerRaw.(string)
375+
switch d.Get("type") {
376+
case "TXT", "SPF":
377+
r.AddAnswer(dns.NewTXTAnswer(answer))
378+
case "CAA":
379+
r.AddAnswer(dns.NewAnswer(strings.SplitN(answer, " ", 3)))
380+
default:
381+
r.AddAnswer(dns.NewAnswer(strings.Split(answer, " ")))
382+
}
381383
}
382384
}
383385
}
384386
if answers := d.Get("answers").([]interface{}); len(answers) > 0 {
385387
for _, answerRaw := range answers {
386-
answer := answerRaw.(map[string]interface{})
387-
var a *dns.Answer
388-
389-
v := answer["answer"].(string)
390-
switch d.Get("type") {
391-
case "TXT", "SPF":
392-
a = dns.NewTXTAnswer(v)
393-
case "CAA":
394-
a = dns.NewAnswer(strings.SplitN(v, " ", 3))
395-
default:
396-
a = dns.NewAnswer(strings.Split(v, " "))
397-
}
388+
if answerRaw != nil {
389+
answer := answerRaw.(map[string]interface{})
390+
var a *dns.Answer
391+
392+
v := answer["answer"].(string)
393+
switch d.Get("type") {
394+
case "TXT", "SPF":
395+
a = dns.NewTXTAnswer(v)
396+
case "CAA":
397+
a = dns.NewAnswer(strings.SplitN(v, " ", 3))
398+
default:
399+
a = dns.NewAnswer(strings.Split(v, " "))
400+
}
398401

399-
if v, ok := answer["region"]; ok {
400-
a.RegionName = v.(string)
401-
}
402+
if v, ok := answer["region"]; ok {
403+
a.RegionName = v.(string)
404+
}
402405

403-
if v, ok := answer["meta"]; ok {
404-
log.Println("answer meta", v)
405-
meta, err := metaHandler(v)
406-
if err != nil {
407-
return err
406+
if v, ok := answer["meta"]; ok {
407+
log.Println("answer meta", v)
408+
meta, err := metaHandler(v)
409+
if err != nil {
410+
return err
411+
}
412+
413+
a.Meta = meta
408414
}
409415

410-
a.Meta = meta
416+
r.AddAnswer(a)
411417
}
412-
413-
r.AddAnswer(a)
414418
}
415419
}
416420
log.Println("number of answers found:", len(r.Answers))
@@ -447,21 +451,23 @@ func resourceDataToRecord(r *dns.Record, d *schema.ResourceData) error {
447451
r.UseClientSubnet = &useClientSubnet
448452

449453
if rawFilters := d.Get("filters").([]interface{}); len(rawFilters) > 0 {
450-
filters := make([]*filter.Filter, len(rawFilters))
451-
for i, filterRaw := range rawFilters {
452-
fi := filterRaw.(map[string]interface{})
453-
config := make(map[string]interface{})
454-
f := filter.Filter{
455-
Type: fi["filter"].(string),
456-
Config: config,
457-
}
458-
if disabled, ok := fi["disabled"]; ok {
459-
f.Disabled = disabled.(bool)
460-
}
461-
if rawConfig, ok := fi["config"]; ok {
462-
f.Config = rawConfig.(map[string]interface{})
454+
filters := make([]*filter.Filter, 0, len(rawFilters))
455+
for _, filterRaw := range rawFilters {
456+
if filterRaw != nil {
457+
fi := filterRaw.(map[string]interface{})
458+
config := make(map[string]interface{})
459+
f := filter.Filter{
460+
Type: fi["filter"].(string),
461+
Config: config,
462+
}
463+
if disabled, ok := fi["disabled"]; ok {
464+
f.Disabled = disabled.(bool)
465+
}
466+
if rawConfig, ok := fi["config"]; ok {
467+
f.Config = rawConfig.(map[string]interface{})
468+
}
469+
filters = append(filters, &f)
463470
}
464-
filters[i] = &f
465471
}
466472
r.Filters = filters
467473
}

ns1/resource_record_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,10 @@ func TestAccRecord_validationError(t *testing.T) {
606606
*/
607607
ExpectError: regexp.MustCompile(`(?s)(Error: (zone|domain) has an invalid (leading|trailing) "\.", got: .*){4}`),
608608
},
609+
{
610+
Config: testAccRecordNoAnswers(rString),
611+
ExpectError: regexp.MustCompile(`Invalid body`),
612+
},
609613
},
610614
})
611615
}
@@ -2018,6 +2022,19 @@ resource "ns1_record" "it" {
20182022
`, rString, rString)
20192023
}
20202024

2025+
// there must be at least one answer
2026+
func testAccRecordNoAnswers(rString string) string {
2027+
return fmt.Sprintf(`
2028+
resource "ns1_record" "it" {
2029+
zone = "terraform-test-%s.io"
2030+
domain = "test.terraform-test-%s.io"
2031+
type = "CNAME"
2032+
ttl = 60
2033+
answers {}
2034+
}
2035+
`, rString, rString)
2036+
}
2037+
20212038
func testAccRecordLink(rString string) string {
20222039
return fmt.Sprintf(`
20232040
# the name being tested that is a link

0 commit comments

Comments
 (0)