summaryrefslogtreecommitdiff
path: root/dns/rdata.py
diff options
context:
space:
mode:
Diffstat (limited to 'dns/rdata.py')
-rw-r--r--dns/rdata.py40
1 files changed, 26 insertions, 14 deletions
diff --git a/dns/rdata.py b/dns/rdata.py
index e114fe3..98ded79 100644
--- a/dns/rdata.py
+++ b/dns/rdata.py
@@ -111,7 +111,7 @@ def _constify(o):
class Rdata:
"""Base class for all DNS rdata types."""
- __slots__ = ['rdclass', 'rdtype']
+ __slots__ = ['rdclass', 'rdtype', 'rdcomment']
def __init__(self, rdclass, rdtype):
"""Initialize an rdata.
@@ -123,6 +123,7 @@ class Rdata:
object.__setattr__(self, 'rdclass', rdclass)
object.__setattr__(self, 'rdtype', rdtype)
+ object.__setattr__(self, 'rdcomment', None)
def __setattr__(self, name, value):
# Rdatas are immutable
@@ -153,6 +154,10 @@ class Rdata:
def __setstate__(self, state):
for slot, val in state.items():
object.__setattr__(self, slot, val)
+ if not hasattr(self, 'rdcomment'):
+ # Pickled rdata from 2.0.x might not have a rdcomment, so add
+ # it if needed.
+ object.__setattr__(self, 'rdcomment', None)
def covers(self):
"""Return the type a Rdata covers.
@@ -319,6 +324,8 @@ class Rdata:
# Ensure that all of the arguments correspond to valid fields.
# Don't allow rdclass or rdtype to be changed, though.
for key in kwargs:
+ if key == 'rdcomment':
+ continue
if key not in parameters:
raise AttributeError("'{}' object has no attribute '{}'"
.format(self.__class__.__name__, key))
@@ -336,6 +343,11 @@ class Rdata:
# this validation can go away.
rd = self.__class__(*args)
dns.rdata.from_text(rd.rdclass, rd.rdtype, rd.to_text())
+ # The comment is not set in the constructor, so give it special
+ # handling.
+ rdcomment = kwargs.get('rdcomment', self.rdcomment)
+ if rdcomment is not None:
+ object.__setattr__(rd, 'rdcomment', rdcomment)
return rd
@@ -364,13 +376,7 @@ class GenericRdata(Rdata):
raise dns.exception.SyntaxError(
r'generic rdata does not start with \#')
length = tok.get_int()
- chunks = []
- while 1:
- token = tok.get()
- if token.is_eol_or_eof():
- break
- chunks.append(token.value.encode())
- hex = b''.join(chunks)
+ hex = tok.concatenate_remaining_identifiers().encode()
data = binascii.unhexlify(hex)
if len(data) != length:
raise dns.exception.SyntaxError(
@@ -459,6 +465,7 @@ def from_text(rdclass, rdtype, tok, origin=None, relativize=True,
rdclass = dns.rdataclass.RdataClass.make(rdclass)
rdtype = dns.rdatatype.RdataType.make(rdtype)
cls = get_rdata_class(rdclass, rdtype)
+ rdata = None
if cls != GenericRdata:
# peek at first token
token = tok.get()
@@ -470,12 +477,17 @@ def from_text(rdclass, rdtype, tok, origin=None, relativize=True,
# wire form from the generic syntax, and then run
# from_wire on it.
#
- rdata = GenericRdata.from_text(rdclass, rdtype, tok, origin,
- relativize, relativize_to)
- return from_wire(rdclass, rdtype, rdata.data, 0, len(rdata.data),
- origin)
- return cls.from_text(rdclass, rdtype, tok, origin, relativize,
- relativize_to)
+ grdata = GenericRdata.from_text(rdclass, rdtype, tok, origin,
+ relativize, relativize_to)
+ rdata = from_wire(rdclass, rdtype, grdata.data, 0, len(grdata.data),
+ origin)
+ if rdata is None:
+ rdata = cls.from_text(rdclass, rdtype, tok, origin, relativize,
+ relativize_to)
+ token = tok.get_eol_as_token()
+ if token.comment is not None:
+ object.__setattr__(rdata, 'rdcomment', token.comment)
+ return rdata
def from_wire_parser(rdclass, rdtype, parser, origin=None):