]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
do more careful bounds checking, and if checking fails, raise dns.exception.FormErr
authorBob Halley <halley@nominum.com>
Tue, 5 Apr 2011 11:30:54 +0000 (12:30 +0100)
committerBob Halley <halley@nominum.com>
Tue, 5 Apr 2011 11:30:54 +0000 (12:30 +0100)
28 files changed:
dns/__init__.py
dns/message.py
dns/name.py
dns/rdata.py
dns/rdtypes/ANY/CERT.py
dns/rdtypes/ANY/GPOS.py
dns/rdtypes/ANY/HINFO.py
dns/rdtypes/ANY/HIP.py
dns/rdtypes/ANY/ISDN.py
dns/rdtypes/ANY/NSEC.py
dns/rdtypes/ANY/NSEC3.py
dns/rdtypes/ANY/NSEC3PARAM.py
dns/rdtypes/ANY/NXT.py
dns/rdtypes/ANY/SOA.py
dns/rdtypes/ANY/SSHFP.py
dns/rdtypes/ANY/X25.py
dns/rdtypes/IN/APL.py
dns/rdtypes/IN/DHCID.py
dns/rdtypes/IN/IPSECKEY.py
dns/rdtypes/IN/NAPTR.py
dns/rdtypes/IN/NSAP.py
dns/rdtypes/IN/PX.py
dns/rdtypes/IN/WKS.py
dns/rdtypes/dsbase.py
dns/rdtypes/keybase.py
dns/rdtypes/sigbase.py
dns/rdtypes/txtbase.py
dns/wiredata.py [new file with mode: 0644]

index 56e1e8a2ea8085d3e516026e2ef41c78cf0e19d6..1716168d131c4392217091bf25e722cf9245206b 100644 (file)
@@ -49,5 +49,6 @@ __all__ = [
     'rdtypes',
     'update',
     'version',
+    'wiredata',
     'zone',
 ]
index a124a3e1779094e08f762388571737da810a642b..77c278716e887ef29fba56618aa0645c588cc439 100644 (file)
@@ -34,6 +34,7 @@ import dns.rdatatype
 import dns.rrset
 import dns.renderer
 import dns.tsig
+import dns.wiredata
 
 class ShortHeader(dns.exception.FormError):
     """Raised if the DNS packet passed to from_wire() is too short."""
@@ -577,7 +578,7 @@ class _WireReader(object):
 
     def __init__(self, wire, message, question_only=False,
                  one_rr_per_rrset=False):
-        self.wire = wire
+        self.wire = dns.wiredata.maybe_wrap(wire)
         self.message = message
         self.current = 0
         self.updating = False
index f239c9b5de20eb9dccefeb7be01dea15e0431008..29c3963914037461bd8d29183303b84676e43fe9 100644 (file)
@@ -29,6 +29,7 @@ if sys.hexversion >= 0x02030000:
     import encodings.idna
 
 import dns.exception
+import dns.wiredata
 
 NAMERELN_NONE = 0
 NAMERELN_SUPERDOMAIN = 1
@@ -670,6 +671,7 @@ def from_wire(message, current):
 
     if not isinstance(message, str):
         raise ValueError("input to from_wire() must be a byte string")
+    message = dns.wiredata.maybe_wrap(message)
     labels = []
     biggest_pointer = current
     hops = 0
@@ -678,7 +680,7 @@ def from_wire(message, current):
     cused = 1
     while count != 0:
         if count < 64:
-            labels.append(message[current : current + count])
+            labels.append(message[current : current + count].unwrap())
             current += count
             if hops == 0:
                 cused += count
index 98f504751df5c7fbcd3f092965858ee9a588e494..caaaa01cb93f2f41774e23356c9cf2987c8cde64 100644 (file)
@@ -32,6 +32,7 @@ import dns.name
 import dns.rdataclass
 import dns.rdatatype
 import dns.tokenizer
+import dns.wiredata
 
 _hex_chunksize = 32
 
