From 5c4715aea7dc5bda704924448d2d74380f75c0b0 Mon Sep 17 00:00:00 2001
From: George Hazan <ghazan@miranda.im>
Date: Fri, 7 Feb 2020 19:46:11 +0300
Subject: fixes #2205 (Unable to create new profile)

---
 libs/libmdbx/src/README.md           |  3 ++-
 libs/libmdbx/src/mdbx.h              |  3 +--
 libs/libmdbx/src/src/elements/core.c | 28 ++++++++++++++++------------
 plugins/Dbx_mdbx/src/dbcrypt.cpp     | 29 ++++++++++++++++++++---------
 4 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/libs/libmdbx/src/README.md b/libs/libmdbx/src/README.md
index 1b2fb69bdd..d5c24f5545 100644
--- a/libs/libmdbx/src/README.md
+++ b/libs/libmdbx/src/README.md
@@ -1,3 +1,5 @@
+<!-- Required extensions: pymdownx.betterem, pymdownx.tilde, pymdownx.emoji, pymdownx.tasklist, pymdownx.superfences -->
+
 libmdbx
 =======
 
@@ -554,4 +556,3 @@ syscall and by scanning data directory.
 --------------------------------------------------------------------------------
 
 ### The [repository now only mirrored on the Github](https://abf.io/erthink/libmdbx) due to illegal discriminatory restrictions for Russian Crimea and for sovereign crimeans.
