add empty container sanity checks when using front() and back()

This commit is contained in:
moneromooo-monero 2017-12-11 22:36:58 +00:00
parent 56fa6ce15f
commit 45a1c4c088
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
9 changed files with 32 additions and 6 deletions

View file

@ -305,7 +305,7 @@ namespace net_utils
m_connections.back().powner = this; m_connections.back().powner = this;
m_connections.back().m_self_it = --m_connections.end(); m_connections.back().m_self_it = --m_connections.end();
m_connections.back().m_context.m_remote_address = remote_address; m_connections.back().m_context.m_remote_address = remote_address;
m_connections.back().m_htread = threads_helper::create_thread(ConnectionHandlerProc, &m_connections.back()); m_connections.back().m_htread = threads_helper::create_thread(ConnectionHandlerProc, &m_connections.back()); // ugh, seems very risky
return true; return true;
} }

View file

@ -62,6 +62,7 @@ void block_queue::add_blocks(uint64_t height, std::list<cryptonote::block_comple
void block_queue::add_blocks(uint64_t height, uint64_t nblocks, const boost::uuids::uuid &connection_id, boost::posix_time::ptime time) void block_queue::add_blocks(uint64_t height, uint64_t nblocks, const boost::uuids::uuid &connection_id, boost::posix_time::ptime time)
{ {
CHECK_AND_ASSERT_THROW_MES(nblocks > 0, "Empty span");
boost::unique_lock<boost::recursive_mutex> lock(mutex); boost::unique_lock<boost::recursive_mutex> lock(mutex);
blocks.insert(span(height, nblocks, connection_id, time)); blocks.insert(span(height, nblocks, connection_id, time));
} }

View file

@ -1003,6 +1003,11 @@ skip:
MDEBUG(context << " next span in the queue has blocks " << start_height << "-" << (start_height + blocks.size() - 1) MDEBUG(context << " next span in the queue has blocks " << start_height << "-" << (start_height + blocks.size() - 1)
<< ", we need " << previous_height); << ", we need " << previous_height);
if (blocks.empty())
{
MERROR("Next span has no blocks");
break;
}
block new_block; block new_block;
if (!parse_and_validate_block_from_blob(blocks.front().block, new_block)) if (!parse_and_validate_block_from_blob(blocks.front().block, new_block))
@ -1498,6 +1503,7 @@ skip:
NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized<NOTIFY_REQUEST_CHAIN::request>(); NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized<NOTIFY_REQUEST_CHAIN::request>();
m_core.get_short_chain_history(r.block_ids); m_core.get_short_chain_history(r.block_ids);
CHECK_AND_ASSERT_MES(!r.block_ids.empty(), false, "Short chain history is empty");
if (!start_from_current_chain) if (!start_from_current_chain)
{ {

View file

@ -205,6 +205,8 @@ namespace
*/ */
bool checksum_test(std::vector<std::string> seed, uint32_t unique_prefix_length) bool checksum_test(std::vector<std::string> seed, uint32_t unique_prefix_length)
{ {
if (seed.empty())
return false;
// The last word is the checksum. // The last word is the checksum.
std::string last_word = seed.back(); std::string last_word = seed.back();
seed.pop_back(); seed.pop_back();

View file

@ -492,6 +492,11 @@ namespace cryptonote
{ {
if (std::find(missed_txs.begin(), missed_txs.end(), h) == missed_txs.end()) if (std::find(missed_txs.begin(), missed_txs.end(), h) == missed_txs.end())
{ {
if (txs.empty())
{
res.status = "Failed: internal error - txs is empty";
return true;
}
// core returns the ones it finds in the right order // core returns the ones it finds in the right order
if (get_transaction_hash(txs.front()) != h) if (get_transaction_hash(txs.front()) != h)
{ {
@ -1150,7 +1155,7 @@ namespace cryptonote
error_resp.message = "Internal error: can't get block by hash. Hash = " + req.hash + '.'; error_resp.message = "Internal error: can't get block by hash. Hash = " + req.hash + '.';
return false; return false;
} }
if (blk.miner_tx.vin.front().type() != typeid(txin_gen)) if (blk.miner_tx.vin.size() != 1 || blk.miner_tx.vin.front().type() != typeid(txin_gen))
{ {
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Internal error: coinbase transaction in the block has the wrong type"; error_resp.message = "Internal error: coinbase transaction in the block has the wrong type";
@ -1188,7 +1193,7 @@ namespace cryptonote
error_resp.message = "Internal error: can't get block by height. Height = " + boost::lexical_cast<std::string>(h) + ". Hash = " + epee::string_tools::pod_to_hex(block_hash) + '.'; error_resp.message = "Internal error: can't get block by height. Height = " + boost::lexical_cast<std::string>(h) + ". Hash = " + epee::string_tools::pod_to_hex(block_hash) + '.';
return false; return false;
} }
if (blk.miner_tx.vin.front().type() != typeid(txin_gen)) if (blk.miner_tx.vin.size() != 1 || blk.miner_tx.vin.front().type() != typeid(txin_gen))
{ {
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Internal error: coinbase transaction in the block has the wrong type"; error_resp.message = "Internal error: coinbase transaction in the block has the wrong type";
@ -1274,7 +1279,7 @@ namespace cryptonote
error_resp.message = "Internal error: can't get block by hash. Hash = " + req.hash + '.'; error_resp.message = "Internal error: can't get block by hash. Hash = " + req.hash + '.';
return false; return false;
} }
if (blk.miner_tx.vin.front().type() != typeid(txin_gen)) if (blk.miner_tx.vin.size() != 1 || blk.miner_tx.vin.front().type() != typeid(txin_gen))
{ {
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Internal error: coinbase transaction in the block has the wrong type"; error_resp.message = "Internal error: coinbase transaction in the block has the wrong type";

View file

@ -799,6 +799,10 @@ namespace rpc
} }
header.hash = hash_in; header.hash = hash_in;
if (b.miner_tx.vin.size() != 1 || b.miner_tx.vin.front().type() != typeid(txin_gen))
{
return false;
}
header.height = boost::get<txin_gen>(b.miner_tx.vin.front()).height; header.height = boost::get<txin_gen>(b.miner_tx.vin.front()).height;
header.major_version = b.major_version; header.major_version = b.major_version;

View file

@ -4321,9 +4321,9 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
fail_msg_writer() << tr("Multiple transactions are created, which is not supposed to happen"); fail_msg_writer() << tr("Multiple transactions are created, which is not supposed to happen");
return true; return true;
} }
if (ptx_vector[0].selected_transfers.size() > 1) if (ptx_vector[0].selected_transfers.size() != 1)
{ {
fail_msg_writer() << tr("The transaction uses multiple inputs, which is not supposed to happen"); fail_msg_writer() << tr("The transaction uses multiple or no inputs, which is not supposed to happen");
return true; return true;
} }

View file

@ -4950,6 +4950,7 @@ bool wallet2::tx_add_fake_output(std::vector<std::vector<tools::wallet2::get_out
if (global_index == real_index) // don't re-add real one if (global_index == real_index) // don't re-add real one
return false; return false;
auto item = std::make_tuple(global_index, tx_public_key, mask); auto item = std::make_tuple(global_index, tx_public_key, mask);
CHECK_AND_ASSERT_MES(!outs.empty(), false, "internal error: outs is empty");
if (std::find(outs.back().begin(), outs.back().end(), item) != outs.back().end()) // don't add duplicates if (std::find(outs.back().begin(), outs.back().end(), item) != outs.back().end()) // don't add duplicates
return false; return false;
outs.back().push_back(item); outs.back().push_back(item);

View file

@ -602,6 +602,13 @@ namespace tools
uint64_t mixin = m_wallet->adjust_mixin(req.mixin); uint64_t mixin = m_wallet->adjust_mixin(req.mixin);
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, req.priority, extra, req.account_index, req.subaddr_indices, m_trusted_daemon); std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, req.unlock_time, req.priority, extra, req.account_index, req.subaddr_indices, m_trusted_daemon);
if (ptx_vector.empty())
{
er.code = WALLET_RPC_ERROR_CODE_TX_NOT_POSSIBLE;
er.message = "No transaction created";
return false;
}
// reject proposed transactions if there are more than one. see on_transfer_split below. // reject proposed transactions if there are more than one. see on_transfer_split below.
if (ptx_vector.size() != 1) if (ptx_vector.size() != 1)
{ {