Fix address/local rule: skip NXDOMAIN address=/domain/ form

GetDomainsFromAddressDirective only considers lines with a non-empty
target after the final slash; address=/domain/ applies to all RR types
and should not require local=. Add tests for trailing-slash and # forms.
This commit is contained in:
2026-03-30 19:41:08 +10:00
parent 5702844cea
commit 1bbab1c8c3
2 changed files with 29 additions and 1 deletions
@@ -390,6 +390,28 @@ public class CrossOptionRulesTests
Assert.Empty(rule.Evaluate(Ctx(cfg)));
}
[Fact]
public void AddressLocalDnsmasq286CompatibilityRule_No_issue_for_nxdomain_form_without_ip()
{
var cfg = CrossOptionTestHelpers.BaselineConfig() with
{
AddressValues = ["/ads.example/"]
};
var rule = new AddressLocalDnsmasq286CompatibilityRule();
Assert.Empty(rule.Evaluate(Ctx(cfg)));
}
[Fact]
public void AddressLocalDnsmasq286CompatibilityRule_Warns_for_hash_target_without_local()
{
var cfg = CrossOptionTestHelpers.BaselineConfig() with
{
AddressValues = ["/blocked.example/#"]
};
var rule = new AddressLocalDnsmasq286CompatibilityRule();
Assert.Single(rule.Evaluate(Ctx(cfg)));
}
[Fact]
public void DnssecCheckUnsignedRequiresDnssecRule_Warns_when_dnssec_check_unsigned_set_without_dnssec()
{
@@ -442,13 +442,19 @@ public sealed class AddressLocalDnsmasq286CompatibilityRule : IEffectiveConfigCr
];
}
// Only address=/domain/IP (or #, etc.) is affected by 2.86 A/AAAA-only behavior. address=/domain/
// (nothing after the last slash) is NXDOMAIN for all RR types and does not need local=.
private static IReadOnlyList<string> GetDomainsFromAddressDirective(string value)
{
var t = value.Trim();
if (!t.StartsWith('/'))
return [];
var end = t.LastIndexOf('/');
if (end <= 1)
if (end < 1)
return [];
var addressPayload = t[(end + 1)..].Trim();
if (addressPayload.Length == 0)
return [];
var domainsPart = t[1..end];