diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.cpp | 4 | ||||
-rw-r--r-- | src/common/password.cpp | 34 | ||||
-rw-r--r-- | src/common/util.cpp | 28 | ||||
-rw-r--r-- | src/common/util.h | 3 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 50 | ||||
-rw-r--r-- | src/wallet/api/wallet.cpp | 21 |
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 |