From e9d411deec5a4384d1a19159354c6996220c05f0 Mon Sep 17 00:00:00 2001 From: Paul Shapiro Date: Mon, 12 Nov 2018 16:04:36 -0600 Subject: [PATCH] updated monero_wallet_utils::decoded_seed with support to sanitize mnemonic string input with redundant and illegal whitespace chars, and updated tests; fixed bug in same function which prevented to_lower() call from being effective --- src/monero_wallet_utils.cpp | 21 +++++++++++++++++---- test/test_all.cpp | 5 +++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/monero_wallet_utils.cpp b/src/monero_wallet_utils.cpp index 2fa492d..d75be99 100644 --- a/src/monero_wallet_utils.cpp +++ b/src/monero_wallet_utils.cpp @@ -163,23 +163,36 @@ bool monero_wallet_utils::are_equal_mnemonics(const string &words_a, const strin const uint32_t stable_32B_seed_mnemonic_word_count = 25; const uint32_t legacy_16B_seed_mnemonic_word_count = 13; +bool _areBothSpaceChars(char lhs, char rhs) { + return lhs == rhs && lhs == ' '; +} bool monero_wallet_utils::decoded_seed( - const epee::wipeable_string &mnemonic_string__ref, + const epee::wipeable_string &arg__mnemonic_string__ref, MnemonicDecodedSeed_RetVals &retVals ) { retVals = {}; // // sanitize inputs - if (mnemonic_string__ref.empty()) { + if (arg__mnemonic_string__ref.empty()) { retVals.did_error = true; retVals.err_string = "Please enter a valid seed"; // return false; } - string mnemonic_string = string(mnemonic_string__ref.data(), mnemonic_string__ref.size()); // just going to take a copy rather than require people to pass mutable string in. + string mnemonic_string = string(arg__mnemonic_string__ref.data(), arg__mnemonic_string__ref.size()); // just going to take a copy rather than require people to pass mutable string in. + // input sanitization boost::algorithm::to_lower(mnemonic_string); // critical - // TODO: strip wrapping whitespace? anything else? // + // converting undesireable whitespace chars to spaces, then removing redundant spaces (this ensures "word\nword"->"word word" + std::replace(mnemonic_string.begin(), mnemonic_string.end(), '\r', ' '); + std::replace(mnemonic_string.begin(), mnemonic_string.end(), '\n', ' '); + std::replace(mnemonic_string.begin(), mnemonic_string.end(), '\t', ' '); + std::string::iterator new_end = std::unique(mnemonic_string.begin(), mnemonic_string.end(), _areBothSpaceChars); + mnemonic_string.erase(new_end, mnemonic_string.end()); + // + // FIXME: any other input sanitization to do here? + // + const epee::wipeable_string &mnemonic_string__ref = mnemonic_string; // re-obtain wipeable_string ref std::stringstream stream(mnemonic_string); // to count words… unsigned long word_count = std::distance(std::istream_iterator(stream), std::istream_iterator()); // unsigned long word_count = boost::range::distance(boost::algorithm::make_split_iterator(mnemonic_string, boost::algorithm::is_space())); // TODO: get this workin diff --git a/test/test_all.cpp b/test/test_all.cpp index 20927d3..f33b964 100644 --- a/test/test_all.cpp +++ b/test/test_all.cpp @@ -687,7 +687,7 @@ BOOST_AUTO_TEST_CASE(bridged__are_equal_mnemonics) // boost::property_tree::ptree root; root.put("a", "foxe selfish hum nexus juven dodeg pepp ember biscuti elap jazz vibrate biscui"); - root.put("b", "fox sel hum nex juv dod pep emb bis ela jaz vib bis"); + root.put("b", "fox sel hum nex juv\r \ndod pep emb bis ela jaz vib bis"); // auto ret_string = serial_bridge::are_equal_mnemonics(args_string_from_root(root)); stringstream ret_stream; @@ -732,7 +732,7 @@ BOOST_AUTO_TEST_CASE(bridged__seed_and_keys_from_mnemonic) using namespace serial_bridge; // boost::property_tree::ptree root; - root.put("mnemonic_string", "foxe selfish hum nexus juven dodeg pepp ember biscuti elap jazz vibrate biscui"); + root.put("mnemonic_string", "foxe selfish\n\r \t hum nexus juven dodeg pepp \r\n\r\n ember biscuti elap jazz vibrate biscui"); root.put("nettype_string", string_from_nettype(MAINNET)); // auto ret_string = serial_bridge::seed_and_keys_from_mnemonic(args_string_from_root(root)); @@ -756,6 +756,7 @@ BOOST_AUTO_TEST_CASE(bridged__seed_and_keys_from_mnemonic) BOOST_REQUIRE(address_string != none); BOOST_REQUIRE((*address_string).size() > 0); cout << "bridged__seed_and_keys_from_mnemonic: address: " << *address_string << endl; + BOOST_REQUIRE((*address_string) == "43zxvpcj5Xv9SEkNXbMCG7LPQStHMpFCQCmkmR4u5nzjWwq5Xkv5VmGgYEsHXg4ja2FGRD5wMWbBVMijDTqmmVqm93wHGkg"); optional pub_viewKey_string = ret_tree.get_optional(ret_json_key__pub_viewKey_string()); BOOST_REQUIRE(pub_viewKey_string != none); BOOST_REQUIRE((*pub_viewKey_string).size() > 0);