-<!-- Required extensions: pymdownx.betterem, pymdownx.tilde, pymdownx.emoji, pymdownx.tasklist, pymdownx.superfences -->
diff --git a/libs/libmdbx/src/mdbx.h b/libs/libmdbx/src/mdbx.h
index fba8c4602b..8c9c865129 100644
--- a/libs/libmdbx/src/mdbx.h
+++ b/libs/libmdbx/src/mdbx.h
@@ -1508,8 +1508,7 @@ typedef enum MDBX_cursor_op {
  * since it opened in read-only mode */
 #define MDBX_WANNA_RECOVERY (-30419)
 
-/* The given key value is mismatched to the current cursor position,
- * when mdbx_cursor_put() called with MDBX_CURRENT option. */
+/* The given key value is mismatched to the current cursor position */
 #define MDBX_EKEYMISMATCH (-30418)
 
 /* Database is too large for current system,
diff --git a/libs/libmdbx/src/src/elements/core.c b/libs/libmdbx/src/src/elements/core.c
index d1cf8979ae..306ce6bc3b 100644
--- a/libs/libmdbx/src/src/elements/core.c
+++ b/libs/libmdbx/src/src/elements/core.c
@@ -2493,13 +2493,13 @@ static int lcklist_detach_locked(MDBX_env *env) {
     TYPE_LIST *const begin = first, *const end = begin + length;               \
                                                                                \
     while (length > 3) {                                                       \
-      const unsigned half = length >> 1;                                       \
-      TYPE_LIST *const middle = first + half;                                  \
+      const unsigned whole = length;                                           \
+      length >>= 1;                                                            \
+      TYPE_LIST *const middle = first + length;                                \
       if (CMP(*middle, item)) {                                                \
         first = middle + 1;                                                    \
-        length -= half + 1;                                                    \
-      } else                                                                   \
-        length = half;                                                         \
+        length = whole - length - 1;                                           \
+      }                                                                        \
     }                                                                          \
                                                                                \
     switch (length) {                                                          \
@@ -2507,17 +2507,21 @@ static int lcklist_detach_locked(MDBX_env *env) {
       if (!CMP(*first, item))                                                  \
         break;                                                                 \
       ++first;                                                                 \
-      /* fall through */                                                       \
-      __fallthrough;                                                           \
+      __fallthrough /* fall through */;                                        \
     case 2:                                                                    \
       if (!CMP(*first, item))                                                  \
         break;                                                                 \
       ++first;                                                                 \
-      /* fall through */                                                       \
-      __fallthrough;                                                           \
+      __fallthrough /* fall through */;                                        \
     case 1:                                                                    \
-      if (CMP(*first, item))                                                   \
-        ++first;                                                               \
+      if (!CMP(*first, item))                                                  \
+        break;                                                                 \
+      ++first;                                                                 \
+      __fallthrough /* fall through */;                                        \
+    case 0:                                                                    \
+      break;                                                                   \
+    default:                                                                   \
+      __unreachable();                                                         \
     }                                                                          \
                                                                                \
     if (mdbx_audit_enabled()) {                                                \
@@ -3176,7 +3180,7 @@ static const char *__mdbx_strerr(int errnum) {
       "MDBX_VERSION_MISMATCH: DB version mismatch libmdbx",
       "MDBX_INVALID: File is not an MDBX file",
       "MDBX_MAP_FULL: Environment mapsize limit reached",
-      "MDBX_DBS_FULL: Too may DBI-handles (maxdbs reached)",
+      "MDBX_DBS_FULL: Too many DBI-handles (maxdbs reached)",
       "MDBX_READERS_FULL: Too many readers (maxreaders reached)",
       NULL /* MDBX_TLS_FULL (-30789): unused in MDBX */,
       "MDBX_TXN_FULL: Transaction has too many dirty pages,"
diff --git a/plugins/Dbx_mdbx/src/dbcrypt.cpp b/plugins/Dbx_mdbx/src/dbcrypt.cpp
index 8cdc884c6f..75a630aa72 100644
--- a/plugins/Dbx_mdbx/src/dbcrypt.cpp
+++ b/plugins/Dbx_mdbx/src/dbcrypt.cpp
@@ -202,11 +202,15 @@ int CDbxMDBX::InitCrypt()
 	if (m_crypto != nullptr)
 		return 0;
 
-	txn_ptr_ro txn(m_txn_ro);
+	int rc;
+	MDBX_val key = { DBKey_Crypto_Provider, sizeof(DBKey_Crypto_Provider) }, value;
+	{
+		txn_ptr_ro txn(m_txn_ro);
+		rc = mdbx_get(txn, m_dbCrypto, &key, &value);
+	}
 
 	CRYPTO_PROVIDER *pProvider;
-	MDBX_val key = { DBKey_Crypto_Provider, sizeof(DBKey_Crypto_Provider) }, value;
-	if (mdbx_get(txn, m_dbCrypto, &key, &value) == MDBX_SUCCESS) {
+	if (rc == MDBX_SUCCESS) {
 		pProvider = Crypto_GetProvider((const char*)value.iov_base);
 		if (pProvider == nullptr)
 			pProvider = SelectProvider();
@@ -220,7 +224,12 @@ int CDbxMDBX::InitCrypt()
 		return 3;
 
 	key.iov_len = sizeof(DBKey_Crypto_Key); key.iov_base = DBKey_Crypto_Key;
-	if (mdbx_get(txn, m_dbCrypto, &key, &value) == MDBX_SUCCESS && (value.iov_len == m_crypto->getKeyLength())) {
+	{
+		txn_ptr_ro txn(m_txn_ro);
+		rc = mdbx_get(txn, m_dbCrypto, &key, &value);
+	}
+	
+	if (rc == MDBX_SUCCESS && (value.iov_len == m_crypto->getKeyLength())) {
 		if (!m_crypto->setKey((const BYTE*)value.iov_base, value.iov_len)) {
 			CEnterPasswordDialog dlg(this);
 			while (true) {
@@ -243,11 +252,13 @@ int CDbxMDBX::InitCrypt()
 	}
 
 	key.iov_len = sizeof(DBKey_Crypto_IsEncrypted); key.iov_base = DBKey_Crypto_IsEncrypted;
-
-	if (mdbx_get(txn, m_dbCrypto, &key, &value) == MDBX_SUCCESS)
-		m_bEncrypted = *(const bool*)value.iov_base;
-	else
-		m_bEncrypted = false;
+	{
+		txn_ptr_ro txn(m_txn_ro);
+		if (mdbx_get(txn, m_dbCrypto, &key, &value) == MDBX_SUCCESS)
+			m_bEncrypted = *(const bool *)value.iov_base;
+		else
+			m_bEncrypted = false;
+	}
 
 	InitDialogs();
 	return 0;
-- 
cgit v1.2.3