mirror of
https://github.com/isar/libmdbx.git
synced 2024-12-30 03:44:13 +08:00
mdbx: add checks for unexpected LEAF2-pages.
The fourth case of https://github.com/erthink/libmdbx/issues/217.
This commit is contained in:
parent
68aef96f0a
commit
e7336e1d5e
58
src/core.c
58
src/core.c
@ -13666,7 +13666,11 @@ skip:
|
||||
return MDBX_CORRUPTED;
|
||||
|
||||
if (IS_LEAF2(mp)) {
|
||||
if (likely(key)) {
|
||||
if (!MDBX_DISABLE_PAGECHECKS && unlikely((mc->mc_flags & C_SUB) == 0)) {
|
||||
mdbx_error("unexpected LEAF2-page %" PRIaPGNO "for non-dupsort cursor",
|
||||
mp->mp_pgno);
|
||||
return MDBX_CORRUPTED;
|
||||
} else if (likely(key)) {
|
||||
key->iov_len = mc->mc_db->md_xsize;
|
||||
key->iov_base = page_leaf2key(mp, mc->mc_ki[mc->mc_top], key->iov_len);
|
||||
}
|
||||
@ -13756,7 +13760,11 @@ static int mdbx_cursor_prev(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
||||
return MDBX_CORRUPTED;
|
||||
|
||||
if (IS_LEAF2(mp)) {
|
||||
if (likely(key)) {
|
||||
if (!MDBX_DISABLE_PAGECHECKS && unlikely((mc->mc_flags & C_SUB) == 0)) {
|
||||
mdbx_error("unexpected LEAF2-page %" PRIaPGNO "for non-dupsort cursor",
|
||||
mp->mp_pgno);
|
||||
return MDBX_CORRUPTED;
|
||||
} else if (likely(key)) {
|
||||
key->iov_len = mc->mc_db->md_xsize;
|
||||
key->iov_base = page_leaf2key(mp, mc->mc_ki[mc->mc_top], key->iov_len);
|
||||
}
|
||||
@ -13974,11 +13982,17 @@ got_node:
|
||||
mc->mc_flags &= ~C_EOF;
|
||||
|
||||
if (IS_LEAF2(mp)) {
|
||||
if (op == MDBX_SET_RANGE || op == MDBX_SET_KEY) {
|
||||
key->iov_len = mc->mc_db->md_xsize;
|
||||
key->iov_base = page_leaf2key(mp, mc->mc_ki[mc->mc_top], key->iov_len);
|
||||
if (!MDBX_DISABLE_PAGECHECKS && unlikely((mc->mc_flags & C_SUB) == 0)) {
|
||||
mdbx_error("unexpected LEAF2-page %" PRIaPGNO "for non-dupsort cursor",
|
||||
mp->mp_pgno);
|
||||
ret.err = MDBX_CORRUPTED;
|
||||
} else {
|
||||
if (op == MDBX_SET_RANGE || op == MDBX_SET_KEY) {
|
||||
key->iov_len = mc->mc_db->md_xsize;
|
||||
key->iov_base = page_leaf2key(mp, mc->mc_ki[mc->mc_top], key->iov_len);
|
||||
}
|
||||
ret.err = MDBX_SUCCESS;
|
||||
}
|
||||
ret.err = MDBX_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -14081,7 +14095,11 @@ static int mdbx_cursor_first(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data) {
|
||||
mc->mc_ki[mc->mc_top] = 0;
|
||||
|
||||
if (IS_LEAF2(mc->mc_pg[mc->mc_top])) {
|
||||
if (likely(key)) {
|
||||
if (!MDBX_DISABLE_PAGECHECKS && unlikely((mc->mc_flags & C_SUB) == 0)) {
|
||||
mdbx_error("unexpected LEAF2-page %" PRIaPGNO "for non-dupsort cursor",
|
||||
mc->mc_pg[mc->mc_top]->mp_pgno);
|
||||
return MDBX_CORRUPTED;
|
||||
} else if (likely(key)) {
|
||||
key->iov_len = mc->mc_db->md_xsize;
|
||||
key->iov_base = page_leaf2key(mc->mc_pg[mc->mc_top], 0, key->iov_len);
|
||||
}
|
||||
@ -14128,7 +14146,11 @@ static int mdbx_cursor_last(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data) {
|
||||
mc->mc_flags |= C_INITIALIZED | C_EOF;
|
||||
|
||||
if (IS_LEAF2(mc->mc_pg[mc->mc_top])) {
|
||||
if (likely(key)) {
|
||||
if (!MDBX_DISABLE_PAGECHECKS && unlikely((mc->mc_flags & C_SUB) == 0)) {
|
||||
mdbx_error("unexpected LEAF2-page %" PRIaPGNO "for non-dupsort cursor",
|
||||
mc->mc_pg[mc->mc_top]->mp_pgno);
|
||||
return MDBX_CORRUPTED;
|
||||
} else if (likely(key)) {
|
||||
key->iov_len = mc->mc_db->md_xsize;
|
||||
key->iov_base = page_leaf2key(mc->mc_pg[mc->mc_top],
|
||||
mc->mc_ki[mc->mc_top], key->iov_len);
|
||||
@ -14186,6 +14208,11 @@ int mdbx_cursor_get(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
||||
|
||||
rc = MDBX_SUCCESS;
|
||||
if (IS_LEAF2(mp)) {
|
||||
if (!MDBX_DISABLE_PAGECHECKS && unlikely((mc->mc_flags & C_SUB) == 0)) {
|
||||
mdbx_error("unexpected LEAF2-page %" PRIaPGNO "for non-dupsort cursor",
|
||||
mp->mp_pgno);
|
||||
return MDBX_CORRUPTED;
|
||||
}
|
||||
key->iov_len = mc->mc_db->md_xsize;
|
||||
key->iov_base = page_leaf2key(mp, mc->mc_ki[mc->mc_top], key->iov_len);
|
||||
} else {
|
||||
@ -15239,8 +15266,14 @@ int mdbx_cursor_del(MDBX_cursor *mc, MDBX_put_flags_t flags) {
|
||||
MDBX_page *mp = mc->mc_pg[mc->mc_top];
|
||||
if (!MDBX_DISABLE_PAGECHECKS && unlikely(!IS_LEAF(mp)))
|
||||
return MDBX_CORRUPTED;
|
||||
if (IS_LEAF2(mp))
|
||||
if (IS_LEAF2(mp)) {
|
||||
if (!MDBX_DISABLE_PAGECHECKS && unlikely((mc->mc_flags & C_SUB) == 0)) {
|
||||
mdbx_error("unexpected LEAF2-page %" PRIaPGNO "for non-dupsort cursor",
|
||||
mp->mp_pgno);
|
||||
return MDBX_CORRUPTED;
|
||||
}
|
||||
goto del_key;
|
||||
}
|
||||
|
||||
MDBX_node *node = page_node(mp, mc->mc_ki[mc->mc_top]);
|
||||
if (F_ISSET(node_flags(node), F_DUPDATA)) {
|
||||
@ -17065,6 +17098,10 @@ __cold static int mdbx_page_check(MDBX_cursor *const mc,
|
||||
if (unlikely(mp->mp_pgno + mp->mp_pages > mc->mc_txn->mt_next_pgno))
|
||||
return bad_page(mp, "overflow page beyond (%u) next-pgno\n",
|
||||
mp->mp_pgno + mp->mp_pages);
|
||||
if (unlikely(mc->mc_db->md_flags & MDBX_DUPSORT))
|
||||
return bad_page(mp,
|
||||
"unexpected overflow-page for dupsort db (flags 0x%x)\n",
|
||||
mc->mc_db->md_flags);
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
@ -17073,6 +17110,9 @@ __cold static int mdbx_page_check(MDBX_cursor *const mc,
|
||||
if (unlikely(nkeys < 2 && IS_BRANCH(mp)))
|
||||
rc = bad_page(mp, "branch-page nkey (%u) < 2\n", nkeys);
|
||||
}
|
||||
if (IS_LEAF2(mp) && unlikely((mc->mc_flags & C_SUB) == 0))
|
||||
rc = bad_page(mp, "unexpected leaf2-page (db flags 0x%x)\n",
|
||||
mc->mc_db->md_flags);
|
||||
|
||||
MDBX_val here, prev = {0, 0};
|
||||
for (unsigned i = 0; i < nkeys; ++i) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user