mdbx: рефакторинг проверок с выносом в cursor_check_multiple() (backport).

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2025-03-20 01:52:21 +03:00
parent 7ed769e9c6
commit 9653c8f45b
4 changed files with 34 additions and 15 deletions

View File

@ -711,22 +711,10 @@ int mdbx_cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, MDBX_p
if (unlikely(rc != MDBX_SUCCESS))
return LOG_IFERR(rc);
/* Check this first so counter will always be zero on any early failures. */
if (unlikely(flags & MDBX_MULTIPLE)) {
if (unlikely(flags & MDBX_RESERVE))
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(!(mc->tree->flags & MDBX_DUPFIXED)))
return LOG_IFERR(MDBX_INCOMPATIBLE);
const size_t dcount = data[1].iov_len;
if (unlikely(dcount < 2 || data->iov_len == 0))
return LOG_IFERR(MDBX_BAD_VALSIZE);
if (unlikely(mc->tree->dupfix_size != data->iov_len) && mc->tree->dupfix_size)
return LOG_IFERR(MDBX_BAD_VALSIZE);
if (unlikely(dcount > MAX_MAPSIZE / 2 / (BRANCH_NODE_MAX(MDBX_MAX_PAGESIZE) - NODESIZE))) {
/* checking for multiplication overflow */
if (unlikely(dcount > MAX_MAPSIZE / 2 / data->iov_len))
return LOG_IFERR(MDBX_TOO_LARGE);
}
rc = cursor_check_multiple(mc, key, data, flags);
if (unlikely(rc != MDBX_SUCCESS))
return LOG_IFERR(rc);
}
if (flags & MDBX_RESERVE) {

View File

@ -266,6 +266,19 @@ int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data, M
rc = cursor_init(&cx.outer, txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return LOG_IFERR(rc);
if (unlikely(flags & MDBX_MULTIPLE)) {
rc = cursor_check_multiple(&cx.outer, key, data, flags);
if (unlikely(rc != MDBX_SUCCESS))
return LOG_IFERR(rc);
}
if (flags & MDBX_RESERVE) {
if (unlikely(cx.outer.tree->flags & (MDBX_DUPSORT | MDBX_REVERSEDUP | MDBX_INTEGERDUP | MDBX_DUPFIXED)))
return LOG_IFERR(MDBX_INCOMPATIBLE);
data->iov_base = nullptr;
}
cx.outer.next = txn->cursors[dbi];
txn->cursors[dbi] = &cx.outer;

View File

@ -1438,6 +1438,21 @@ insert_node:;
return rc;
}
int cursor_check_multiple(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, unsigned flags) {
(void)key;
if (unlikely(flags & MDBX_RESERVE))
return MDBX_EINVAL;
if (unlikely(!(mc->tree->flags & MDBX_DUPFIXED)))
return MDBX_INCOMPATIBLE;
const size_t number = data[1].iov_len;
if (unlikely(number > MAX_MAPSIZE / 2 / (BRANCH_NODE_MAX(MDBX_MAX_PAGESIZE) - NODESIZE))) {
/* checking for multiplication overflow */
if (unlikely(number > MAX_MAPSIZE / 2 / data->iov_len))
return MDBX_TOO_LARGE;
}
return MDBX_SUCCESS;
}
__hot int cursor_put_checklen(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, unsigned flags) {
cASSERT(mc, (mc->flags & z_inner) == 0);
if (unlikely(key->iov_len > mc->clc->k.lmax || key->iov_len < mc->clc->k.lmin)) {

View File

@ -315,6 +315,9 @@ MDBX_INTERNAL MDBX_cursor *cursor_cpstk(const MDBX_cursor *csrc, MDBX_cursor *cd
MDBX_INTERNAL int __must_check_result cursor_ops(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
const MDBX_cursor_op op);
MDBX_INTERNAL int __must_check_result cursor_check_multiple(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data,
unsigned flags);
MDBX_INTERNAL int __must_check_result cursor_put_checklen(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data,
unsigned flags);