aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.cpp4
-rw-r--r--src/common/password.cpp34
-rw-r--r--src/common/util.cpp28
-rw-r--r--src/common/util.h3
-rw-r--r--src/simplewallet/simplewallet.cpp50
-rw-r--r--src/wallet/api/wallet.cpp21
6 files changed, 73 insertions, 67 deletions
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp
index 824598f8c..bd91f308a 100644
--- a/src/blockchain_db/lmdb/db_lmdb.cpp
+++ b/src/blockchain_db/lmdb/db_lmdb.cpp
@@ -649,7 +649,7 @@ uint64_t BlockchainLMDB::get_estimated_batch_size(uint64_t batch_num_blocks, uin
{
MDB_txn *rtxn;
mdb_txn_cursors *rcurs;
- block_rtxn_start(&rtxn, &rcurs);
+ bool my_rtxn = block_rtxn_start(&rtxn, &rcurs);
for (uint64_t block_num = block_start; block_num <= block_stop; ++block_num)
{
// we have access to block weight, which will be greater or equal to block size,
@@ -661,7 +661,7 @@ uint64_t BlockchainLMDB::get_estimated_batch_size(uint64_t batch_num_blocks, uin
// some blocks were to be skipped for being outliers.
++num_blocks_used;
}
- block_rtxn_stop();
+ if (my_rtxn) block_rtxn_stop();
avg_block_size = total_block_size / num_blocks_used;
MDEBUG("average block size across recent " << num_blocks_used << " blocks: " << avg_block_size);
}
diff --git a/src/common/password.cpp b/src/common/password.cpp
index b32bedae2..a8d5141dc 100644
--- a/src/common/password.cpp
+++ b/src/common/password.cpp
@@ -56,8 +56,6 @@ namespace
bool read_from_tty(epee::wipeable_string& pass, bool hide_input)
{
- static constexpr const char BACKSPACE = 8;
-
HANDLE h_cin = ::GetStdHandle(STD_INPUT_HANDLE);
DWORD mode_old;
@@ -67,32 +65,46 @@ namespace
bool r = true;
pass.reserve(tools::password_container::max_password_size);
+ std::vector<int> chlen;
+ chlen.reserve(tools::password_container::max_password_size);
while (pass.size() < tools::password_container::max_password_size)
{
DWORD read;
- char ch;
- r = (TRUE == ::ReadConsoleA(h_cin, &ch, 1, &read, NULL));
+ wchar_t ucs2_ch;
+ r = (TRUE == ::ReadConsoleW(h_cin, &ucs2_ch, 1, &read, NULL));
r &= (1 == read);
+
if (!r)
{
break;
}
- else if (ch == '\n' || ch == '\r')
+ else if (ucs2_ch == L'\n' || ucs2_ch == L'\r')
{
std::cout << std::endl;
break;
}
- else if (ch == BACKSPACE)
+ else if (ucs2_ch == L'\b')
{
if (!pass.empty())
{
- pass.pop_back();
+ int len = chlen.back();
+ chlen.pop_back();
+ while(len-- > 0)
+ pass.pop_back();
}
+ continue;
}
- else
- {
- pass.push_back(ch);
- }
+
+ char utf8_ch[8] = {0};
+ int len;
+ if((len = WideCharToMultiByte(CP_UTF8, 0, &ucs2_ch, 1, utf8_ch, sizeof(utf8_ch), NULL, NULL)) <= 0)
+ break;
+
+ if(pass.size() + len >= tools::password_container::max_password_size)
+ break;
+
+ chlen.push_back(len);
+ pass += utf8_ch;
}
::SetConsoleMode(h_cin, mode_old);
diff --git a/src/common/util.cpp b/src/common/util.cpp
index c56c77505..2a1d49af0 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -939,4 +939,32 @@ std::string get_nix_version_display_string()
}
return newval;
}
+
+#ifdef _WIN32
+ std::string input_line_win()
+ {
+ HANDLE hConIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
+ DWORD oldMode;
+
+ FlushConsoleInputBuffer(hConIn);
+ GetConsoleMode(hConIn, &oldMode);
+ SetConsoleMode(hConIn, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT);
+
+ wchar_t buffer[1024];
+ DWORD read;
+
+ ReadConsoleW(hConIn, buffer, sizeof(buffer)/sizeof(wchar_t)-1, &read, nullptr);
+ buffer[read] = 0;
+
+ SetConsoleMode(hConIn, oldMode);
+ CloseHandle(hConIn);
+
+ int size_needed = WideCharToMultiByte(CP_UTF8, 0, buffer, -1, NULL, 0, NULL, NULL);
+ std::string buf(size_needed, '\0');
+ WideCharToMultiByte(CP_UTF8, 0, buffer, -1, &buf[0], size_needed, NULL, NULL);
+ buf.pop_back(); //size_needed includes null that we needed to have space for
+ return buf;
+ }
+#endif
+
}
diff --git a/src/common/util.h b/src/common/util.h
index 0e0b50520..ce773bd38 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -235,4 +235,7 @@ namespace tools
boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str);
std::string glob_to_regex(const std::string &val);
+#ifdef _WIN32
+ std::string input_line_win();
+#endif
}
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 90f8535d7..a1d6eb590 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -137,47 +137,6 @@ namespace
const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""};
-#ifdef WIN32
- // Translate from CP850 to UTF-8;
- // std::getline for a Windows console returns a string in CP437 or CP850; as simplewallet,
- // like all of Monero, is assumed to work internally with UTF-8 throughout, even on Windows
- // (although only implemented partially), a translation to UTF-8 is needed for input.
- //
- // Note that if a program is started inside the MSYS2 shell somebody already translates
- // console input to UTF-8, but it's not clear how one could detect that in order to avoid
- // double-translation; this code here thus breaks UTF-8 input within a MSYS2 shell,
- // unfortunately.
- //
- // Note also that input for passwords is NOT translated, to remain compatible with any
- // passwords containing special characters that predate this switch to UTF-8 support.
- template<typename T>
- static T cp850_to_utf8(const T &cp850_str)
- {
- boost::locale::generator gen;
- gen.locale_cache_enabled(true);
- std::locale loc = gen("en_US.CP850");
- const boost::locale::conv::method_type how = boost::locale::conv::default_method;
- T result;
- const char *begin = cp850_str.data();
- const char *end = begin + cp850_str.size();
- result.reserve(end-begin);
- typedef std::back_insert_iterator<T> inserter_type;
- inserter_type inserter(result);
- boost::locale::utf::code_point c;
- while(begin!=end) {
- c=boost::locale::utf::utf_traits<char>::template decode<char const *>(begin,end);
- if(c==boost::locale::utf::illegal || c==boost::locale::utf::incomplete) {
- if(how==boost::locale::conv::stop)
- throw boost::locale::conv::conversion_error();
- }
- else {
- boost::locale::utf::utf_traits<char>::template encode<inserter_type>(c,inserter);
- }
- }
- return result;
- }
-#endif
-
std::string input_line(const std::string& prompt)
{
#ifdef HAVE_READLINE
@@ -186,9 +145,10 @@ namespace
std::cout << prompt;
std::string buf;
+#ifdef _WIN32
+ buf = tools::input_line_win();
+#else
std::getline(std::cin, buf);
-#ifdef WIN32
- buf = cp850_to_utf8(buf);
#endif
return epee::string_tools::trim(buf);
@@ -208,10 +168,6 @@ namespace
epee::wipeable_string buf = pwd_container->password();
-#ifdef WIN32
- buf = cp850_to_utf8(buf);
-#endif
-
buf.trim();
return buf;
}
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 236928348..58a6db689 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -96,6 +96,9 @@ namespace {
throw runtime_error("Multisig wallet is not finalized yet");
}
}
+ void checkMultisigWalletReady(const std::unique_ptr<tools::wallet2> &wallet) {
+ return checkMultisigWalletReady(wallet.get());
+ }
void checkMultisigWalletNotReady(const tools::wallet2* wallet) {
if (!wallet) {
@@ -111,6 +114,9 @@ namespace {
throw runtime_error("Multisig wallet is already finalized");
}
}
+ void checkMultisigWalletNotReady(const std::unique_ptr<tools::wallet2> &wallet) {
+ return checkMultisigWalletNotReady(wallet.get());
+ }
}
struct Wallet2CallbackImpl : public tools::i_wallet2_callback
@@ -376,15 +382,15 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds)
, m_rebuildWalletCache(false)
, m_is_connected(false)
{
- m_wallet = std::make_unique<tools::wallet2>(static_cast<cryptonote::network_type>(nettype), kdf_rounds, true);
- m_history = std::make_unique<TransactionHistoryImpl>(this);
- m_wallet2Callback = std::make_unique<Wallet2CallbackImpl>(this);
- m_wallet->callback(m_wallet2Callback);
+ m_wallet.reset(new tools::wallet2(static_cast<cryptonote::network_type>(nettype), kdf_rounds, true));
+ m_history.reset(new TransactionHistoryImpl(this));
+ m_wallet2Callback.reset(new Wallet2CallbackImpl(this));
+ m_wallet->callback(m_wallet2Callback.get());
m_refreshThreadDone = false;
m_refreshEnabled = false;
- m_addressBook = std::make_unique<AddressBookImpl>(this);
- m_subaddress = std::make_unique<SubaddressImpl>(this);
- m_subaddressAccount = std::make_unique<SubaddressAccountImpl>(this);
+ m_addressBook.reset(new AddressBookImpl(this));
+ m_subaddress.reset(new SubaddressImpl(this));
+ m_subaddressAccount.reset(new SubaddressAccountImpl(this));
m_refreshIntervalMillis = DEFAULT_REFRESH_INTERVAL_MILLIS;
@@ -399,6 +405,7 @@ WalletImpl::~WalletImpl()
{
LOG_PRINT_L1(__FUNCTION__);
+ m_wallet->callback(NULL);
// Pause refresh thread - prevents refresh from starting again
pauseRefresh();
// Close wallet - stores cache and stops ongoing refresh operation