n = iter->stack[iter->sp];
leaf = n;
} else {
+ if (to <= searchlen && to <= foundlen && iter->sp > 0) {
+ /*
+ * If we're here, search[to] >= found[to],
+ * meaning every leaf in this set of twigs
+ * is less than the one we wanted. It's
+ * possible we're already positioned at
+ * the correct predecessor, but it's not
+ * guaranteed, so we pop up to the parent
+ * branch, and find the greatest leaf from
+ * there.
+ */
+ if (!is_branch(n)) {
+ iter->stack[iter->sp--] = NULL;
+ n = iter->stack[iter->sp];
+ }
+ }
+
if (is_branch(n)) {
- iter->sp--;
+ iter->stack[iter->sp--] = NULL;
n = greatest_leaf(qp, n, iter);
}
return (n);
}
foundlen = leaf_qpkey(qp, leaf, found);
- to = qpkey_compare(search, searchlen, found, foundlen);
+
+ size_t nto = qpkey_compare(search, searchlen, found, foundlen);
+ if (nto < to) {
+ /*
+ * We've moved to a new leaf and it differs at an
+ * even earlier point, so no further improvement is
+ * possible.
+ */
+ return (leaf);
+ }
+ to = nto;
}
if (is_branch(n)) {
*/
n = fix_iterator(qp, iter, n, search, searchlen, bit,
offset);
- iter->stack[iter->sp] = NULL;
- iter->sp--;
+ iter->stack[iter->sp--] = NULL;
} else {
/*
* this branch is a dead end, and the predecessor
*/
ISC_RUN_TEST_IMPL(fixiterator) {
dns_qp_t *qp = NULL;
- const char insert[][32] = { "dynamic.",
- "a.dynamic.",
- "aaaa.dynamic.",
- "cdnskey.dynamic.",
- "cds.dynamic.",
- "cname.dynamic.",
- "dname.dynamic.",
- "dnskey.dynamic.",
- "ds.dynamic.",
- "mx.dynamic.",
- "ns.dynamic.",
- "nsec.dynamic.",
- "private-cdnskey.dynamic.",
- "private-dnskey.dynamic.",
- "rrsig.dynamic.",
- "txt.dynamic.",
- "trailing.",
- "" };
+ const char insert1[][32] = { "dynamic.",
+ "a.dynamic.",
+ "aaaa.dynamic.",
+ "cdnskey.dynamic.",
+ "cds.dynamic.",
+ "cname.dynamic.",
+ "dname.dynamic.",
+ "dnskey.dynamic.",
+ "ds.dynamic.",
+ "mx.dynamic.",
+ "ns.dynamic.",
+ "nsec.dynamic.",
+ "private-cdnskey.dynamic.",
+ "private-dnskey.dynamic.",
+ "rrsig.dynamic.",
+ "txt.dynamic.",
+ "trailing.",
+ "" };
int i = 0;
dns_qp_create(mctx, &string_methods, NULL, &qp);
- while (insert[i][0] != '\0') {
- insert_str(qp, insert[i++]);
+ while (insert1[i][0] != '\0') {
+ insert_str(qp, insert1[i++]);
}
static struct check_predecessors check1[] = {
};
check_predecessors(qp, check1);
+ dns_qp_destroy(&qp);
+
+ const char insert2[][64] = { ".", "abb.", "abc.", "" };
+ i = 0;
+
+ dns_qp_create(mctx, &string_methods, NULL, &qp);
+ while (insert2[i][0] != '\0') {
+ insert_str(qp, insert2[i++]);
+ }
+
+ static struct check_predecessors check2[] = {
+ { "acb.", "abc.", DNS_R_PARTIALMATCH, 0 },
+ { "acc.", "abc.", DNS_R_PARTIALMATCH, 0 },
+ { "abbb.", "abb.", DNS_R_PARTIALMATCH, 1 },
+ { "aab.", ".", DNS_R_PARTIALMATCH, 2 },
+ { NULL, NULL, 0, 0 }
+ };
+ check_predecessors(qp, check2);
dns_qp_destroy(&qp);
}