From dd7a17365e9b368aaa98d1d866f481a2c7141c35 Mon Sep 17 00:00:00 2001 From: Suliman Abdulrazzaq Date: Sat, 3 Oct 2026 09:01:52 +0300 Subject: [PATCH] fix: report IMPORT_TRANSFORM of a non-existent domain instead of crashing ValidateAndNormalizeConfig records an error when the domain named by an IMPORT_TRANSFORM does not exist, but then calls importTransform with the nil domain anyway, which dereferences it and panics. Skip the transform after recording the error, as is done when the transform table cannot be decoded. --- pkg/normalize/importTransform_test.go | 34 +++++++++++++++++++++++++++ pkg/normalize/validate.go | 1 + 2 files changed, 35 insertions(+) diff --git a/pkg/normalize/importTransform_test.go b/pkg/normalize/importTransform_test.go index 84eb5c5a8e..3ce47e54f4 100644 --- a/pkg/normalize/importTransform_test.go +++ b/pkg/normalize/importTransform_test.go @@ -1,6 +1,7 @@ package normalize import ( + "strings" "testing" dnsv2 "codeberg.org/miekg/dns" @@ -46,3 +47,36 @@ func TestImportTransform(t *testing.T) { t.Fatalf("Expected 3 records in internal, but got %d", len(d.Records)) } } + +// An IMPORT_TRANSFORM that names a domain that is not in the config must be +// reported as an error. It must not crash. +func TestImportTransformMissingDomain(t *testing.T) { + const transformSingle = "0.0.0.0~1.1.1.1~~8.0.0.0" + + dc := models.MustNewDomainConfig("internal") + dc.AddRecordConfig(dc.MustNewRecordConfig("www", 0, dnsv2.TypeA, "0.0.3.3")) + dc.AddRecordConfig(dc.MustNewRecordConfig("@", 0, privatetypes.TypeIMPORTTRANSFORM, transformSingle, 299, "com.internal", "missing.example")) + + cfg := &models.DNSConfig{} + cfg.Domains = append(cfg.Domains, dc) + if err := cfg.PostProcess(); err != nil { + t.Fatal(err) + } + + var errs []error + func() { + defer func() { + if r := recover(); r != nil { + t.Fatalf("ValidateAndNormalizeConfig panicked: %v", r) + } + }() + errs = ValidateAndNormalizeConfig(cfg) + }() + + for _, err := range errs { + if strings.Contains(err.Error(), `IMPORT_TRANSFORM mentions non-existent domain "missing.example"`) { + return + } + } + t.Errorf("expected an error about the non-existent domain, got %v", errs) +} diff --git a/pkg/normalize/validate.go b/pkg/normalize/validate.go index e50571d490..824b84fec5 100644 --- a/pkg/normalize/validate.go +++ b/pkg/normalize/validate.go @@ -530,6 +530,7 @@ func ValidateAndNormalizeConfig(config *models.DNSConfig) (errs []error) { if c == nil { err = fmt.Errorf("IMPORT_TRANSFORM mentions non-existent domain %q", targetDomain) errs = append(errs, err) + continue } err = importTransform(c, domain, table, ttl, suffixstrip) if err != nil {