mdbx: more runtime checks/errors instead of assertions.

Change-Id: I843f28b7faeb23f986154dd92a0e2b50d66a1dde
This commit is contained in:
Leonid Yuriev 2020-09-02 21:52:52 +03:00
parent a758e32f91
commit 6867c13bd1

View File

@ -3105,7 +3105,7 @@ static int __must_check_result mdbx_page_get(MDBX_cursor *mc, pgno_t pgno,
const txnid_t pp_txnid); const txnid_t pp_txnid);
static int __must_check_result mdbx_page_search_root(MDBX_cursor *mc, static int __must_check_result mdbx_page_search_root(MDBX_cursor *mc,
const MDBX_val *key, const MDBX_val *key,
int modify); int flags);
#define MDBX_PS_MODIFY 1 #define MDBX_PS_MODIFY 1
#define MDBX_PS_ROOTONLY 2 #define MDBX_PS_ROOTONLY 2
@ -3202,7 +3202,7 @@ static int __must_check_result mdbx_xcursor_init1(MDBX_cursor *mc,
const MDBX_page *mp); const MDBX_page *mp);
static int __must_check_result mdbx_xcursor_init2(MDBX_cursor *mc, static int __must_check_result mdbx_xcursor_init2(MDBX_cursor *mc,
MDBX_xcursor *src_mx, MDBX_xcursor *src_mx,
int force); bool new_dupdata);
static void mdbx_cursor_copy(const MDBX_cursor *csrc, MDBX_cursor *cdst); static void mdbx_cursor_copy(const MDBX_cursor *csrc, MDBX_cursor *cdst);
static int __must_check_result mdbx_drop0(MDBX_cursor *mc, int subs); static int __must_check_result mdbx_drop0(MDBX_cursor *mc, int subs);
@ -11466,6 +11466,9 @@ skip:
" with %u keys, key index %u", " with %u keys, key index %u",
mp->mp_pgno, page_numkeys(mp), mc->mc_ki[mc->mc_top]); mp->mp_pgno, page_numkeys(mp), mc->mc_ki[mc->mc_top]);
if (unlikely(!IS_LEAF(mp)))
return MDBX_CORRUPTED;
if (IS_LEAF2(mp)) { if (IS_LEAF2(mp)) {
if (likely(key)) { if (likely(key)) {
key->iov_len = mc->mc_db->md_xsize; key->iov_len = mc->mc_db->md_xsize;
@ -11474,9 +11477,7 @@ skip:
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
mdbx_cassert(mc, IS_LEAF(mp));
node = page_node(mp, mc->mc_ki[mc->mc_top]); node = page_node(mp, mc->mc_ki[mc->mc_top]);
if (F_ISSET(node_flags(node), F_DUPDATA)) { if (F_ISSET(node_flags(node), F_DUPDATA)) {
rc = mdbx_xcursor_init1(mc, node, mp); rc = mdbx_xcursor_init1(mc, node, mp);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
@ -11849,7 +11850,9 @@ static int mdbx_cursor_first(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data) {
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
} }
mdbx_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top]));
if (unlikely(!IS_LEAF(mc->mc_pg[mc->mc_top])))
return MDBX_CORRUPTED;
mc->mc_flags |= C_INITIALIZED; mc->mc_flags |= C_INITIALIZED;
mc->mc_flags &= ~C_EOF; mc->mc_flags &= ~C_EOF;
@ -11895,9 +11898,11 @@ static int mdbx_cursor_last(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data) {
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
} }
mdbx_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top]));
} }
if (unlikely(!IS_LEAF(mc->mc_pg[mc->mc_top])))
return MDBX_CORRUPTED;
mc->mc_ki[mc->mc_top] = (indx_t)page_numkeys(mc->mc_pg[mc->mc_top]) - 1; mc->mc_ki[mc->mc_top] = (indx_t)page_numkeys(mc->mc_pg[mc->mc_top]) - 1;
mc->mc_flags |= C_INITIALIZED | C_EOF; mc->mc_flags |= C_INITIALIZED | C_EOF;
@ -13188,7 +13193,7 @@ static int __must_check_result mdbx_node_add_leaf(MDBX_cursor *mc,
mdbx_cassert(mc, PAGETYPE(mp) == P_LEAF); mdbx_cassert(mc, PAGETYPE(mp) == P_LEAF);
MDBX_page *largepage = NULL; MDBX_page *largepage = NULL;
size_t leaf_bytes = 0; size_t leaf_bytes;
if (unlikely(flags & F_BIGDATA)) { if (unlikely(flags & F_BIGDATA)) {
/* Data already on overflow page. */ /* Data already on overflow page. */
STATIC_ASSERT(sizeof(pgno_t) % 2 == 0); STATIC_ASSERT(sizeof(pgno_t) % 2 == 0);
@ -13197,7 +13202,10 @@ static int __must_check_result mdbx_node_add_leaf(MDBX_cursor *mc,
/* See note inside leaf_size() */ /* See note inside leaf_size() */
mc->mc_txn->mt_env->me_branch_nodemax)) { mc->mc_txn->mt_env->me_branch_nodemax)) {
/* Put data on overflow page. */ /* Put data on overflow page. */
mdbx_cassert(mc, !F_ISSET(mc->mc_db->md_flags, MDBX_DUPSORT)); mdbx_ensure(mc->mc_txn->mt_env,
!F_ISSET(mc->mc_db->md_flags, MDBX_DUPSORT));
if (unlikely(flags & (F_DUPDATA | F_SUBDATA)))
return MDBX_PROBLEM;
const pgno_t ovpages = number_of_ovpages(mc->mc_txn->mt_env, data->iov_len); const pgno_t ovpages = number_of_ovpages(mc->mc_txn->mt_env, data->iov_len);
int rc = mdbx_page_new(mc, P_OVERFLOW, ovpages, &largepage); int rc = mdbx_page_new(mc, P_OVERFLOW, ovpages, &largepage);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
@ -13426,7 +13434,12 @@ static int mdbx_xcursor_init1(MDBX_cursor *mc, MDBX_node *node,
return MDBX_CORRUPTED; return MDBX_CORRUPTED;
} }
if (node_flags(node) & F_SUBDATA) { const uint8_t flags = node_flags(node);
switch (flags) {
default:
mdbx_error("invalid node flags %u", flags);
return MDBX_CORRUPTED;
case F_DUPDATA | F_SUBDATA:
if (unlikely(node_ds(node) != sizeof(MDBX_db))) { if (unlikely(node_ds(node) != sizeof(MDBX_db))) {
mdbx_error("invalid nested-db record size %zu", node_ds(node)); mdbx_error("invalid nested-db record size %zu", node_ds(node));
return MDBX_CORRUPTED; return MDBX_CORRUPTED;
@ -13443,7 +13456,8 @@ static int mdbx_xcursor_init1(MDBX_cursor *mc, MDBX_node *node,
mx->mx_cursor.mc_snum = 0; mx->mx_cursor.mc_snum = 0;
mx->mx_cursor.mc_top = 0; mx->mx_cursor.mc_top = 0;
mx->mx_cursor.mc_flags = C_SUB | (mc->mc_flags & (C_COPYING | C_SKIPORD)); mx->mx_cursor.mc_flags = C_SUB | (mc->mc_flags & (C_COPYING | C_SKIPORD));
} else { break;
case F_DUPDATA:
if (unlikely(node_ds(node) <= PAGEHDRSZ)) { if (unlikely(node_ds(node) <= PAGEHDRSZ)) {
mdbx_error("invalid nested-page size %zu", node_ds(node)); mdbx_error("invalid nested-page size %zu", node_ds(node));
return MDBX_CORRUPTED; return MDBX_CORRUPTED;
@ -13465,6 +13479,7 @@ static int mdbx_xcursor_init1(MDBX_cursor *mc, MDBX_node *node,
mx->mx_db.md_flags = flags_db2sub(mc->mc_db->md_flags); mx->mx_db.md_flags = flags_db2sub(mc->mc_db->md_flags);
mx->mx_db.md_xsize = mx->mx_db.md_xsize =
(mc->mc_db->md_flags & MDBX_DUPFIXED) ? fp->mp_leaf2_ksize : 0; (mc->mc_db->md_flags & MDBX_DUPFIXED) ? fp->mp_leaf2_ksize : 0;
break;
} }
if (unlikely(mx->mx_db.md_xsize != mc->mc_db->md_xsize)) { if (unlikely(mx->mx_db.md_xsize != mc->mc_db->md_xsize)) {
@ -13504,7 +13519,7 @@ static int mdbx_xcursor_init1(MDBX_cursor *mc, MDBX_node *node,
* [in] src_mx The xcursor of an up-to-date cursor. * [in] src_mx The xcursor of an up-to-date cursor.
* [in] new_dupdata True if converting from a non-F_DUPDATA item. */ * [in] new_dupdata True if converting from a non-F_DUPDATA item. */
static int mdbx_xcursor_init2(MDBX_cursor *mc, MDBX_xcursor *src_mx, static int mdbx_xcursor_init2(MDBX_cursor *mc, MDBX_xcursor *src_mx,
int new_dupdata) { bool new_dupdata) {
MDBX_xcursor *mx = mc->mc_xcursor; MDBX_xcursor *mx = mc->mc_xcursor;
if (unlikely(mx == nullptr)) { if (unlikely(mx == nullptr)) {
mdbx_error("unexpected dupsort-page for non-dupsort db/cursor (dbi %u)", mdbx_error("unexpected dupsort-page for non-dupsort db/cursor (dbi %u)",