@@ -469,5 +470,6 @@ def from_wire(rdclass, rdtype, wire, current, rdlen, origin = None):
     @type origin: dns.name.Name
     @rtype: dns.rdata.Rdata instance"""
 
+    wire = dns.wiredata.maybe_wrap(wire)
     cls = get_rdata_class(rdclass, rdtype)
     return cls.from_wire(rdclass, rdtype, wire, current, rdlen, origin)
index d2703519d5f842325f02e02f57a4963e1920b715..0152bb25796959398ff3d94d4f63ecb3d7bee1c7 100644 (file)
@@ -106,13 +106,13 @@ class CERT(dns.rdata.Rdata):
         file.write(self.certificate)
 
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        prefix = wire[current : current + 5]
+        prefix = wire[current : current + 5].unwrap()
         current += 5
         rdlen -= 5
         if rdlen < 0:
             raise dns.exception.FormError
         (certificate_type, key_tag, algorithm) = struct.unpack("!HHB", prefix)
-        certificate = wire[current : current + rdlen]
+        certificate = wire[current : current + rdlen].unwrap()
         return cls(rdclass, rdtype, certificate_type, key_tag, algorithm,
                    certificate)
 
index 6f63cc05f63c549cecb28a9b42ce6d4bb5d144aa..3457cc486f60c8e395edc54f2526e646eea8a411 100644 (file)
@@ -29,7 +29,7 @@ def _validate_float_string(what):
         raise dns.exception.FormError
     if not right == '' and not right.isdigit():
         raise dns.exception.FormError
-    
+
 class GPOS(dns.rdata.Rdata):
     """GPOS record
 
@@ -42,7 +42,7 @@ class GPOS(dns.rdata.Rdata):
     @see: RFC 1712"""
 
     __slots__ = ['latitude', 'longitude', 'altitude']
-    
+
     def __init__(self, rdclass, rdtype, latitude, longitude, altitude):
         super(GPOS, self).__init__(rdclass, rdtype)
         if isinstance(latitude, float) or \
@@ -66,14 +66,14 @@ class GPOS(dns.rdata.Rdata):
 
     def to_text(self, origin=None, relativize=True, **kw):
         return '%s %s %s' % (self.latitude, self.longitude, self.altitude)
-        
+
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         latitude = tok.get_string()
         longitude = tok.get_string()
         altitude = tok.get_string()
         tok.get_eol()
         return cls(rdclass, rdtype, latitude, longitude, altitude)
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
@@ -92,14 +92,14 @@ class GPOS(dns.rdata.Rdata):
         byte = chr(l)
         file.write(byte)
         file.write(self.altitude)
-        
+
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         l = ord(wire[current])
         current += 1
         rdlen -= 1
         if l > rdlen:
             raise dns.exception.FormError
-        latitude = wire[current : current + l]
+        latitude = wire[current : current + l].unwrap()
         current += l
         rdlen -= l
         l = ord(wire[current])
@@ -107,7 +107,7 @@ class GPOS(dns.rdata.Rdata):
         rdlen -= 1
         if l > rdlen:
             raise dns.exception.FormError
-        longitude = wire[current : current + l]
+        longitude = wire[current : current + l].unwrap()
         current += l
         rdlen -= l
         l = ord(wire[current])
@@ -115,7 +115,7 @@ class GPOS(dns.rdata.Rdata):
         rdlen -= 1
         if l != rdlen:
             raise dns.exception.FormError
-        altitude = wire[current : current + l]
+        altitude = wire[current : current + l].unwrap()
         return cls(rdclass, rdtype, latitude, longitude, altitude)
 
     from_wire = classmethod(from_wire)
index e592ad39a7d86b5a30e5d2b223a09be83d612d34..2a1ff38932f4fd4e185c53ab62b295ba10c12022 100644 (file)
@@ -27,7 +27,7 @@ class HINFO(dns.rdata.Rdata):
     @see: RFC 1035"""
 
     __slots__ = ['cpu', 'os']
-    
+
     def __init__(self, rdclass, rdtype, cpu, os):
         super(HINFO, self).__init__(rdclass, rdtype)
         self.cpu = cpu
@@ -36,13 +36,13 @@ class HINFO(dns.rdata.Rdata):
     def to_text(self, origin=None, relativize=True, **kw):
         return '"%s" "%s"' % (dns.rdata._escapify(self.cpu),
                               dns.rdata._escapify(self.os))
-        
+
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         cpu = tok.get_string()
         os = tok.get_string()
         tok.get_eol()
         return cls(rdclass, rdtype, cpu, os)
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
@@ -56,14 +56,14 @@ class HINFO(dns.rdata.Rdata):
         byte = chr(l)
         file.write(byte)
         file.write(self.os)
-        
+
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         l = ord(wire[current])
         current += 1
         rdlen -= 1
         if l > rdlen:
             raise dns.exception.FormError
-        cpu = wire[current : current + l]
+        cpu = wire[current : current + l].unwrap()
         current += l
         rdlen -= l
         l = ord(wire[current])
