From f81bf6bafdc3084111e148d2fd6352f28d3b6506 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Tue, 30 Apr 2024 14:23:43 -0700 Subject: [PATCH] handle QP lookups involving escaped characters better in QP keys, characters that are not common in DNS names are encoded as two-octet sequences. this caused a glitch in iterator positioning when some lookups failed. consider the case where we're searching for "\009" (represented in a QP key as {0x03, 0x0c}) and a branch exists for "\000" (represented as {0x03, 0x03}). we match on the 0x03, and continue to search down. at the point where we find we have no match, we need to pop back up to the branch before the 0x03 - which may be multiple levels up the stack - before we position the iterator. --- lib/dns/qp.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/dns/qp.c b/lib/dns/qp.c index 0329f424cb..e8ff8f66a7 100644 --- a/lib/dns/qp.c +++ b/lib/dns/qp.c @@ -2167,7 +2167,21 @@ fix_iterator(dns_qpreader_t *qp, dns_qpiter_t *iter, dns_qpkey_t search, } if (is_branch(n)) { - iter->stack[iter->sp--] = NULL; + /* + * Pop up until we reach a branch that + * differs earlier than the position we're + * looking at. Note that because of escaped + * characters, this might require popping + * more than once. + */ + dns_qpnode_t *last = iter->stack[iter->sp]; + while (iter->sp > 0 && + to < branch_key_offset(last)) + { + n = last; + iter->stack[iter->sp--] = NULL; + last = iter->stack[iter->sp]; + } greatest_leaf(qp, n, iter); }