From bfa6dea7845a308b30f96a5f206708d904b18c5c Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Mon, 5 Jun 2017 20:48:05 +0300 Subject: [PATCH] mdbx: fix size_t/unsigned/int warnings. Change-Id: Ic5a8684aed232b8b732d6e7a87a6757f3f7afcec --- TODO.md | 2 +- mdbx.h | 8 +- src/bits.h | 13 +- src/mdbx.c | 380 ++++++++++++++++++++++++------------------- src/tools/mdbx_chk.c | 12 +- test/utils.cc | 4 +- 6 files changed, 233 insertions(+), 186 deletions(-) diff --git a/TODO.md b/TODO.md index 338f6e83..c0170135 100644 --- a/TODO.md +++ b/TODO.md @@ -27,7 +27,7 @@ - [x] Добавить мета-страницы в coredump, проверить lck - [x] Сделать список для txnid_t, кода sizeof(txnid_t) > sizeof(pgno_t) и вернуть размер pgno_t - [x] Избавиться от умножения на размер страницы (заменить на сдвиг). -- [ ] Устранение всех предупреждений (в том числе под Windows). +- [x] Устранение всех предупреждений (в том числе под Windows). - [ ] Перевод mdbx-tools на С++ и сборка для Windows - [ ] Заменить заглушки mdbx_version и mdbx_build - [ ] Актуализация README.md diff --git a/mdbx.h b/mdbx.h index 9429eb71..f696d0a3 100644 --- a/mdbx.h +++ b/mdbx.h @@ -1562,9 +1562,9 @@ typedef void MDBX_debug_func(int type, const char *function, int line, LIBMDBX_API int mdbx_setup_debug(int flags, MDBX_debug_func *logger); typedef int MDBX_pgvisitor_func(uint64_t pgno, unsigned pgnumber, void *ctx, - const char *dbi, const char *type, int nentries, - int payload_bytes, int header_bytes, - int unused_bytes); + const char *dbi, const char *type, + size_t nentries, size_t payload_bytes, + size_t header_bytes, size_t unused_bytes); LIBMDBX_API int mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor, void *ctx); @@ -1595,7 +1595,7 @@ LIBMDBX_API int mdbx_replace(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, * of multi-values/duplicates for a given key. * 2) updates the key for pointing to the actual key's data inside DB. */ LIBMDBX_API int mdbx_get_ex(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, - MDBX_val *data, int *values_count); + MDBX_val *data, size_t *values_count); LIBMDBX_API int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr); diff --git a/src/bits.h b/src/bits.h index b2d219eb..73bea6f5 100644 --- a/src/bits.h +++ b/src/bits.h @@ -660,9 +660,9 @@ struct MDBX_env { unsigned me_maxfree_1pg; /* Max size of a node on a page */ unsigned me_nodemax; - unsigned me_maxkey_limit; /* max size of a key */ - int me_live_reader; /* have liveness lock in reader table */ - void *me_userctx; /* User-settable context */ + unsigned me_maxkey_limit; /* max size of a key */ + mdbx_pid_t me_live_reader; /* have liveness lock in reader table */ + void *me_userctx; /* User-settable context */ #if MDBX_DEBUG MDBX_assert_func *me_assert_func; /* Callback for assertion failures */ #endif @@ -896,7 +896,7 @@ static __inline size_t roundup2(size_t value, size_t granularity) { #define PAGEDATA(p) ((void *)((char *)(p) + PAGEHDRSZ)) /* Number of nodes on a page */ -#define NUMKEYS(p) ((p)->mp_lower >> 1) +#define NUMKEYS(p) ((unsigned)(p)->mp_lower >> 1) /* The amount of space remaining in the page */ #define SIZELEFT(p) (indx_t)((p)->mp_upper - (p)->mp_lower) @@ -1045,9 +1045,10 @@ static __inline size_t NODEDSZ(const MDBX_node *node) { } /* Set the size of the data for a leaf node */ -static __inline void SETDSZ(MDBX_node *node, unsigned size) { +static __inline void SETDSZ(MDBX_node *node, size_t size) { + assert(size < INT_MAX); if (UNALIGNED_OK) { - node->mn_dsize = size; + node->mn_dsize = (uint32_t)size; } else { node->mn_lo = (uint16_t)size; node->mn_hi = (uint16_t)(size >> 16); diff --git a/src/mdbx.c b/src/mdbx.c index 93bcf94b..7ba9b54f 100644 --- a/src/mdbx.c +++ b/src/mdbx.c @@ -159,16 +159,16 @@ __cold void mdbx_rthc_remove(mdbx_thread_key_t key) { /* Allocate an IDL. * Allocates memory for an IDL of the given size. * Returns IDL on success, NULL on failure. */ -static MDBX_IDL mdbx_midl_alloc(unsigned size) { +static MDBX_IDL mdbx_midl_alloc(size_t size) { MDBX_IDL ids = malloc((size + 2) * sizeof(pgno_t)); if (likely(ids)) { - *ids++ = size; + *ids++ = (pgno_t)size; *ids = 0; } return ids; } -static MDBX_TXL mdbx_txl_alloc(unsigned size) { +static MDBX_TXL mdbx_txl_alloc(size_t size) { MDBX_TXL ptr = malloc((size + 2) * sizeof(txnid_t)); if (likely(ptr)) { *ptr++ = size; @@ -247,21 +247,21 @@ static void mdbx_midl_shrink(MDBX_IDL *idp) { /* Grow an IDL. * Return the IDL to the size growed by given number. * [in,out] idp Address of the IDL to grow. */ -static int mdbx_midl_grow(MDBX_IDL *idp, unsigned num) { +static int mdbx_midl_grow(MDBX_IDL *idp, size_t num) { MDBX_IDL idn = *idp - 1; /* grow it */ idn = realloc(idn, (*idn + num + 2) * sizeof(pgno_t)); if (unlikely(!idn)) return MDBX_ENOMEM; - *idn++ += num; + *idn++ += (pgno_t)num; *idp = idn; return 0; } -static int mdbx_txl_grow(MDBX_TXL *ptr, unsigned num) { +static int mdbx_txl_grow(MDBX_TXL *ptr, size_t num) { MDBX_TXL list = *ptr - 1; /* grow it */ - list = realloc(list, (*list + num + 2) * sizeof(txnid_t)); + list = realloc(list, ((size_t)*list + num + 2) * sizeof(txnid_t)); if (unlikely(!list)) return MDBX_ENOMEM; *list++ += num; @@ -273,7 +273,7 @@ static int mdbx_txl_grow(MDBX_TXL *ptr, unsigned num) { * [in,out] idp Address of the IDL. * [in] num Number of elements to make room for. * Returns 0 on success, MDBX_ENOMEM on failure. */ -static int mdbx_midl_need(MDBX_IDL *idp, unsigned num) { +static int mdbx_midl_need(MDBX_IDL *idp, size_t num) { MDBX_IDL ids = *idp; num += ids[0]; if (unlikely(num > ids[-1])) { @@ -281,7 +281,7 @@ static int mdbx_midl_need(MDBX_IDL *idp, unsigned num) { ids = realloc(ids - 1, num * sizeof(pgno_t)); if (unlikely(!ids)) return MDBX_ENOMEM; - *ids++ = num - 2; + *ids++ = (pgno_t)num - 2; *idp = ids; } return 0; @@ -308,7 +308,7 @@ static int mdbx_txl_append(MDBX_TXL *ptr, txnid_t id) { MDBX_TXL list = *ptr; /* Too big? */ if (unlikely(list[0] >= list[-1])) { - if (mdbx_txl_grow(ptr, list[0])) + if (mdbx_txl_grow(ptr, (size_t)list[0])) return MDBX_ENOMEM; list = *ptr; } @@ -338,11 +338,11 @@ static int mdbx_txl_append_list(MDBX_TXL *ptr, MDBX_TXL append) { MDBX_TXL list = *ptr; /* Too big? */ if (unlikely(list[0] + append[0] >= list[-1])) { - if (mdbx_txl_grow(ptr, append[0])) + if (mdbx_txl_grow(ptr, (size_t)append[0])) return MDBX_ENOMEM; list = *ptr; } - memcpy(&list[list[0] + 1], &append[1], append[0] * sizeof(txnid_t)); + memcpy(&list[list[0] + 1], &append[1], (size_t)append[0] * sizeof(txnid_t)); list[0] += append[0]; return 0; } @@ -352,7 +352,7 @@ static int mdbx_txl_append_list(MDBX_TXL *ptr, MDBX_TXL append) { * [in] id The lowest ID to append. * [in] n Number of IDs to append. * Returns 0 on success, MDBX_ENOMEM if the IDL is too large. */ -static int mdbx_midl_append_range(MDBX_IDL *idp, pgno_t id, unsigned n) { +static int mdbx_midl_append_range(MDBX_IDL *idp, pgno_t id, size_t n) { pgno_t *ids = *idp, len = ids[0]; /* Too big? */ if (unlikely(len + n > ids[-1])) { @@ -360,7 +360,7 @@ static int mdbx_midl_append_range(MDBX_IDL *idp, pgno_t id, unsigned n) { return MDBX_ENOMEM; ids = *idp; } - ids[0] = len + n; + ids[0] = len + (pgno_t)n; ids += len; while (n) ids[n--] = id++; @@ -605,7 +605,7 @@ static void mdbx_env_close0(MDBX_env *env); static MDBX_node *mdbx_node_search(MDBX_cursor *mc, MDBX_val *key, int *exactp); static int mdbx_node_add(MDBX_cursor *mc, indx_t indx, MDBX_val *key, MDBX_val *data, pgno_t pgno, unsigned flags); -static void mdbx_node_del(MDBX_cursor *mc, int ksize); +static void mdbx_node_del(MDBX_cursor *mc, size_t ksize); static void mdbx_node_shrink(MDBX_page *mp, indx_t indx); static int mdbx_node_move(MDBX_cursor *csrc, MDBX_cursor *cdst, int fromleft); static int mdbx_node_read(MDBX_cursor *mc, MDBX_node *leaf, MDBX_val *data); @@ -923,18 +923,16 @@ static void mdbx_cursor_chk(MDBX_cursor *mc) { static void mdbx_audit(MDBX_txn *txn) { MDBX_cursor mc; MDBX_val key, data; - pgno_t freecount, count; - MDBX_dbi i; int rc; - freecount = 0; + pgno_t freecount = 0; mdbx_cursor_init(&mc, txn, FREE_DBI, NULL); while ((rc = mdbx_cursor_get(&mc, &key, &data, MDBX_NEXT)) == 0) freecount += *(pgno_t *)data.iov_base; mdbx_tassert(txn, rc == MDBX_NOTFOUND); - count = 0; - for (i = 0; i < txn->mt_numdbs; i++) { + pgno_t count = 0; + for (MDBX_dbi i = 0; i < txn->mt_numdbs; i++) { MDBX_xcursor mx; if (!(txn->mt_dbflags[i] & DB_VALID)) continue; @@ -946,10 +944,8 @@ static void mdbx_audit(MDBX_txn *txn) { if (txn->mt_dbs[i].md_flags & MDBX_DUPSORT) { rc = mdbx_page_search(&mc, NULL, MDBX_PS_FIRST); for (; rc == MDBX_SUCCESS; rc = mdbx_cursor_sibling(&mc, 1)) { - unsigned j; - MDBX_page *mp; - mp = mc.mc_pg[mc.mc_top]; - for (j = 0; j < NUMKEYS(mp); j++) { + MDBX_page *mp = mc.mc_pg[mc.mc_top]; + for (unsigned j = 0; j < NUMKEYS(mp); j++) { MDBX_node *leaf = NODEPTR(mp, j); if (leaf->mn_flags & F_SUBDATA) { MDBX_db db; @@ -1195,7 +1191,7 @@ mark_done: return rc; } -static int mdbx_page_flush(MDBX_txn *txn, size_t keep); +static int mdbx_page_flush(MDBX_txn *txn, pgno_t keep); /* Spill pages from the dirty list back to disk. * This is intended to prevent running into MDBX_TXN_FULL situations, @@ -1239,7 +1235,7 @@ static int mdbx_page_spill(MDBX_cursor *m0, MDBX_val *key, MDBX_val *data) { return MDBX_SUCCESS; /* Estimate how much space this op will take */ - size_t i = m0->mc_db->md_depth; + pgno_t i = m0->mc_db->md_depth; /* Named DBs also dirty the main DB */ if (m0->mc_dbi >= CORE_DBS) i += txn->mt_dbs[MAIN_DBI].md_depth; @@ -1247,7 +1243,7 @@ static int mdbx_page_spill(MDBX_cursor *m0, MDBX_val *key, MDBX_val *data) { if (key) i += bytes2pgno(txn->mt_env, LEAFSIZE(key, data) + txn->mt_env->me_psize); i += i; /* double it for good measure */ - size_t need = i; + pgno_t need = i; if (txn->mt_dirtyroom > i) return MDBX_SUCCESS; @@ -1259,7 +1255,7 @@ static int mdbx_page_spill(MDBX_cursor *m0, MDBX_val *key, MDBX_val *data) { } else { /* purge deleted slots */ MDBX_IDL sl = txn->mt_spill_pages; - unsigned num = sl[0], j = 0; + pgno_t num = sl[0], j = 0; for (i = 1; i <= num; i++) { if (!(sl[i] & 1)) sl[++j] = sl[i]; @@ -1268,7 +1264,7 @@ static int mdbx_page_spill(MDBX_cursor *m0, MDBX_val *key, MDBX_val *data) { } /* Preserve pages which may soon be dirtied again */ - int rc = mdbx_pages_xkeep(m0, P_DIRTY, 1); + int rc = mdbx_pages_xkeep(m0, P_DIRTY, true); if (unlikely(rc != MDBX_SUCCESS)) goto bailout; @@ -1684,7 +1680,7 @@ static int mdbx_page_alloc(MDBX_cursor *mc, unsigned num, MDBX_page **mp, if (flags & MDBX_LIFORECLAIM) { if (txn->mt_lifo_reclaimed) { - for (j = txn->mt_lifo_reclaimed[0]; j > 0; --j) + for (j = (unsigned)txn->mt_lifo_reclaimed[0]; j > 0; --j) if (txn->mt_lifo_reclaimed[j] == last) break; if (j) @@ -2896,7 +2892,8 @@ again: head_room = mop_len - total_room; if (head_room > maxfree_1pg && head_id > 1) { /* Overflow multi-page for part of me_pghead */ - head_room /= head_id; /* amortize page sizes */ + head_room /= (head_id < INT16_MAX) ? (pgno_t)head_id + : INT16_MAX; /* amortize page sizes */ head_room += maxfree_1pg - head_room % (maxfree_1pg + 1); } else if (head_room < 0) { /* Rare case, not bothering to delete this record */ @@ -2989,7 +2986,7 @@ again: data.iov_base = mop -= len; save = mop[0]; - mop[0] = len; + mop[0] = (pgno_t)len; rc = mdbx_cursor_put(&mc, &key, &data, MDBX_CURRENT); mdbx_tassert( txn, cleanup_idx == @@ -3015,7 +3012,7 @@ bailout: * records. */ cleanup_idx = 0; /* LY: restart filling */ - refill_idx = total_room = head_room = 0; + total_room = head_room = refill_idx = 0; more = 1; goto again; } @@ -3033,11 +3030,11 @@ bailout: * [in] txn the transaction that's being committed * [in] keep number of initial pages in dirtylist to keep dirty. * Returns 0 on success, non-zero on failure. */ -static int mdbx_page_flush(MDBX_txn *txn, size_t keep) { +static int mdbx_page_flush(MDBX_txn *txn, pgno_t keep) { MDBX_env *env = txn->mt_env; MDBX_ID2L dl = txn->mt_rw_dirtylist; - unsigned j; - int i, pagecount = dl[0].mid, rc; + unsigned i, j, pagecount = dl[0].mid; + int rc; size_t size = 0, pos = 0; pgno_t pgno = 0; MDBX_page *dp = NULL; @@ -3609,7 +3606,10 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags, MDBX_meta *const meta2 = METAPAGE(env, 2); MDBX_meta *const head = mdbx_meta_head(env); - const size_t prev_mapsize = head->mm_mapsize; + mdbx_assert(env, head->mm_mapsize < MAX_MAPSIZE); + STATIC_ASSERT(SSIZE_MAX > MAX_MAPSIZE); + const size_t prev_mapsize = (size_t)head->mm_mapsize; + const size_t used_size = pgno2bytes(env, pending->mm_last_pg + 1); mdbx_assert(env, mdbx_meta_eq_mask(env) == 0); @@ -3806,11 +3806,17 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags, mdbx_assert(env, ((env->me_flags ^ flags) & MDBX_WRITEMAP) == 0); if (unlikely(pending->mm_mapsize < prev_mapsize)) { mdbx_assert(env, pending->mm_mapsize == env->me_mapsize); - rc = mdbx_ftruncate(env->me_fd, pending->mm_mapsize); + if (pending->mm_mapsize > MAX_MAPSIZE) { + rc = MDBX_PROBLEM; + goto fail; + } + const size_t mapsize = (size_t)pending->mm_mapsize; + mdbx_assert(env, pending->mm_mapsize == mapsize); + + rc = mdbx_ftruncate(env->me_fd, mapsize); if (unlikely(rc != MDBX_SUCCESS)) goto fail; - rc = mdbx_mremap_size((void **)&env->me_map, prev_mapsize, - pending->mm_mapsize); + rc = mdbx_mremap_size((void **)&env->me_map, prev_mapsize, mapsize); if (unlikely(rc != MDBX_SUCCESS)) goto fail; } @@ -3828,26 +3834,22 @@ int __cold mdbx_env_get_maxkeysize(MDBX_env *env) { return env->me_maxkey_limit; } -static __inline ssize_t mdbx_calc_nodemax(ssize_t pagesize) { - assert(pagesize > 0); - return (((pagesize - PAGEHDRSZ) / MDBX_MINKEYS) & -(ssize_t)2) - - sizeof(indx_t); -} +#define mdbx_nodemax(pagesize) \ + (((((pagesize)-PAGEHDRSZ) / MDBX_MINKEYS) & -(ssize_t)2) - sizeof(indx_t)) -static __inline ssize_t mdbx_calc_maxkey(ssize_t nodemax) { - assert(nodemax > 0); - return nodemax - (NODESIZE + sizeof(MDBX_db)); -} +#define mdbx_maxkey(nodemax) ((nodemax) - (NODESIZE + sizeof(MDBX_db))) + +#define mdbx_maxfree1pg(pagesize) (((pagesize)-PAGEHDRSZ) / sizeof(pgno_t) - 1) int mdbx_get_maxkeysize(size_t pagesize) { if (pagesize == 0) pagesize = mdbx_syspagesize(); - ssize_t nodemax = mdbx_calc_nodemax(pagesize); + ssize_t nodemax = mdbx_nodemax(pagesize); if (nodemax < 0) return -MDBX_EINVAL; - ssize_t maxkey = mdbx_calc_maxkey(nodemax); + ssize_t maxkey = mdbx_maxkey(nodemax); return (maxkey > 0 && maxkey < INT_MAX) ? (int)maxkey : -MDBX_EINVAL; } @@ -3856,12 +3858,27 @@ static void __cold mdbx_setup_pagesize(MDBX_env *env, size_t pagesize) { mdbx_ensure(env, pagesize >= MIN_PAGESIZE); mdbx_ensure(env, pagesize <= MAX_PAGESIZE); - env->me_psize = pagesize; - env->me_maxfree_1pg = (pagesize - PAGEHDRSZ) / sizeof(pgno_t) - 1; - env->me_nodemax = mdbx_calc_nodemax(pagesize); - env->me_maxkey_limit = mdbx_calc_maxkey(env->me_nodemax); - mdbx_assert(env, - env->me_maxkey_limit > 42 && env->me_maxkey_limit < pagesize); + env->me_psize = (unsigned)pagesize; + + STATIC_ASSERT(mdbx_maxfree1pg(MIN_PAGESIZE) > 42); + STATIC_ASSERT(mdbx_maxfree1pg(MAX_PAGESIZE) < MDBX_IDL_DB_MAX); + const ssize_t maxfree_1pg = (pagesize - PAGEHDRSZ) / sizeof(pgno_t) - 1; + mdbx_ensure(env, maxfree_1pg > 42 && maxfree_1pg < MDBX_IDL_DB_MAX); + env->me_maxfree_1pg = (unsigned)maxfree_1pg; + + STATIC_ASSERT(mdbx_nodemax(MIN_PAGESIZE) > 42); + STATIC_ASSERT(mdbx_nodemax(MAX_PAGESIZE) < UINT16_MAX); + const ssize_t nodemax = mdbx_nodemax(pagesize); + mdbx_ensure(env, nodemax > 42 && nodemax < UINT16_MAX); + env->me_nodemax = (unsigned)nodemax; + + STATIC_ASSERT(mdbx_maxkey(MIN_PAGESIZE) > 42); + STATIC_ASSERT(mdbx_maxkey(MIN_PAGESIZE) < MIN_PAGESIZE); + STATIC_ASSERT(mdbx_maxkey(MAX_PAGESIZE) > 42); + STATIC_ASSERT(mdbx_maxkey(MAX_PAGESIZE) < MAX_PAGESIZE); + const ssize_t maxkey_limit = mdbx_maxkey(env->me_nodemax); + mdbx_ensure(env, maxkey_limit > 42 && (size_t)maxkey_limit < pagesize); + env->me_maxkey_limit = (unsigned)maxkey_limit; env->me_psize2log = 0; while (pagesize > 1) { @@ -3884,12 +3901,13 @@ int __cold mdbx_env_create(MDBX_env **penv) { env->me_pid = mdbx_getpid(); int rc; - env->me_os_psize = mdbx_syspagesize(); - if (!is_power2(env->me_os_psize) || env->me_os_psize < MIN_PAGESIZE) { - mdbx_error("unsuitable system pageize %u", env->me_os_psize); + const size_t os_psize = mdbx_syspagesize(); + if (!is_power2(os_psize) || os_psize < MIN_PAGESIZE) { + mdbx_error("unsuitable system pageize %" PRIuPTR, os_psize); rc = MDBX_INCOMPATIBLE; goto bailout; } + env->me_os_psize = (unsigned)os_psize; mdbx_setup_pagesize(env, env->me_os_psize); rc = mdbx_fastmutex_init(&env->me_dbi_lock); @@ -4261,23 +4279,22 @@ static int __cold mdbx_setup_lck(MDBX_env *env, char *lck_pathname, int mode) { return err; size = wanna; } - } - - if ((size & (env->me_os_psize - 1)) || size < env->me_os_psize) { + } else if (size > SSIZE_MAX || (size & (env->me_os_psize - 1)) || + size < env->me_os_psize) { mdbx_notice("lck-file has invalid size %" PRIu64 " bytes", size); return MDBX_PROBLEM; } - const uint64_t maxreaders = - (size - sizeof(MDBX_lockinfo)) / sizeof(MDBX_reader) + 1; + const size_t maxreaders = + ((size_t)size - sizeof(MDBX_lockinfo)) / sizeof(MDBX_reader) + 1; if (maxreaders > UINT16_MAX) { - mdbx_error("lck-size too big (up to %" PRIu64 " readers)", maxreaders); + mdbx_error("lck-size too big (up to %" PRIuPTR " readers)", maxreaders); return MDBX_PROBLEM; } env->me_maxreaders = (unsigned)maxreaders; void *addr = NULL; - err = mdbx_mmap(&addr, size, true, env->me_lfd); + err = mdbx_mmap(&addr, (size_t)size, true, env->me_lfd); if (unlikely(err != MDBX_SUCCESS)) return err; assert(addr != nullptr); @@ -4304,7 +4321,7 @@ static int __cold mdbx_setup_lck(MDBX_env *env, char *lck_pathname, int mode) { if (rc == MDBX_RESULT_TRUE) { /* LY: exlcusive mode, init lck */ - memset(env->me_lck, 0, size); + memset(env->me_lck, 0, (size_t)size); err = mdbx_lck_init(env); if (err) return err; @@ -4344,9 +4361,6 @@ static int __cold mdbx_setup_lck(MDBX_env *env, char *lck_pathname, int mode) { int __cold mdbx_env_open_ex(MDBX_env *env, const char *path, unsigned flags, mode_t mode, int *exclusive) { - int oflags, rc, len; - char *lck_pathname, *dxb_pathname; - if (unlikely(!env || !path)) return MDBX_EINVAL; @@ -4357,16 +4371,17 @@ int __cold mdbx_env_open_ex(MDBX_env *env, const char *path, unsigned flags, (flags & ~(CHANGEABLE | CHANGELESS))) return MDBX_EINVAL; - len = strlen(path); + size_t len_full, len = strlen(path); if (flags & MDBX_NOSUBDIR) { - rc = len + sizeof(MDBX_LOCK_SUFFIX) + len + 1; + len_full = len + sizeof(MDBX_LOCK_SUFFIX) + len + 1; } else { - rc = len + sizeof(MDBX_LOCKNAME) + len + sizeof(MDBX_DATANAME); + len_full = len + sizeof(MDBX_LOCKNAME) + len + sizeof(MDBX_DATANAME); } - lck_pathname = malloc(rc); + char *lck_pathname = malloc(len_full); if (!lck_pathname) return MDBX_ENOMEM; + char *dxb_pathname; if (flags & MDBX_NOSUBDIR) { dxb_pathname = lck_pathname + len + sizeof(MDBX_LOCK_SUFFIX); sprintf(lck_pathname, "%s" MDBX_LOCK_SUFFIX, path); @@ -4377,7 +4392,7 @@ int __cold mdbx_env_open_ex(MDBX_env *env, const char *path, unsigned flags, sprintf(dxb_pathname, "%s" MDBX_DATANAME, path); } - rc = MDBX_SUCCESS; + int rc = MDBX_SUCCESS; flags |= env->me_flags; if (flags & MDBX_RDONLY) { /* LY: silently ignore irrelevant flags when @@ -4403,6 +4418,7 @@ int __cold mdbx_env_open_ex(MDBX_env *env, const char *path, unsigned flags, } env->me_dbxs[FREE_DBI].md_cmp = mdbx_cmp_int_ai; /* aligned MDBX_INTEGERKEY */ + int oflags; if (F_ISSET(flags, MDBX_RDONLY)) oflags = O_RDONLY; else @@ -5970,7 +5986,6 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, uint16_t fp_flags; MDBX_val xdata, *rdata, dkey, olddata; MDBX_db dummy; - int do_sub = 0, insert_key, insert_data; unsigned mcount = 0, dcount = 0, nospill; size_t nsize; int rc = MDBX_SUCCESS, rc2; @@ -5987,10 +6002,12 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, /* Check this first so counter will always be zero on any early failures. */ if (flags & MDBX_MULTIPLE) { - dcount = data[1].iov_len; - data[1].iov_len = 0; if (unlikely(!F_ISSET(mc->mc_db->md_flags, MDBX_DUPFIXED))) return MDBX_INCOMPATIBLE; + if (unlikely(data[1].iov_len >= INT_MAX)) + return MDBX_EINVAL; + dcount = (unsigned)data[1].iov_len; + data[1].iov_len = 0; } if (flags & MDBX_RESERVE) { @@ -6137,7 +6154,8 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, return rc2; } - insert_key = insert_data = rc; + bool insert_key, insert_data, do_sub = false; + insert_key = insert_data = (rc != MDBX_SUCCESS); if (insert_key) { /* The key does not exist */ mdbx_debug("inserting key at index %i", mc->mc_ki[mc->mc_top]); @@ -6285,7 +6303,8 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, xdata.iov_base = &dummy; if ((rc = mdbx_page_alloc(mc, 1, &mp, MDBX_ALLOC_ALL))) return rc; - offset = env->me_psize - olddata.iov_len; + mdbx_cassert(mc, env->me_psize > olddata.iov_len); + offset = env->me_psize - (unsigned)olddata.iov_len; flags |= F_DUPDATA | F_SUBDATA; dummy.md_root = mp->mp_pgno; sub_root = mp; @@ -6308,7 +6327,7 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, rdata = &xdata; flags |= F_DUPDATA; - do_sub = 1; + do_sub = true; if (!insert_key) mdbx_node_del(mc, 0); goto new_sub; @@ -6388,14 +6407,16 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, else if (!(mc->mc_flags & C_SUB)) memcpy(olddata.iov_base, data->iov_base, data->iov_len); else { - assert(NUMKEYS(mc->mc_pg[mc->mc_top]) == 1); - assert(mc->mc_pg[mc->mc_top]->mp_upper == - mc->mc_pg[mc->mc_top]->mp_lower); - assert(IS_LEAF(mc->mc_pg[mc->mc_top]) && - !IS_LEAF2(mc->mc_pg[mc->mc_top])); - assert(NODEDSZ(leaf) == 0); - assert(leaf->mn_flags == 0); - memcpy(NODEKEY(leaf), key->iov_base, leaf->mn_ksize = key->iov_len); + mdbx_cassert(mc, NUMKEYS(mc->mc_pg[mc->mc_top]) == 1); + mdbx_cassert(mc, mc->mc_pg[mc->mc_top]->mp_upper == + mc->mc_pg[mc->mc_top]->mp_lower); + mdbx_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top]) && + !IS_LEAF2(mc->mc_pg[mc->mc_top])); + mdbx_cassert(mc, NODEDSZ(leaf) == 0); + mdbx_cassert(mc, leaf->mn_flags == 0); + mdbx_cassert(mc, key->iov_len < UINT16_MAX); + leaf->mn_ksize = (uint16_t)key->iov_len; + memcpy(NODEKEY(leaf), key->iov_base, key->iov_len); assert((char *)NODEDATA(leaf) + NODEDSZ(leaf) < (char *)(mc->mc_pg[mc->mc_top]) + env->me_psize); goto fix_parent; @@ -6496,7 +6517,8 @@ new_sub: } } } - ecount = mc->mc_xcursor->mx_db.md_entries; + mdbx_cassert(mc, mc->mc_xcursor->mx_db.md_entries < SIZE_MAX); + ecount = (size_t)mc->mc_xcursor->mx_db.md_entries; if (flags & MDBX_APPENDDUP) xflags |= MDBX_APPEND; rc = mdbx_cursor_put(&mc->mc_xcursor->mx_cursor, data, &xdata, xflags); @@ -6504,7 +6526,7 @@ new_sub: void *db = NODEDATA(leaf); memcpy(db, &mc->mc_xcursor->mx_db, sizeof(MDBX_db)); } - insert_data = mc->mc_xcursor->mx_db.md_entries - ecount; + insert_data = (ecount != (size_t)mc->mc_xcursor->mx_db.md_entries); } /* Increment count unless we just replaced an existing item. */ if (insert_data) @@ -6524,7 +6546,7 @@ new_sub: data[1].iov_len = mcount; if (mcount < dcount) { data[0].iov_base = (char *)data[0].iov_base + data[0].iov_len; - insert_key = insert_data = 0; + insert_key = insert_data = false; goto more; } } @@ -6765,7 +6787,6 @@ static int mdbx_node_add(MDBX_cursor *mc, indx_t indx, MDBX_val *key, unsigned i; size_t node_size = NODESIZE; ssize_t room; - unsigned ofs; MDBX_node *node; MDBX_page *mp = mc->mc_pg[mc->mc_top]; MDBX_page *ofp = NULL; /* overflow page */ @@ -6783,17 +6804,19 @@ static int mdbx_node_add(MDBX_cursor *mc, indx_t indx, MDBX_val *key, if (IS_LEAF2(mp)) { mdbx_cassert(mc, key); /* Move higher keys up one slot. */ - int ksize = mc->mc_db->md_xsize, dif; - char *ptr = LEAF2KEY(mp, indx, ksize); - dif = NUMKEYS(mp) - indx; - if (dif > 0) - memmove(ptr + ksize, ptr, dif * ksize); + const int ksize = mc->mc_db->md_xsize; + char *const ptr = LEAF2KEY(mp, indx, ksize); + const int diff = NUMKEYS(mp) - indx; + if (diff > 0) + memmove(ptr + ksize, ptr, diff * ksize); /* insert new key */ memcpy(ptr, key->iov_base, ksize); /* Just using these for counting */ + mdbx_cassert(mc, UINT16_MAX - mp->mp_lower >= (int)sizeof(indx_t)); mp->mp_lower += sizeof(indx_t); - mp->mp_upper -= ksize - sizeof(indx_t); + mdbx_cassert(mc, mp->mp_upper >= ksize - sizeof(indx_t)); + mp->mp_upper -= (indx_t)(ksize - sizeof(indx_t)); return MDBX_SUCCESS; } @@ -6807,7 +6830,7 @@ static int mdbx_node_add(MDBX_cursor *mc, indx_t indx, MDBX_val *key, node_size += sizeof(pgno_t); } else if (unlikely(node_size + data->iov_len > mc->mc_txn->mt_env->me_nodemax)) { - unsigned ovpages = OVPAGES(mc->mc_txn->mt_env, data->iov_len); + pgno_t ovpages = OVPAGES(mc->mc_txn->mt_env, data->iov_len); int rc; /* Put data on overflow page. */ mdbx_debug("data size is %" PRIuPTR ", node would be %" PRIuPTR @@ -6835,8 +6858,9 @@ update: mp->mp_ptrs[i] = mp->mp_ptrs[i - 1]; /* Adjust free space offsets. */ - ofs = mp->mp_upper - node_size; + size_t ofs = mp->mp_upper - node_size; mdbx_cassert(mc, ofs >= mp->mp_lower + sizeof(indx_t)); + mdbx_cassert(mc, ofs <= UINT16_MAX); mp->mp_ptrs[indx] = (uint16_t)ofs; mp->mp_upper = (uint16_t)ofs; mp->mp_lower += sizeof(indx_t); @@ -6888,10 +6912,9 @@ full: * [in] mc Cursor pointing to the node to delete. * [in] ksize The size of a node. Only used if the page is * part of a MDBX_DUPFIXED database. */ -static void mdbx_node_del(MDBX_cursor *mc, int ksize) { +static void mdbx_node_del(MDBX_cursor *mc, size_t ksize) { MDBX_page *mp = mc->mc_pg[mc->mc_top]; indx_t indx = mc->mc_ki[mc->mc_top]; - unsigned sz; indx_t i, j, numkeys, ptr; MDBX_node *node; char *base; @@ -6902,17 +6925,21 @@ static void mdbx_node_del(MDBX_cursor *mc, int ksize) { mdbx_cassert(mc, indx < numkeys); if (IS_LEAF2(mp)) { - int x = numkeys - 1 - indx; + mdbx_cassert(mc, ksize >= sizeof(indx_t)); + unsigned diff = numkeys - 1 - indx; base = LEAF2KEY(mp, indx, ksize); - if (x) - memmove(base, base + ksize, x * ksize); + if (diff) + memmove(base, base + ksize, diff * ksize); + mdbx_cassert(mc, mp->mp_lower >= sizeof(indx_t)); mp->mp_lower -= sizeof(indx_t); - mp->mp_upper += ksize - sizeof(indx_t); + mdbx_cassert(mc, + (size_t)UINT16_MAX - mp->mp_upper >= ksize - sizeof(indx_t)); + mp->mp_upper += (indx_t)(ksize - sizeof(indx_t)); return; } node = NODEPTR(mp, indx); - sz = NODESIZE + node->mn_ksize; + size_t sz = NODESIZE + node->mn_ksize; if (IS_LEAF(mp)) { if (F_ISSET(node->mn_flags, F_BIGDATA)) sz += sizeof(pgno_t); @@ -6925,8 +6952,10 @@ static void mdbx_node_del(MDBX_cursor *mc, int ksize) { for (i = j = 0; i < numkeys; i++) { if (i != indx) { mp->mp_ptrs[j] = mp->mp_ptrs[i]; - if (mp->mp_ptrs[i] < ptr) - mp->mp_ptrs[j] += sz; + if (mp->mp_ptrs[i] < ptr) { + mdbx_cassert(mc, (size_t)UINT16_MAX - mp->mp_ptrs[j] >= sz); + mp->mp_ptrs[j] += (indx_t)sz; + } j++; } } @@ -6934,8 +6963,10 @@ static void mdbx_node_del(MDBX_cursor *mc, int ksize) { base = (char *)mp + mp->mp_upper + PAGEHDRSZ; memmove(base + sz, base, ptr - mp->mp_upper); + mdbx_cassert(mc, mp->mp_lower >= sizeof(indx_t)); mp->mp_lower -= sizeof(indx_t); - mp->mp_upper += sz; + mdbx_cassert(mc, (size_t)UINT16_MAX - mp->mp_upper >= sz); + mp->mp_upper += (indx_t)sz; } /* Compact the main page after deleting a node on a subpage. @@ -6945,7 +6976,7 @@ static void mdbx_node_shrink(MDBX_page *mp, indx_t indx) { MDBX_node *node; MDBX_page *sp, *xp; char *base; - unsigned nsize, delta, len, ptr; + size_t nsize, delta, len, ptr; int i; node = NODEPTR(mp, indx); @@ -6960,8 +6991,10 @@ static void mdbx_node_shrink(MDBX_page *mp, indx_t indx) { return; /* do not make the node uneven-sized */ } else { xp = (MDBX_page *)((char *)sp + delta); /* destination subpage */ - for (i = NUMKEYS(sp); --i >= 0;) - xp->mp_ptrs[i] = sp->mp_ptrs[i] - delta; + for (i = NUMKEYS(sp); --i >= 0;) { + assert(sp->mp_ptrs[i] >= delta); + xp->mp_ptrs[i] = (indx_t)(sp->mp_ptrs[i] - delta); + } len = PAGEHDRSZ; } sp->mp_upper = sp->mp_lower; @@ -6974,10 +7007,13 @@ static void mdbx_node_shrink(MDBX_page *mp, indx_t indx) { ptr = mp->mp_ptrs[indx]; for (i = NUMKEYS(mp); --i >= 0;) { - if (mp->mp_ptrs[i] <= ptr) - mp->mp_ptrs[i] += delta; + if (mp->mp_ptrs[i] <= ptr) { + assert((size_t)UINT16_MAX - mp->mp_ptrs[i] >= delta); + mp->mp_ptrs[i] += (indx_t)delta; + } } - mp->mp_upper += delta; + assert((size_t)UINT16_MAX - mp->mp_upper >= delta); + mp->mp_upper += (indx_t)delta; } /* Initial setup of a sorted-dups cursor. @@ -7049,7 +7085,7 @@ static void mdbx_xcursor_init1(MDBX_cursor *mc, MDBX_node *node) { mdbx_debug("Sub-db -%u root page %" PRIaPGNO "", mx->mx_cursor.mc_dbi, mx->mx_db.md_root); mx->mx_dbflag = DB_VALID | DB_USRVALID | DB_DUPDATA; - /* #if UINT_MAX < SIZE_MAX + /* FIXME: #if UINT_MAX < SIZE_MAX if (mx->mx_dbx.md_cmp == mdbx_cmp_int && mx->mx_db.md_pad == sizeof(size_t)) mx->mx_dbx.md_cmp = mdbx_cmp_clong; @@ -7217,9 +7253,9 @@ int mdbx_cursor_count(MDBX_cursor *mc, size_t *countp) { if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { mdbx_cassert(mc, mc->mc_xcursor && (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)); - *countp = unlikely(mc->mc_xcursor->mx_db.md_entries > INT_MAX) - ? INT_MAX - : mc->mc_xcursor->mx_db.md_entries; + *countp = unlikely(mc->mc_xcursor->mx_db.md_entries > SIZE_MAX) + ? SIZE_MAX + : (size_t)mc->mc_xcursor->mx_db.md_entries; } } return MDBX_SUCCESS; @@ -8079,21 +8115,19 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata, pgno_t newpgno, unsigned nflags) { unsigned flags; int rc = MDBX_SUCCESS, new_root = 0, did_split = 0; - indx_t newindx; pgno_t pgno = 0; - int i, j, split_indx, nkeys, pmax; + unsigned i, ptop; MDBX_env *env = mc->mc_txn->mt_env; MDBX_node *node; MDBX_val sepkey, rkey, xdata, *rdata = &xdata; MDBX_page *copy = NULL; - MDBX_page *mp, *rp, *pp; - int ptop; + MDBX_page *rp, *pp; MDBX_cursor mn; DKBUF; - mp = mc->mc_pg[mc->mc_top]; - newindx = mc->mc_ki[mc->mc_top]; - nkeys = NUMKEYS(mp); + MDBX_page *mp = mc->mc_pg[mc->mc_top]; + unsigned newindx = mc->mc_ki[mc->mc_top]; + unsigned nkeys = NUMKEYS(mp); mdbx_debug("-----> splitting %s page %" PRIaPGNO " and adding [%s] at index %i/%i", @@ -8147,6 +8181,7 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata, mn.mc_pg[mn.mc_top] = rp; mn.mc_ki[ptop] = mc->mc_ki[ptop] + 1; + unsigned split_indx; if (nflags & MDBX_APPEND) { mn.mc_ki[mn.mc_top] = 0; sepkey = *newkey; @@ -8176,27 +8211,32 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata, sepkey.iov_base = split; } if (x < 0) { + mdbx_cassert(mc, ksize >= sizeof(indx_t)); ins = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], ksize); memcpy(rp->mp_ptrs, split, rsize); sepkey.iov_base = rp->mp_ptrs; memmove(ins + ksize, ins, (split_indx - mc->mc_ki[mc->mc_top]) * ksize); memcpy(ins, newkey->iov_base, ksize); + mdbx_cassert(mc, UINT16_MAX - mp->mp_lower >= (int)sizeof(indx_t)); mp->mp_lower += sizeof(indx_t); - mp->mp_upper -= ksize - sizeof(indx_t); + mdbx_cassert(mc, mp->mp_upper >= ksize - sizeof(indx_t)); + mp->mp_upper -= (indx_t)(ksize - sizeof(indx_t)); } else { if (x) memcpy(rp->mp_ptrs, split, x * ksize); ins = LEAF2KEY(rp, x, ksize); memcpy(ins, newkey->iov_base, ksize); memcpy(ins + ksize, split + x * ksize, rsize - x * ksize); + mdbx_cassert(mc, UINT16_MAX - rp->mp_lower >= (int)sizeof(indx_t)); rp->mp_lower += sizeof(indx_t); - rp->mp_upper -= ksize - sizeof(indx_t); + mdbx_cassert(mc, rp->mp_upper >= ksize - sizeof(indx_t)); + rp->mp_upper -= (indx_t)(ksize - sizeof(indx_t)); mc->mc_ki[mc->mc_top] = x; } } else { - int psize, nsize, k; + size_t psize, nsize, k; /* Maximum free space in an empty page */ - pmax = env->me_psize - PAGEHDRSZ; + unsigned pmax = env->me_psize - PAGEHDRSZ; if (IS_LEAF(mp)) nsize = mdbx_leaf_size(env, newkey, newdata); else @@ -8215,10 +8255,9 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata, copy->mp_upper = env->me_psize - PAGEHDRSZ; /* prepare to insert */ - for (i = 0, j = 0; i < nkeys; i++) { - if (i == newindx) { + for (unsigned j = i = 0; i < nkeys; i++) { + if (i == newindx) copy->mp_ptrs[j++] = 0; - } copy->mp_ptrs[j++] = mp->mp_ptrs[i]; } @@ -8237,19 +8276,20 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata, * the split so the new page is emptier than the old page. * This yields better packing during sequential inserts. */ + int dir; if (nkeys < 20 || nsize > pmax / 16 || newindx >= nkeys) { /* Find split point */ psize = 0; if (newindx <= split_indx || newindx >= nkeys) { i = 0; - j = 1; - k = newindx >= nkeys ? nkeys : split_indx + 1 + IS_LEAF(mp); + dir = 1; + k = (newindx >= nkeys) ? nkeys : split_indx + 1 + IS_LEAF(mp); } else { i = nkeys; - j = -1; + dir = -1; k = split_indx - 1; } - for (; i != k; i += j) { + for (; i != k; i += dir) { if (i == newindx) { psize += nsize; node = NULL; @@ -8264,8 +8304,8 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata, } psize = EVEN(psize); } - if (psize > pmax || i == k - j) { - split_indx = i + (j < 0); + if (psize > pmax || i == k - dir) { + split_indx = i + (dir < 0); break; } } @@ -8297,9 +8337,9 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata, goto done; /* root split? */ - if (mc->mc_snum > snum) { + if (mc->mc_snum > snum) ptop++; - } + /* Right page might now have changed parent. * Check if left page also changed parent. */ if (mn.mc_pg[ptop] != mc->mc_pg[ptop] && @@ -8341,7 +8381,7 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata, /* Move nodes */ mc->mc_pg[mc->mc_top] = rp; i = split_indx; - j = 0; + indx_t n = 0; do { if (i == newindx) { rkey.iov_base = newkey->iov_base; @@ -8352,7 +8392,7 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata, pgno = newpgno; flags = nflags; /* Update index for the new key. */ - mc->mc_ki[mc->mc_top] = j; + mc->mc_ki[mc->mc_top] = n; } else { node = (MDBX_node *)((char *)mp + copy->mp_ptrs[i] + PAGEHDRSZ); rkey.iov_base = NODEKEY(node); @@ -8366,21 +8406,21 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata, flags = node->mn_flags; } - if (!IS_LEAF(mp) && j == 0) { + if (!IS_LEAF(mp) && n == 0) { /* First branch index doesn't need key data. */ rkey.iov_len = 0; } - rc = mdbx_node_add(mc, j, &rkey, rdata, pgno, flags); + rc = mdbx_node_add(mc, n, &rkey, rdata, pgno, flags); if (rc) goto done; if (i == nkeys) { i = 0; - j = 0; + n = 0; mc->mc_pg[mc->mc_top] = copy; } else { i++; - j++; + n++; } } while (i != split_indx); @@ -8552,8 +8592,8 @@ typedef struct mdbx_copy { mdbx_condmutex_t mc_condmutex; char *mc_wbuf[2]; char *mc_over[2]; - int mc_wlen[2]; - int mc_olen[2]; + size_t mc_wlen[2]; + size_t mc_olen[2]; pgno_t mc_next_pgno; mdbx_filehandle_t mc_fd; int mc_toggle; /* Buffer number in provider */ @@ -8567,7 +8607,7 @@ typedef struct mdbx_copy { static THREAD_RESULT __cold THREAD_CALL mdbx_env_copythr(void *arg) { mdbx_copy *my = arg; char *ptr; - int toggle = 0, wsize; + int toggle = 0; int rc; #if defined(F_SETNOSIGPIPE) @@ -8593,7 +8633,7 @@ static THREAD_RESULT __cold THREAD_CALL mdbx_env_copythr(void *arg) { mdbx_condmutex_wait(&my->mc_condmutex); if (my->mc_new == 0 + MDBX_EOF) /* 0 buffers, just EOF */ break; - wsize = my->mc_wlen[toggle]; + size_t wsize = my->mc_wlen[toggle]; ptr = my->mc_wbuf[toggle]; again: if (wsize > 0 && !my->mc_error) { @@ -8942,14 +8982,13 @@ int __cold mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd, } int __cold mdbx_env_copy(MDBX_env *env, const char *path, unsigned flags) { - int rc, len; char *lck_pathname; mdbx_filehandle_t newfd = INVALID_HANDLE_VALUE; if (env->me_flags & MDBX_NOSUBDIR) { lck_pathname = (char *)path; } else { - len = strlen(path); + size_t len = strlen(path); len += sizeof(MDBX_DATANAME); lck_pathname = malloc(len); if (!lck_pathname) @@ -8960,7 +8999,8 @@ int __cold mdbx_env_copy(MDBX_env *env, const char *path, unsigned flags) { /* The destination path must exist, but the destination file must not. * We don't want the OS to cache the writes, since the source data is * already in the OS cache. */ - rc = mdbx_openfile(lck_pathname, O_WRONLY | O_CREAT | O_EXCL, 0666, &newfd); + int rc = + mdbx_openfile(lck_pathname, O_WRONLY | O_CREAT | O_EXCL, 0666, &newfd); if (rc == MDBX_SUCCESS) { if (env->me_psize >= env->me_os_psize) { #ifdef F_NOCACHE /* __APPLE__ */ @@ -9761,7 +9801,9 @@ static txnid_t __cold mdbx_oomkick(MDBX_env *env, txnid_t oldest) { if (oldest < snap || reader < 0) { if (retry && env->me_oom_func) { /* LY: notify end of oom-loop */ - env->me_oom_func(env, 0, 0, oldest, snap - oldest, -retry); + const txnid_t gap = snap - oldest; + env->me_oom_func(env, 0, 0, oldest, + (gap < UINT_MAX) ? (unsigned)gap : UINT_MAX, -retry); } return snap; } @@ -9780,9 +9822,10 @@ static txnid_t __cold mdbx_oomkick(MDBX_env *env, txnid_t oldest) { if (r->mr_txnid != oldest || pid <= 0) continue; - rc = env->me_oom_func( - env, pid, tid, oldest, - mdbx_meta_txnid_stable(env, mdbx_meta_head(env)) - oldest, retry); + const txnid_t gap = + mdbx_meta_txnid_stable(env, mdbx_meta_head(env)) - oldest; + rc = env->me_oom_func(env, pid, tid, oldest, + (gap < UINT_MAX) ? (unsigned)gap : UINT_MAX, retry); if (rc < 0) break; @@ -9849,11 +9892,11 @@ int mdbx_txn_straggler(MDBX_txn *txn, int *percent) MDBX_env *env = txn->mt_env; MDBX_meta *meta = mdbx_meta_head(env); if (percent) { - size_t maxpg = env->me_maxpg; - size_t last = meta->mm_last_pg + 1; + pgno_t maxpg = env->me_maxpg; + pgno_t last = meta->mm_last_pg + 1; if (env->me_txn) last = env->me_txn0->mt_next_pgno; - *percent = (last * 100ull + maxpg / 2) / maxpg; + *percent = (int)((last * UINT64_C(100) + maxpg / 2) / maxpg); } txnid_t lag = mdbx_meta_txnid_fluid(env, meta) - txn->mt_ro_reader->mr_txnid; return (lag > INT_MAX) ? INT_MAX : (int)lag; @@ -9870,7 +9913,7 @@ static int __cold mdbx_env_walk(mdbx_walk_ctx_t *ctx, const char *dbi, pgno_t pg, int deep) { MDBX_page *mp; int rc, i, nkeys; - unsigned header_size, unused_size, payload_size, align_bytes; + size_t header_size, unused_size, payload_size, align_bytes; const char *type; if (pg == P_INVALID) @@ -10278,7 +10321,7 @@ bailout: } int mdbx_get_ex(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, - int *values_count) { + size_t *values_count) { DKBUF; mdbx_debug("===> get db %u key [%s]", dbi, DKEY(key)); @@ -10313,7 +10356,10 @@ int mdbx_get_ex(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { mdbx_tassert(txn, mc.mc_xcursor == &mx && (mx.mx_cursor.mc_flags & C_INITIALIZED)); - *values_count = mx.mx_db.md_entries; + *values_count = (sizeof(*values_count) >= sizeof(mx.mx_db.md_entries) || + mx.mx_db.md_entries <= SIZE_MAX) + ? (size_t)mx.mx_db.md_entries + : SIZE_MAX; } } } diff --git a/src/tools/mdbx_chk.c b/src/tools/mdbx_chk.c index 726f5712..7c14188c 100644 --- a/src/tools/mdbx_chk.c +++ b/src/tools/mdbx_chk.c @@ -224,8 +224,9 @@ static uint64_t problems_pop(struct problem *list) { } static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx, - const char *dbi, const char *type, int nentries, - int payload_bytes, int header_bytes, int unused_bytes) { + const char *dbi, const char *type, size_t nentries, + size_t payload_bytes, size_t header_bytes, + size_t unused_bytes) { (void)ctx; if (type) { @@ -240,13 +241,14 @@ static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx, print(" %s-page %" PRIu64, type, pgno); else print(" %s-span %" PRIu64 "[%u]", type, pgno, pgnumber); - print(" of %s: header %i, payload %i, unused %i\n", dbi, header_bytes, - payload_bytes, unused_bytes); + print(" of %s: header %" PRIiPTR ", payload %" PRIiPTR + ", unused %" PRIiPTR "\n", + dbi, header_bytes, payload_bytes, unused_bytes); } walk.pgcount += pgnumber; - if (unused_bytes < 0 || (size_t)unused_bytes > page_size) + if (unused_bytes > page_size) problem_add("page", pgno, "illegal unused-bytes", "%u < %i < %u", 0, unused_bytes, envstat.ms_psize); diff --git a/test/utils.cc b/test/utils.cc index ae58311f..fd2162f1 100644 --- a/test/utils.cc +++ b/test/utils.cc @@ -163,9 +163,7 @@ uint64_t entropy_ticks(void) { #elif defined(_M_IX86) || defined(_M_X64) return __rdtsc(); -#endif /* __GNUC__ || __clang__ */ - -#if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) +#elif defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) LARGE_INTEGER PerformanceCount; if (QueryPerformanceCounter(&PerformanceCount)) return PerformanceCount.QuadPart;