@@ -71,7 +71,7 @@ class HINFO(dns.rdata.Rdata):
         rdlen -= 1
         if l != rdlen:
             raise dns.exception.FormError
-        os = wire[current : current + l]
+        os = wire[current : current + l].unwrap()
         return cls(rdclass, rdtype, cpu, os)
 
     from_wire = classmethod(from_wire)
index 8f96ae93d640cc8dbd4a699a494fa94c8c6b902d..aa6c7e9aab9a38168b8f229293e6f5edfedce514 100644 (file)
@@ -86,10 +86,10 @@ class HIP(dns.rdata.Rdata):
                                             wire[current : current + 4])
         current += 4
         rdlen -= 4
-        hit = wire[current : current + lh]
+        hit = wire[current : current + lh].unwrap()
         current += lh
         rdlen -= lh
-        key = wire[current : current + lk]
+        key = wire[current : current + lk].unwrap()
         current += lk
         rdlen -= lk
         servers = []
index 424d3a9a3c9f95194e91a0d26efe797a3af08248..1bf4d5e03426231587f219488f8a4be46a98aa61 100644 (file)
@@ -73,7 +73,7 @@ class ISDN(dns.rdata.Rdata):
         rdlen -= 1
         if l > rdlen:
             raise dns.exception.FormError
-        address = wire[current : current + l]
+        address = wire[current : current + l].unwrap()
         current += l
         rdlen -= l
         if rdlen > 0:
@@ -82,7 +82,7 @@ class ISDN(dns.rdata.Rdata):
             rdlen -= 1
             if l != rdlen:
                 raise dns.exception.FormError
-            subaddress = wire[current : current + l]
+            subaddress = wire[current : current + l].unwrap()
         else:
             subaddress = ''
         return cls(rdclass, rdtype, address, subaddress)
index 44ccbc1b0bb0151d4a4826d363fb5e351c13e04a..e54e69292b6b0affe74f94a4cb955d22261c9e52 100644 (file)
@@ -111,7 +111,7 @@ class NSEC(dns.rdata.Rdata):
             rdlen -= 2
             if rdlen < octets:
                 raise dns.exception.FormError("bad NSEC bitmap length")
-            bitmap = wire[current : current + octets]
+            bitmap = wire[current : current + octets].unwrap()
             current += octets
             rdlen -= octets
             windows.append((window, bitmap))
index 932d7b40327553a83e5f8c971f6558a4b94d8a11..2f0ea7dbc710a6e4fdaac8f8b989d46a71d101c0 100644 (file)
@@ -145,13 +145,13 @@ class NSEC3(dns.rdata.Rdata):
                                                              wire[current : current + 5])
         current += 5
         rdlen -= 5
-        salt = wire[current : current + slen]
+        salt = wire[current : current + slen].unwrap()
         current += slen
         rdlen -= slen
         (nlen, ) = struct.unpack('!B', wire[current])
         current += 1
         rdlen -= 1
-        next = wire[current : current + nlen]
+        next = wire[current : current + nlen].unwrap()
         current += nlen
         rdlen -= nlen
         windows = []
@@ -166,7 +166,7 @@ class NSEC3(dns.rdata.Rdata):
             rdlen -= 2
             if rdlen < octets:
                 raise dns.exception.FormError("bad NSEC3 bitmap length")
-            bitmap = wire[current : current + octets]
+            bitmap = wire[current : current + octets].unwrap()
             current += octets
             rdlen -= octets
             windows.append((window, bitmap))
index ec91e5e85c3a76544f5529f9ab09487439277bb9..c00685636fd9b213d13f16785becc9231e9ce305 100644 (file)
@@ -71,7 +71,7 @@ class NSEC3PARAM(dns.rdata.Rdata):
                                                              wire[current : current + 5])
         current += 5
         rdlen -= 5
-        salt = wire[current : current + slen]
+        salt = wire[current : current + slen].unwrap()
         current += slen
         rdlen -= slen
         if rdlen != 0:
index 99ae9b9dff6eca36bcaaa60de38cf91087654260..0bfe2f309b69bafe419fe57dc2ec468ec5676eaf 100644 (file)
@@ -82,7 +82,7 @@ class NXT(dns.rdata.Rdata):
         (next, cused) = dns.name.from_wire(wire[: current + rdlen], current)
         current += cused
         rdlen -= cused
