Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions commands/getZones.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,12 +484,12 @@ func formatDsl(rec *models.RecordConfig, defaultTTL uint32) string {
// DnsControl uses the API to get this info. NAMESERVER() is just
// to override that when needed.
if rec.Name == "@" {
return fmt.Sprintf(`//NAMESERVER("%s")`, rec.AsNS().Ns)
return fmt.Sprintf(`//NAMESERVER(%s)`, jsonQuoted(rec.AsNS().Ns))
}
target = `"` + rec.AsNS().Ns + `"`
target = jsonQuoted(rec.AsNS().Ns)
case "MIKROTIK_FORWARDER":
// Forwarder: target is dns-servers, metadata has doh_servers/verify_doh_cert
target = `"` + rec.GetRDATA().String() + `"`
target = jsonQuoted(rec.GetRDATA().String())
if rec.Metadata != nil {
var fwdParts []string
if v := rec.Metadata["doh_servers"]; v != "" {
Expand All @@ -510,31 +510,31 @@ func formatDsl(rec *models.RecordConfig, defaultTTL uint32) string {
target = strings.Join(fj, ", ")
}

return fmt.Sprintf(`%s("%s", %s%s%s%s%s%s%s%s)`, rec.Type, rec.Name, target, cfproxy, cfflatten, cfcomment, cftags, mtmeta, hednsDynamic, ttlop)
return fmt.Sprintf(`%s(%s, %s%s%s%s%s%s%s%s)`, rec.Type, jsonQuoted(rec.Name), target, cfproxy, cfflatten, cfcomment, cftags, mtmeta, hednsDynamic, ttlop)
}

func makeCaa(rec *models.RecordConfig, ttlop string) string {
f := rec.AsCAA()
var target string
if f.Flag == 128 {
target = fmt.Sprintf(`"%s", "%s", CAA_CRITICAL`, f.Tag, f.Value)
target = fmt.Sprintf(`%s, %s, CAA_CRITICAL`, jsonQuoted(f.Tag), jsonQuoted(f.Value))
} else {
target = fmt.Sprintf(`"%s", "%s"`, f.Tag, f.Value)
target = fmt.Sprintf(`%s, %s`, jsonQuoted(f.Tag), jsonQuoted(f.Value))
}
return fmt.Sprintf(`%s("%s", %s%s)`, rec.Type, rec.Name, target, ttlop)
return fmt.Sprintf(`%s(%s, %s%s)`, rec.Type, jsonQuoted(rec.Name), target, ttlop)

// TODO(tlim): Generate a CAA_BUILDER() instead?
}

func makeR53alias(rec *models.RecordConfig, ttl uint32) string {
f := rec.AsR53ALIAS()
items := []string{
`"` + rec.Name + `"`,
`"` + f.AliasType + `"`,
`"` + f.Target + `"`,
jsonQuoted(rec.Name),
jsonQuoted(f.AliasType),
jsonQuoted(f.Target),
}
if f.ZoneID != "" {
items = append(items, `R53_ZONE("`+f.ZoneID+`")`)
items = append(items, `R53_ZONE(`+jsonQuoted(f.ZoneID)+`)`)
}
if f.EvalTargetHealth == "true" {
items = append(items, "R53_EVALUATE_TARGET_HEALTH(true)")
Expand All @@ -546,5 +546,5 @@ func makeR53alias(rec *models.RecordConfig, ttl uint32) string {
}

func makeUknown(rc *models.RecordConfig, ttl uint32) string {
return fmt.Sprintf(`// %s("%s", TTL(%d))`, rc.UnknownTypeName, rc.GetRDATA().String(), ttl)
return fmt.Sprintf(`// %s(%s, TTL(%d))`, strings.NewReplacer("\r", " ", "\n", " ").Replace(rc.UnknownTypeName), jsonQuoted(rc.GetRDATA().String()), ttl)
}
48 changes: 48 additions & 0 deletions commands/gz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package commands
import (
"fmt"
"os"
"strings"
"testing"

"github.com/DNSControl/dnscontrol/v5/models"
"github.com/DNSControl/dnscontrol/v5/pkg/js"
_ "github.com/DNSControl/dnscontrol/v5/pkg/providers/_all"
"github.com/google/go-cmp/cmp"
)
Expand Down Expand Up @@ -76,3 +79,48 @@ func testFormat(t *testing.T, domain, format string) {
t.Errorf("testFormat mismatch (-got +want):\n%s", diff)
}
}

func TestFormatDslEscaping(t *testing.T) {
dc := &models.DomainConfig{Name: "example.com"}
hostile := `x"), A("injected", "192.0.2.66`

tests := []struct {
name string
label string
rtype string
args []any
}{
{"label", hostile, "A", []any{"192.0.2.1"}},
{"ns", "sub", "NS", []any{hostile + ".example.net."}},
{"apex ns", "@", "NS", []any{"ns1.example.net.\n" + hostile}},
{"caa", "@", "CAA", []any{0, "issue", hostile}},
{"caa critical", "@", "CAA", []any{128, "issue", hostile}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
rc, err := dc.NewRecordConfig(tt.label, 300, tt.rtype, tt.args...)
if err != nil {
t.Fatalf("NewRecordConfig: %v", err)
}
line := formatDsl(rc, 300)
script := fmt.Sprintf("D(\"example.com\", NewRegistrar(\"none\"), DnsProvider(NewDnsProvider(\"none\")),\n%s\n);\n", line)
conf, err := js.ExecuteJavascriptString([]byte(script), false, nil)
if err != nil {
t.Fatalf("generated line does not parse: %v\n%s", err, line)
}
records := conf.Domains[0].Records
if strings.HasPrefix(line, "//") {
if len(records) != 0 {
t.Fatalf("commented-out line produced %d records:\n%s", len(records), line)
}
return
}
if len(records) != 1 {
t.Fatalf("got %d records, want 1:\n%s", len(records), line)
}
if got, want := records[0].GetRDATA().String(), rc.GetRDATA().String(); got != want {
t.Errorf("RDATA = %q, want %q", got, want)
}
})
}
}
Loading