diff --git a/lib/dns/qp.c b/lib/dns/qp.c index 4e70fa0dac..dff011ba66 100644 --- a/lib/dns/qp.c +++ b/lib/dns/qp.c @@ -2126,6 +2126,7 @@ fix_iterator(dns_qpreader_t *qp, dns_qpiter_t *iter, dns_qpnode_t *start, dns_qpiter_init(qp, iter); return (prevleaf(iter)); } + /* * As long as the branch offset point is after the point where the * search key differs, we need to branch up and find a better leaf @@ -2139,7 +2140,17 @@ fix_iterator(dns_qpreader_t *qp, dns_qpiter_t *iter, dns_qpnode_t *start, * go to the parent branch and iterate back to the * predecessor from that point. */ - n = prevleaf(iter); + isc_result_t result = dns_qpiter_prev(iter, NULL, NULL, + NULL); + if (result == ISC_R_NOMORE) { + /* + * This was the first domain; move the iterator + * one step back from the origin and return. + */ + return (prevleaf(iter)); + } + RUNTIME_CHECK(result == ISC_R_SUCCESS); + n = iter->stack[iter->sp]; leaf = n; } else { if (is_branch(n)) { diff --git a/tests/dns/qp_test.c b/tests/dns/qp_test.c index b9c3afcc5f..7dc0f68c2a 100644 --- a/tests/dns/qp_test.c +++ b/tests/dns/qp_test.c @@ -777,6 +777,7 @@ ISC_RUN_TEST_IMPL(fixiterator) { "private-dnskey.dynamic.", "rrsig.dynamic.", "txt.dynamic.", + "trailing.", "" }; int i = 0; @@ -786,9 +787,11 @@ ISC_RUN_TEST_IMPL(fixiterator) { } static struct check_predecessors check1[] = { - { "newtext.dynamic.", "mx.dynamic.", DNS_R_PARTIALMATCH, 6 }, - { "absent.", "txt.dynamic.", ISC_R_NOTFOUND, 0 }, - { "nonexistent.", "txt.dynamic.", ISC_R_NOTFOUND, 0 }, + { "newtext.dynamic.", "mx.dynamic.", DNS_R_PARTIALMATCH, 7 }, + { "d.", "trailing.", ISC_R_NOTFOUND, 0 }, + { "absent.", "trailing.", ISC_R_NOTFOUND, 0 }, + { "nonexistent.", "txt.dynamic.", ISC_R_NOTFOUND, 1 }, + { "wayback.", "trailing.", ISC_R_NOTFOUND, 0 }, { NULL, NULL, 0, 0 } };