-        bitmap = wire[current : current + rdlen]
+        bitmap = wire[current : current + rdlen].unwrap()
         if not origin is None:
             next = next.relativize(origin)
         return cls(rdclass, rdtype, next, bitmap)
index a25a35e29b0bf4bb1a9eb42ea4d2d4003dcd620a..5f74b8d384201272cddb9f6c9817453744102a3d 100644 (file)
@@ -41,7 +41,7 @@ class SOA(dns.rdata.Rdata):
 
     __slots__ = ['mname', 'rname', 'serial', 'refresh', 'retry', 'expire',
                  'minimum']
-    
+
     def __init__(self, rdclass, rdtype, mname, rname, serial, refresh, retry,
                  expire, minimum):
         super(SOA, self).__init__(rdclass, rdtype)
@@ -59,7 +59,7 @@ class SOA(dns.rdata.Rdata):
         return '%s %s %d %d %d %d %d' % (
             mname, rname, self.serial, self.refresh, self.retry,
             self.expire, self.minimum )
-        
+
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         mname = tok.get_name()
         rname = tok.get_name()
@@ -73,7 +73,7 @@ class SOA(dns.rdata.Rdata):
         tok.get_eol()
         return cls(rdclass, rdtype, mname, rname, serial, refresh, retry,
                    expire, minimum )
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
index 162dda5c4887ae501634370bf0c5fe7abd96b436..881cc8164968ee7cd0bd6e91a59cf190a16dcc6a 100644 (file)
@@ -30,7 +30,7 @@ class SSHFP(dns.rdata.Rdata):
     @see: draft-ietf-secsh-dns-05.txt"""
 
     __slots__ = ['algorithm', 'fp_type', 'fingerprint']
-    
+
     def __init__(self, rdclass, rdtype, algorithm, fp_type,
                  fingerprint):
         super(SSHFP, self).__init__(rdclass, rdtype)
@@ -43,7 +43,7 @@ class SSHFP(dns.rdata.Rdata):
                              self.fp_type,
                              dns.rdata._hexify(self.fingerprint,
                                                chunksize=128))
-        
+
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         algorithm = tok.get_uint8()
         fp_type = tok.get_uint8()
@@ -51,19 +51,19 @@ class SSHFP(dns.rdata.Rdata):
         fingerprint = fingerprint.decode('hex_codec')
         tok.get_eol()
         return cls(rdclass, rdtype, algorithm, fp_type, fingerprint)
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
         header = struct.pack("!BB", self.algorithm, self.fp_type)
         file.write(header)
         file.write(self.fingerprint)
-        
+
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         header = struct.unpack("!BB", wire[current : current + 2])
         current += 2
         rdlen -= 2
-        fingerprint = wire[current : current + rdlen]
+        fingerprint = wire[current : current + rdlen].unwrap()
         return cls(rdclass, rdtype, header[0], header[1], fingerprint)
 
     from_wire = classmethod(from_wire)
index c3632f7fc406b088c08dd834f3a0fc8e9be101a0..e10efb45bb3c7311d91aa1731dd4bbb7c7933552 100644 (file)
@@ -25,19 +25,19 @@ class X25(dns.rdata.Rdata):
     @see: RFC 1183"""
 
     __slots__ = ['address']
-    
+
     def __init__(self, rdclass, rdtype, address):
         super(X25, self).__init__(rdclass, rdtype)
         self.address = address
 
     def to_text(self, origin=None, relativize=True, **kw):
         return '"%s"' % dns.rdata._escapify(self.address)
-        
+
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         address = tok.get_string()
         tok.get_eol()
         return cls(rdclass, rdtype, address)
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
@@ -46,14 +46,14 @@ class X25(dns.rdata.Rdata):
         byte = chr(l)
         file.write(byte)
         file.write(self.address)
-        
+
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         l = ord(wire[current])
         current += 1
         rdlen -= 1
         if l != rdlen:
             raise dns.exception.FormError
-        address = wire[current : current + l]
+        address = wire[current : current + l].unwrap()
         return cls(rdclass, rdtype, address)
 
     from_wire = classmethod(from_wire)
index 7412c02d304196d9570e1b55c46553201356bdce..c181e823ee7bf295def273131d601637a62b0a3f 100644 (file)
@@ -131,7 +131,7 @@ class APL(dns.rdata.Rdata):
             rdlen -= 4
             if rdlen < afdlen:
                 raise dns.exception.FormError
-            address = wire[current : current + afdlen]
+            address = wire[current : current + afdlen].unwrap()
             l = len(address)
             if header[0] == 1:
                 if l < 4:
