raise dns.exception.SyntaxError, "bad algorithm type"
chunks = []
while 1:
- t = tok.get()
+ t = tok.get().unescape()
if t.is_eol_or_eof():
break
if not t.is_identifier():
t = t[0 : -1]
altitude = float(t) * 100.0 # m -> cm
- token = tok.get()
+ token = tok.get().unescape()
if not token.is_eol_or_eof():
value = token.value
if value[-1] == 'm':
value = value[0 : -1]
size = float(value) * 100.0 # m -> cm
- token = tok.get()
+ token = tok.get().unescape()
if not token.is_eol_or_eof():
value = token.value
if value[-1] == 'm':
value = value[0 : -1]
hprec = float(value) * 100.0 # m -> cm
- token = tok.get()
+ token = tok.get().unescape()
if not token.is_eol_or_eof():
value = token.value
if value[-1] == 'm':
next = next.choose_relativity(origin, relativize)
rdtypes = []
while 1:
- token = tok.get()
+ token = tok.get().unescape()
if token.is_eol_or_eof():
break
nrdtype = dns.rdatatype.from_text(token.value)
next = base64.b32decode(next)
rdtypes = []
while 1:
- token = tok.get()
+ token = tok.get().unescape()
if token.is_eol_or_eof():
break
nrdtype = dns.rdatatype.from_text(token.value)
'\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00' ]
while 1:
- token = tok.get()
+ token = tok.get().unescape()
if token.is_eol_or_eof():
break
if token.value.isdigit():
def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
items = []
while 1:
- token = tok.get()
+ token = tok.get().unescape()
if token.is_eol_or_eof():
break
item = token.value
def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
chunks = []
while 1:
- t = tok.get()
+ t = tok.get().unescape()
if t.is_eol_or_eof():
break
if not t.is_identifier():
gateway = tok.get_string()
chunks = []
while 1:
- t = tok.get()
+ t = tok.get().unescape()
if t.is_eol_or_eof():
break
if not t.is_identifier():
key = b64.decode('base64_codec')
return cls(rdclass, rdtype, precedence, gateway_type, algorithm,
gateway, key)
-
+
from_text = classmethod(from_text)
def to_wire(self, file, compress = None, origin = None):
else:
raise ValueError, 'invalid gateway type'
file.write(self.key)
-
+
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
if rdlen < 3:
raise dns.exception.FormError
other.to_wire(f)
wire2 = f.getvalue()
f.close()
-
+
return cmp(wire1, wire2)
protocol = socket.getprotobyname(protocol)
bitmap = []
while 1:
- token = tok.get()
+ token = tok.get().unescape()
if token.is_eol_or_eof():
break
if token.value.isdigit():
digest_type = tok.get_uint8()
chunks = []
while 1:
- t = tok.get()
+ t = tok.get().unescape()
if t.is_eol_or_eof():
break
if not t.is_identifier():
algorithm = dns.dnssec.algorithm_from_text(tok.get_string())
chunks = []
while 1:
- t = tok.get()
+ t = tok.get().unescape()
if t.is_eol_or_eof():
break
if not t.is_identifier():
signer = signer.choose_relativity(origin, relativize)
chunks = []
while 1:
- t = tok.get()
+ t = tok.get().unescape()
if t.is_eol_or_eof():
break
if not t.is_identifier():
def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
strings = []
while 1:
- token = tok.get()
+ token = tok.get().unescape()
if token.is_eol_or_eof():
break
if not (token.is_quoted_string() or token.is_identifier()):
@type ttype: int
@ivar value: The token value
@type value: string
+ @ivar has_escape: Does the token value contain escapes?
+ @type has_escape: bool
"""
def __init__(self, ttype, value='', has_escape=False):
def __str__(self):
return '%d "%s"' % (self.ttype, self.value)
+ def unescape(self):
+ if not self.has_escape:
+ return self
+ unescaped = ''
+ l = len(self.value)
+ i = 0
+ while i < l:
+ c = self.value[i]
+ i += 1
+ if c == '\\':
+ if i >= l:
+ raise dns.exception.UnexpectedEnd
+ c = self.value[i]
+ i += 1
+ if c.isdigit():
+ if i >= l:
+ raise dns.exception.UnexpectedEnd
+ c2 = self.value[i]
+ i += 1
+ if i >= l:
+ raise dns.exception.UnexpectedEnd
+ c3 = self.value[i]
+ i += 1
+ if not (c2.isdigit() and c3.isdigit()):
+ raise dns.exception.SyntaxError
+ c = chr(int(c) * 100 + int(c2) * 10 + int(c3))
+ unescaped += c
+ return Token(self.ttype, unescaped)
+
class Tokenizer(object):
"""A DNS master file format tokenizer.
return Token(WHITESPACE, ' ')
token = ''
ttype = IDENTIFIER
+ has_escape = False
while True:
c = self._get_char()
if c == '' or c in self.delimiters:
raise dns.exception.SyntaxError, 'newline in quoted string'
elif c == '\\':
#
- # Treat \ followed by a delimiter as the
- # delimiter, otherwise leave it alone.
+ # It's an escape. Put it and the next character into
+ # the token; it will be checked later for goodness.
#
+ token += c
+ has_escape = True
c = self._get_char()
- if c == '' or not c in self.delimiters:
- self._unget_char(c)
- c = '\\'
+ if c == '' or c == '\n':
+ raise dns.exception.UnexpectedEnd
token += c
if token == '' and ttype != QUOTED_STRING:
if self.multiline:
@rtype: int
"""
- token = self.get()
+ token = self.get().unescape()
if not token.is_identifier():
raise dns.exception.SyntaxError, 'expecting an identifier'
if not token.value.isdigit():
@rtype: int
"""
- token = self.get()
+ token = self.get().unescape()
if not token.is_identifier():
raise dns.exception.SyntaxError, 'expecting an identifier'
if not token.value.isdigit():
@rtype: string
"""
- token = self.get()
+ token = self.get().unescape()
if not (token.is_identifier() or token.is_quoted_string()):
raise dns.exception.SyntaxError, 'expecting a string'
return token.value
@rtype: string
"""
- token = self.get()
+ token = self.get().unescape()
if not token.is_identifier():
raise dns.exception.SyntaxError, 'expecting an identifier'
return token.value
return token.value
def get_ttl(self):
- token = self.get()
+ token = self.get().unescape()
if not token.is_identifier():
raise dns.exception.SyntaxError, 'expecting an identifier'
return dns.ttl.from_text(token.value)
try:
while 1:
- token = self.tok.get(True, True)
+ token = self.tok.get(True, True).unescape()
if token.is_eof():
if not self.current_file is None:
self.current_file.close()
def testEscapedDelimiter1(self):
tok = dns.tokenizer.Tokenizer(r'ch\ ld')
t = tok.get()
- self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch ld')
+ self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\ ld')
def testEscapedDelimiter2(self):
tok = dns.tokenizer.Tokenizer(r'ch\0ld')
t = tok.get()
self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\0ld')
+ def testEscapedDelimiter3(self):
+ tok = dns.tokenizer.Tokenizer(r'ch\032ld')
+ t = tok.get()
+ self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\032ld')
+
+ def testEscapedDelimiter1u(self):
+ tok = dns.tokenizer.Tokenizer(r'ch\ ld')
+ t = tok.get().unescape()
+ self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\ ld')
+
+ def testEscapedDelimiter2u(self):
+ tok = dns.tokenizer.Tokenizer(r'ch\0ld')
+ t = tok.get().unescape()
+ self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\0ld')
+
+ def testEscapedDelimiter3u(self):
+ tok = dns.tokenizer.Tokenizer(r'ch\032ld')
+ t = tok.get().unescape()
+ self.failUnless(t.ttype == dns.tokenizer.IDENTIFIER and t.value == r'ch\032ld')
+
if __name__ == '__main__':
unittest.main()