From 97f54bd629fc97e3a86b0a137539df20df1f8163 Mon Sep 17 00:00:00 2001 From: Bob Halley Date: Fri, 20 May 2016 07:01:27 -0700 Subject: [PATCH] LOC processing lost N/S or E/W info when values were within a degree of the equator or the prime meridian. --- dns/rdtypes/ANY/LOC.py | 59 ++++++++++++++------------------------ tests/example | 2 ++ tests/example1.good | 2 ++ tests/example2.good | 2 ++ tests/example3.good | 2 ++ tests/test_rdtypeanyloc.py | 18 ++++++------ 6 files changed, 40 insertions(+), 45 deletions(-) diff --git a/dns/rdtypes/ANY/LOC.py b/dns/rdtypes/ANY/LOC.py index a4655d88..fbfcd70f 100644 --- a/dns/rdtypes/ANY/LOC.py +++ b/dns/rdtypes/ANY/LOC.py @@ -55,20 +55,15 @@ def _float_to_tuple(what): seconds = int(what // 1000) what -= int(seconds * 1000) what = int(what) - return (degrees * sign, minutes, seconds, what) + return (degrees, minutes, seconds, what, sign) def _tuple_to_float(what): - if what[0] < 0: - sign = -1 - value = float(what[0]) * -1 - else: - sign = 1 - value = float(what[0]) + value = float(what[0]) value += float(what[1]) / 60.0 value += float(what[2]) / 3600.0 value += float(what[3]) / 3600000.0 - return sign * value + return float(what[4]) * value def _encode_size(what, desc): @@ -93,11 +88,11 @@ class LOC(dns.rdata.Rdata): """LOC record @ivar latitude: latitude - @type latitude: (int, int, int, int) tuple specifying the degrees, minutes, - seconds, and milliseconds of the coordinate. + @type latitude: (int, int, int, int, sign) tuple specifying the degrees, minutes, + seconds, milliseconds, and sign of the coordinate. @ivar longitude: longitude - @type longitude: (int, int, int, int) tuple specifying the degrees, - minutes, seconds, and milliseconds of the coordinate. + @type longitude: (int, int, int, int, sign) tuple specifying the degrees, + minutes, seconds, milliseconds, and sign of the coordinate. @ivar altitude: altitude @type altitude: float @ivar size: size of the sphere @@ -139,22 +134,24 @@ class LOC(dns.rdata.Rdata): self.vertical_precision = float(vprec) def to_text(self, origin=None, relativize=True, **kw): - if self.latitude[0] > 0: + if self.latitude[4] > 0: lat_hemisphere = 'N' lat_degrees = self.latitude[0] else: lat_hemisphere = 'S' lat_degrees = -1 * self.latitude[0] - if self.longitude[0] > 0: + if self.longitude[4] > 0: long_hemisphere = 'E' long_degrees = self.longitude[0] else: long_hemisphere = 'W' long_degrees = -1 * self.longitude[0] text = "%d %d %d.%03d %s %d %d %d.%03d %s %0.2fm" % ( - lat_degrees, self.latitude[1], self.latitude[2], self.latitude[3], - lat_hemisphere, long_degrees, self.longitude[1], self.longitude[2], - self.longitude[3], long_hemisphere, self.altitude / 100.0 + self.latitude[0], self.latitude[1], + self.latitude[2], self.latitude[3], lat_hemisphere, + self.longitude[0], self.longitude[1], self.longitude[2], + self.longitude[3], long_hemisphere, + self.altitude / 100.0 ) # do not print default values @@ -169,8 +166,8 @@ class LOC(dns.rdata.Rdata): @classmethod def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): - latitude = [0, 0, 0, 0] - longitude = [0, 0, 0, 0] + latitude = [0, 0, 0, 0, 1] + longitude = [0, 0, 0, 0, 1] size = _default_size hprec = _default_hprec vprec = _default_vprec @@ -204,7 +201,7 @@ class LOC(dns.rdata.Rdata): latitude[2] = int(t) t = tok.get_string() if t == 'S': - latitude[0] *= -1 + latitude[4] = -1 elif t != 'N': raise dns.exception.SyntaxError('bad latitude hemisphere value') @@ -237,7 +234,7 @@ class LOC(dns.rdata.Rdata): longitude[2] = int(t) t = tok.get_string() if t == 'W': - longitude[0] *= -1 + longitude[4] = -1 elif t != 'E': raise dns.exception.SyntaxError('bad longitude hemisphere value') @@ -270,27 +267,15 @@ class LOC(dns.rdata.Rdata): size, hprec, vprec) def to_wire(self, file, compress=None, origin=None): - if self.latitude[0] < 0: - sign = -1 - degrees = long(-1 * self.latitude[0]) - else: - sign = 1 - degrees = long(self.latitude[0]) - milliseconds = (degrees * 3600000 + + milliseconds = (self.latitude[0] * 3600000 + self.latitude[1] * 60000 + self.latitude[2] * 1000 + - self.latitude[3]) * sign + self.latitude[3]) * self.latitude[4] latitude = long(0x80000000) + milliseconds - if self.longitude[0] < 0: - sign = -1 - degrees = long(-1 * self.longitude[0]) - else: - sign = 1 - degrees = long(self.longitude[0]) - milliseconds = (degrees * 3600000 + + milliseconds = (self.longitude[0] * 3600000 + self.longitude[1] * 60000 + self.longitude[2] * 1000 + - self.longitude[3]) * sign + self.longitude[3]) * self.longitude[4] longitude = long(0x80000000) + milliseconds altitude = long(self.altitude) + long(10000000) size = _encode_size(self.size, "size") diff --git a/tests/example b/tests/example index b4ad6068..378f23ee 100644 --- a/tests/example +++ b/tests/example @@ -119,6 +119,8 @@ loc02 LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20m 2000m 20m loc03 LOC 60 9 0.000 N 24 39 0.000 E 10.00m 90000000.00m 2000m 20m loc04 LOC 60 9 1.5 N 24 39 0.000 E 10.00m 20m 2000m 20m loc05 LOC 60 9 1.51 N 24 39 0.000 E 10.00m 20m 2000m 20m +loc06 LOC 0 9 1.51 N 0 39 0.000 E 10.00m 20m 2000m 20m +loc07 LOC 0 9 1.51 S 0 39 0.000 W 10.00m 20m 2000m 20m ;; ;; XXXRTH These are all obsolete and unused. dnspython doesn't implement ;; them diff --git a/tests/example1.good b/tests/example1.good index 1eef90b3..ec8c96c5 100644 --- a/tests/example1.good +++ b/tests/example1.good @@ -66,6 +66,8 @@ loc02 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m loc03 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 90000000.00m 2000.00m 20.00m loc04 3600 IN LOC 60 9 1.500 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m loc05 3600 IN LOC 60 9 1.510 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +loc06 3600 IN LOC 0 9 1.510 N 0 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +loc07 3600 IN LOC 0 9 1.510 S 0 39 0.000 W 10.00m 20.00m 2000.00m 20.00m mx01 3600 IN MX 10 mail mx02 3600 IN MX 10 . naptr01 3600 IN NAPTR 0 0 "" "" "" . diff --git a/tests/example2.good b/tests/example2.good index 2a105062..e3f1890a 100644 --- a/tests/example2.good +++ b/tests/example2.good @@ -66,6 +66,8 @@ loc02.example. 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20. loc03.example. 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 90000000.00m 2000.00m 20.00m loc04.example. 3600 IN LOC 60 9 1.500 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m loc05.example. 3600 IN LOC 60 9 1.510 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +loc06.example. 3600 IN LOC 0 9 1.510 N 0 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +loc07.example. 3600 IN LOC 0 9 1.510 S 0 39 0.000 W 10.00m 20.00m 2000.00m 20.00m mx01.example. 3600 IN MX 10 mail.example. mx02.example. 3600 IN MX 10 . naptr01.example. 3600 IN NAPTR 0 0 "" "" "" . diff --git a/tests/example3.good b/tests/example3.good index 1eef90b3..ec8c96c5 100644 --- a/tests/example3.good +++ b/tests/example3.good @@ -66,6 +66,8 @@ loc02 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m loc03 3600 IN LOC 60 9 0.000 N 24 39 0.000 E 10.00m 90000000.00m 2000.00m 20.00m loc04 3600 IN LOC 60 9 1.500 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m loc05 3600 IN LOC 60 9 1.510 N 24 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +loc06 3600 IN LOC 0 9 1.510 N 0 39 0.000 E 10.00m 20.00m 2000.00m 20.00m +loc07 3600 IN LOC 0 9 1.510 S 0 39 0.000 W 10.00m 20.00m 2000.00m 20.00m mx01 3600 IN MX 10 mail mx02 3600 IN MX 10 . naptr01 3600 IN NAPTR 0 0 "" "" "" . diff --git a/tests/test_rdtypeanyloc.py b/tests/test_rdtypeanyloc.py index 5cd8c70a..43fa4932 100644 --- a/tests/test_rdtypeanyloc.py +++ b/tests/test_rdtypeanyloc.py @@ -35,10 +35,12 @@ class RdtypeAnyLocTestCase(unittest.TestCase): def testEqual2(self): '''Test default values for size, horizontal and vertical precision.''' - r1 = dns.rdtypes.ANY.LOC.LOC(1, 29, (49, 11, 42, 400), - (16, 36, 29, 600), 22764.0) # centimeters - r2 = dns.rdtypes.ANY.LOC.LOC(1, 29, (49, 11, 42, 400), - (16, 36, 29, 600), 22764.0, # centimeters + r1 = dns.rdtypes.ANY.LOC.LOC(1, 29, (49, 11, 42, 400, 1), + (16, 36, 29, 600, 1), + 22764.0) # centimeters + r2 = dns.rdtypes.ANY.LOC.LOC(1, 29, (49, 11, 42, 400, 1), + (16, 36, 29, 600, 1), + 22764.0, # centimeters 100.0, 1000000.00, 1000.0) # centimeters self.failUnless(r1 == r2, '"%s" != "%s"' % (r1, r2)) @@ -46,8 +48,8 @@ class RdtypeAnyLocTestCase(unittest.TestCase): '''Test size, horizontal and vertical precision parsers: 100 cm == 1 m. Parsers in from_text() and __init__() have to produce equal results.''' - r1 = dns.rdtypes.ANY.LOC.LOC(1, 29, (49, 11, 42, 400), - (16, 36, 29, 600), 22764.0, + r1 = dns.rdtypes.ANY.LOC.LOC(1, 29, (49, 11, 42, 400, 1), + (16, 36, 29, 600, 1), 22764.0, 200.0, 1000.00, 200.0) # centimeters r2 = dns.rrset.from_text('FOO', 600, 'in', 'loc', '49 11 42.400 N 16 36 29.600 E 227.64m ' @@ -59,8 +61,8 @@ class RdtypeAnyLocTestCase(unittest.TestCase): Parsers in from_text() and __init__() have produce equal result for values with and without trailing "m".''' - r1 = dns.rdtypes.ANY.LOC.LOC(1, 29, (49, 11, 42, 400), - (16, 36, 29, 600), 22764.0, + r1 = dns.rdtypes.ANY.LOC.LOC(1, 29, (49, 11, 42, 400, 1), + (16, 36, 29, 600, 1), 22764.0, 200.0, 1000.00, 200.0) # centimeters r2 = dns.rrset.from_text('FOO', 600, 'in', 'loc', '49 11 42.400 N 16 36 29.600 E 227.64 ' -- 2.47.3