index 2d35234bf04ca025638438698c4097ae078e8ec0..ffe0b91c29c866880abf7ac4727bbe431e5c349d 100644 (file)
@@ -51,7 +51,7 @@ class DHCID(dns.rdata.Rdata):
         file.write(self.data)
 
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        data = wire[current : current + rdlen]
+        data = wire[current : current + rdlen].unwrap()
         return cls(rdclass, rdtype, data)
 
     from_wire = classmethod(from_wire)
index 9ab08d881c552877090315192d30629210a9d759..6248e6cfc078a2ba1c3d3eb72fdfaefdbda43ac4 100644 (file)
@@ -140,7 +140,7 @@ class IPSECKEY(dns.rdata.Rdata):
             rdlen -= cused
         else:
             raise dns.exception.FormError('invalid IPSECKEY gateway type')
-        key = wire[current : current + rdlen]
+        key = wire[current : current + rdlen].unwrap()
         return cls(rdclass, rdtype, header[0], gateway_type, header[2],
                    gateway, key)
 
index a3cca55e1ce6fe581377f4ab891d8fafa061c1c9..60ec177e15041e74d370b058c8f6a3e5d94d02c7 100644 (file)
@@ -45,7 +45,7 @@ class NAPTR(dns.rdata.Rdata):
 
     __slots__ = ['order', 'preference', 'flags', 'service', 'regexp',
                  'replacement']
-    
+
     def __init__(self, rdclass, rdtype, order, preference, flags, service,
                  regexp, replacement):
         super(NAPTR, self).__init__(rdclass, rdtype)
@@ -76,7 +76,7 @@ class NAPTR(dns.rdata.Rdata):
         tok.get_eol()
         return cls(rdclass, rdtype, order, preference, flags, service,
                    regexp, replacement)
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
@@ -86,7 +86,7 @@ class NAPTR(dns.rdata.Rdata):
         _write_string(file, self.service)
         _write_string(file, self.regexp)
         self.replacement.to_wire(file, compress, origin)
-        
+
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         (order, preference) = struct.unpack('!HH', wire[current : current + 4])
         current += 4
@@ -98,7 +98,7 @@ class NAPTR(dns.rdata.Rdata):
             rdlen -= 1
             if l > rdlen or rdlen < 0:
                 raise dns.exception.FormError
-            s = wire[current : current + l]
+            s = wire[current : current + l].unwrap()
             current += l
             rdlen -= l
             strings.append(s)
@@ -116,7 +116,7 @@ class NAPTR(dns.rdata.Rdata):
     def choose_relativity(self, origin = None, relativize = True):
         self.replacement = self.replacement.choose_relativity(origin,
                                                               relativize)
-        
+
     def _cmp(self, other):
         sp = struct.pack("!HH", self.order, self.preference)
         op = struct.pack("!HH", other.order, other.preference)
index 22b9131ccf3fe0c751801f542cf3131f54d4b453..b4112aed1df720b8880c1daba458ea810b9a8302 100644 (file)
@@ -50,7 +50,7 @@ class NSAP(dns.rdata.Rdata):
         file.write(self.address)
 
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        address = wire[current : current + rdlen]
+        address = wire[current : current + rdlen].unwrap()
         return cls(rdclass, rdtype, address)
 
     from_wire = classmethod(from_wire)
