From fa20a70905d6e62d673c5a00bf0112f51f807fa3 Mon Sep 17 00:00:00 2001 From: Brian Wellington Date: Fri, 26 Jun 2020 13:59:59 -0700 Subject: Attempt to refactor per-opcode validation. Instead of validating rrsets and sections after parsing them, check the class/type for each record before parsing it. This is more generic, because it moves all of the update logic out of the common code. It's also more flexible, as it allows the update logic to specify that meta-records are empty. --- dns/update.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'dns/update.py') diff --git a/dns/update.py b/dns/update.py index 9615a73..e21a283 100644 --- a/dns/update.py +++ b/dns/update.py @@ -300,17 +300,24 @@ class UpdateMessage(dns.message.Message): # Updates are always one_rr_per_rrset return True - def _validate_rrset(self, section, rrset): + def _parse_rr_header(self, reader, section, rdclass, rdtype): + deleting = None + empty = False if section == UpdateSection.ZONE: - if rrset.rdtype != dns.rdatatype.SOA: + if dns.rdataclass.is_metaclass(rdclass) or \ + rdtype != dns.rdatatype.SOA or \ + getattr(reader, 'zone_rdclass', None): raise dns.exception.FormError - - def _finish_section(self, section): - if section == UpdateSection.ZONE and len(self.zone) != 1: - raise dns.exception.FormError - self.zone_rdclass = self.zone[0].rdclass - # We do NOT want to set origin here, as that would cause - # from_wire() relativization. + reader.zone_rdclass = rdclass + else: + if not getattr(reader, 'zone_rdclass', None): + raise dns.exception.FormError + if rdclass in (dns.rdataclass.ANY, dns.rdataclass.NONE): + deleting = rdclass + rdclass = reader.zone_rdclass + empty = (deleting == dns.rdataclass.ANY or + section == UpdateSection.PREREQ) + return (rdclass, rdtype, deleting, empty) # backwards compatibility Update = UpdateMessage -- cgit v1.2.1