From e43cf081f1a681e5538b55499cb42be881df51fe Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Sat, 13 Mar 2021 17:05:43 +0300 Subject: [PATCH] mdbx: fix `mdbx_env_info_ex()` for a non-open environment case. Fix the https://github.com/erthink/libmdbx/issues/171. Change-Id: Iad3d0186ef40dfd40fad1c3ae0dd97f9c1161c16 --- ChangeLog.md | 1 + src/core.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 42ef1931..afe05d4f 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -34,6 +34,7 @@ Fixes: - Fixed performance regression due non-optimal C11 atomics usage (https://github.com/erthink/libmdbx/issues/160). - Fixed "reincarnation" of subDB after it deletion (https://github.com/erthink/libmdbx/issues/168). - Fixed (disallowing) implicit subDB deletion via operations on `@MAIN`'s DBI-handle. + - Fixed a crash of `mdbx_env_info_ex()` in case of a call for a non-open environment (https://github.com/erthink/libmdbx/issues/171). ## v0.9.3 at 2021-02-02 diff --git a/src/core.c b/src/core.c index 530bc0f5..0eab66a3 100644 --- a/src/core.c +++ b/src/core.c @@ -18444,6 +18444,31 @@ __cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn, if (unlikely(bytes != sizeof(MDBX_envinfo)) && bytes != size_before_bootid) return MDBX_EINVAL; + /* is the environment open? (https://github.com/erthink/libmdbx/issues/171) */ + if (unlikely(!env->me_map)) { + /* environment not yet opened */ +#if 1 + /* default behavior: returns the available info but zeroed the rest */ + memset(arg, 0, bytes); + arg->mi_geo.lower = env->me_dbgeo.lower; + arg->mi_geo.upper = env->me_dbgeo.upper; + arg->mi_geo.shrink = env->me_dbgeo.shrink; + arg->mi_geo.grow = env->me_dbgeo.grow; + arg->mi_geo.current = env->me_dbgeo.now; + arg->mi_maxreaders = env->me_maxreaders; + arg->mi_dxb_pagesize = env->me_psize; + arg->mi_sys_pagesize = env->me_os_psize; + if (likely(bytes > size_before_bootid)) { + arg->mi_bootid.current.x = bootid.x; + arg->mi_bootid.current.y = bootid.y; + } + return MDBX_SUCCESS; +#else + /* some users may prefer this behavior: return appropriate error */ + return MDBX_EPERM; +#endif + } + const MDBX_meta *const meta0 = METAPAGE(env, 0); const MDBX_meta *const meta1 = METAPAGE(env, 1); const MDBX_meta *const meta2 = METAPAGE(env, 2);