index 0f112907240696c0cb74acbed5855c8a1c2df3e9..4718944ff4fd8e841107e18be38b7874b865bf2c 100644 (file)
@@ -31,7 +31,7 @@ class PX(dns.rdata.Rdata):
     @see: RFC 2163"""
 
     __slots__ = ['preference', 'map822', 'mapx400']
-        
+
     def __init__(self, rdclass, rdtype, preference, map822, mapx400):
         super(PX, self).__init__(rdclass, rdtype)
         self.preference = preference
@@ -42,7 +42,7 @@ class PX(dns.rdata.Rdata):
         map822 = self.map822.choose_relativity(origin, relativize)
         mapx400 = self.mapx400.choose_relativity(origin, relativize)
         return '%d %s %s' % (self.preference, map822, mapx400)
-        
+
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         preference = tok.get_uint16()
         map822 = tok.get_name()
@@ -51,7 +51,7 @@ class PX(dns.rdata.Rdata):
         mapx400 = mapx400.choose_relativity(origin, relativize)
         tok.get_eol()
         return cls(rdclass, rdtype, preference, map822, mapx400)
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
@@ -59,7 +59,7 @@ class PX(dns.rdata.Rdata):
         file.write(pref)
         self.map822.to_wire(file, None, origin)
         self.mapx400.to_wire(file, None, origin)
-        
+
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         (preference, ) = struct.unpack('!H', wire[current : current + 2])
         current += 2
index 85aafb3d231d546cf3d68c5ed89cf0b9318fd87c..06e2970aec1e6b3c8bafa6891092712c4f63e5c5 100644 (file)
@@ -95,7 +95,7 @@ class WKS(dns.rdata.Rdata):
         protocol, = struct.unpack('!B', wire[current + 4 : current + 5])
         current += 5
         rdlen -= 5
-        bitmap = wire[current : current + rdlen]
+        bitmap = wire[current : current + rdlen].unwrap()
         return cls(rdclass, rdtype, address, protocol, bitmap)
 
     from_wire = classmethod(from_wire)
index aa46403a5f181ac69583cf00eda077a63b8e314c..151c96d377a77e2a72d8ea976b1da24dbb928347 100644 (file)
@@ -76,7 +76,7 @@ class DSBase(dns.rdata.Rdata):
         header = struct.unpack("!HBB", wire[current : current + 4])
         current += 4
         rdlen -= 4
-        digest = wire[current : current + rdlen]
+        digest = wire[current : current + rdlen].unwrap()
         return cls(rdclass, rdtype, header[0], header[1], header[2], digest)
 
     from_wire = classmethod(from_wire)
index 75c9272670bff9c3e002f0bf8b7f881c9e2b6084..100670513869c934569dea2813a823c4cb17a956 100644 (file)
@@ -134,7 +134,7 @@ class KEYBase(dns.rdata.Rdata):
         header = struct.unpack('!HBB', wire[current : current + 4])
         current += 4
         rdlen -= 4
-        key = wire[current : current + rdlen]
+        key = wire[current : current + rdlen].unwrap()
         return cls(rdclass, rdtype, header[0], header[1], header[2],
                    key)
 
index 81ca31e95e3b1d4e99349d926b6e518c91637f1f..b3ffce578ede523ce5f166b3d42b7559fb0956ab 100644 (file)
@@ -141,7 +141,7 @@ class SIGBase(dns.rdata.Rdata):
         rdlen -= cused
         if not origin is None:
             signer = signer.relativize(origin)
-        signature = wire[current : current + rdlen]
+        signature = wire[current : current + rdlen].unwrap()
         return cls(rdclass, rdtype, header[0], header[1], header[2],
                    header[3], header[4], header[5], header[6], signer,
                    signature)
index 43db2a48c0791c407acc403a33d2c12833aee412..b203e8ece9c5362e98426b355dddf40a5b416e58 100644 (file)
@@ -75,7 +75,7 @@ class TXTBase(dns.rdata.Rdata):
             rdlen -= 1
             if l > rdlen:
                 raise dns.exception.FormError
-            s = wire[current : current + l]
+            s = wire[current : current + l].unwrap()
             current += l
             rdlen -= l
             strings.append(s)
diff --git a/dns/wiredata.py b/dns/wiredata.py
new file mode 100644 (file)
index 0000000..86d954a
--- /dev/null
@@ -0,0 +1,59 @@
+# Copyright (C) 2011 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""DNS Wire Data Helper"""
+
+import sys
+
+import dns.exception
+
+class WireData(str):
+    # WireData is a string with stricter slicing
+    def __getitem__(self, key):
+        try:
+            return WireData(super(WireData, self).__getitem__(key))
+        except IndexError:
+            raise dns.exception.FormError
+    def __getslice__(self, i, j):
+        try:
+            if j == sys.maxint:
+                # handle the case where the right bound is unspecified
+                j = len(self)
+            if i < 0 or j < 0:
+                raise dns.exception.FormError
+            # If it's not an empty slice, access left and right bounds
+            # to make sure they're valid
+            if i != j:
+                super(WireData, self).__getitem__(i)
+                super(WireData, self).__getitem__(j - 1)
+            return WireData(super(WireData, self).__getslice__(i, j))
+        except IndexError:
+            raise dns.exception.FormError
+    def __iter__(self):
+        i = 0
+        while 1:
+            try:
+                yield self[i]
+                i += 1
+            except dns.exception.FormError:
+                raise StopIteration
+    def unwrap(self):
+        return str(self)
+
+def maybe_wrap(wire):
+    if not isinstance(wire, WireData):
+        return WireData(wire)
+    else:
+        return wire