From 11485861f6cfcd762871f903bd68a798089f0697 Mon Sep 17 00:00:00 2001 From: Bob Halley Date: Thu, 28 May 2020 06:03:54 -0700 Subject: [PATCH] Fix resolve() NoAnswer problems from [Issue #488] --- dns/resolver.py | 16 ++++++++++++---- dns/trio/resolver.py | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/dns/resolver.py b/dns/resolver.py index 20356685..f9dbd641 100644 --- a/dns/resolver.py +++ b/dns/resolver.py @@ -1056,7 +1056,11 @@ class Resolver(object): start = time.time() while True: (request, answer) = resolution.next_request() - if answer: + # Note we need to say "if answer is not None" and not just + # "if answer" because answer implements __len__, and python + # will call that. We want to return if we have an answer + # object, including in cases where its length is 0. + if answer is not None: # cache hit! return answer done = False @@ -1088,11 +1092,15 @@ class Resolver(object): timeout=timeout) elif protocol: continue - (answer, done) = resolution.query_result(response, None) - if answer: - return answer except Exception as ex: (_, done) = resolution.query_result(None, ex) + (answer, done) = resolution.query_result(response, None) + # Note we need to say "if answer is not None" and not just + # "if answer" because answer implements __len__, and python + # will call that. We want to return if we have an answer + # object, including in cases where its length is 0. + if answer is not None: + return answer def query(self, qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN, tcp=False, source=None, raise_on_no_answer=True, source_port=0, diff --git a/dns/trio/resolver.py b/dns/trio/resolver.py index f9cdfeac..4551857c 100644 --- a/dns/trio/resolver.py +++ b/dns/trio/resolver.py @@ -89,7 +89,11 @@ class Resolver(dns.resolver.Resolver): raise_on_no_answer, search) while True: (request, answer) = resolution.next_request() - if answer: + # Note we need to say "if answer is not None" and not just + # "if answer" because answer implements __len__, and python + # will call that. We want to return if we have an answer + # object, including in cases where its length is 0. + if answer is not None: # cache hit! return answer loops = 1 @@ -121,11 +125,15 @@ class Resolver(dns.resolver.Resolver): else: # We don't do DoH yet. raise NotImplementedError - (answer, done) = resolution.query_result(response, None) - if answer: - return answer except Exception as ex: (_, done) = resolution.query_result(None, ex) + (answer, done) = resolution.query_result(response, None) + # Note we need to say "if answer is not None" and not just + # "if answer" because answer implements __len__, and python + # will call that. We want to return if we have an answer + # object, including in cases where its length is 0. + if answer is not None: + return answer async def query(self, *args, **kwargs): # We have to define something here as we don't want to inherit the -- 2.47.3