]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
handle QP lookups involving escaped characters better
authorEvan Hunt <each@isc.org>
Tue, 30 Apr 2024 21:23:43 +0000 (14:23 -0700)
committerEvan Hunt <each@isc.org>
Wed, 1 May 2024 07:36:51 +0000 (00:36 -0700)
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

index 0329f424cb9caae6cdb5f0168a3df8340db5f1bc..e8ff8f66a7828d37f6717694b0f83ccd36f5d683 100644 (file)
@@ -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);
                        }