forked from lthn/blockchain
added sanitizing of utf8 in plain wallet, removed unnecessary rpc calls from get recent history
This commit is contained in:
parent
09c3c2c156
commit
3ad96b5028
6 changed files with 161 additions and 34 deletions
|
|
@ -840,5 +840,113 @@ std::string get_nix_version_display_string()
|
|||
return pr.first + " " + pr.second;
|
||||
}
|
||||
|
||||
// Replaces invalid UTF-8 sequences with the UTF-8 replacement character (U+FFFD).
|
||||
// If the original string is already valid UTF-8, it remains untouched.
|
||||
// Returns true if the function modified the string, false otherwise.
|
||||
bool sanitize_utf8(std::string& str_to_sanitize) {
|
||||
const unsigned char* data = reinterpret_cast<const unsigned char*>(str_to_sanitize.data());
|
||||
const unsigned char* end = data + str_to_sanitize.size();
|
||||
|
||||
std::string output; // remains empty unless invalid data is found
|
||||
bool foundInvalid = false;
|
||||
|
||||
// We'll track where the last "valid segment" started.
|
||||
const unsigned char* segmentStart = data;
|
||||
|
||||
// Helper lambda to append the replacement character U+FFFD (0xEF 0xBF 0xBD).
|
||||
auto appendReplacementChar = [&](const unsigned char* pos) {
|
||||
// If this is our first detected invalid sequence, start building 'output'.
|
||||
// - Copy everything from segmentStart to 'pos' (not inclusive).
|
||||
if (!foundInvalid) {
|
||||
foundInvalid = true;
|
||||
// Reserve approximate space to avoid repeated allocations
|
||||
output.reserve(str_to_sanitize.size());
|
||||
output.append(reinterpret_cast<const char*>(segmentStart),
|
||||
reinterpret_cast<const char*>(pos));
|
||||
}
|
||||
// Append the UTF-8 replacement character
|
||||
output.append("\xEF\xBF\xBD");
|
||||
};
|
||||
|
||||
while (data < end) {
|
||||
unsigned char c = *data;
|
||||
int extraBytes = 0;
|
||||
|
||||
// 1) Determine how many bytes the current sequence should have,
|
||||
// based on the leading byte.
|
||||
if ((c & 0x80) == 0) {
|
||||
// 1-byte sequence (ASCII)
|
||||
extraBytes = 0;
|
||||
}
|
||||
else if ((c & 0xE0) == 0xC0) {
|
||||
// 2-byte sequence
|
||||
extraBytes = 1;
|
||||
}
|
||||
else if ((c & 0xF0) == 0xE0) {
|
||||
// 3-byte sequence
|
||||
extraBytes = 2;
|
||||
}
|
||||
else if ((c & 0xF8) == 0xF0) {
|
||||
// 4-byte sequence
|
||||
extraBytes = 3;
|
||||
}
|
||||
else {
|
||||
// Invalid leading byte
|
||||
appendReplacementChar(data);
|
||||
data++;
|
||||
// Next segment of "known good" data starts after this invalid byte
|
||||
segmentStart = data;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 2) Check that we have enough bytes left in the string
|
||||
if (data + extraBytes >= end) {
|
||||
// We don't have enough continuation bytes for a complete sequence
|
||||
appendReplacementChar(data);
|
||||
// Nothing more we can parse, so we're done
|
||||
data = end;
|
||||
break;
|
||||
}
|
||||
|
||||
// 3) Validate the continuation bytes, which must match 10xxxxxx
|
||||
bool invalidContinuation = false;
|
||||
for (int i = 1; i <= extraBytes; ++i) {
|
||||
if ((data[i] & 0xC0) != 0x80) {
|
||||
invalidContinuation = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (invalidContinuation) {
|
||||
// One or more continuation bytes are invalid
|
||||
appendReplacementChar(data);
|
||||
data++;
|
||||
segmentStart = data;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we reach here, (c + continuation) forms a valid UTF-8 sequence
|
||||
data += (extraBytes + 1);
|
||||
}
|
||||
|
||||
// If we never encountered invalid data, 'foundInvalid' is false.
|
||||
// In that case, we do nothing and simply return false.
|
||||
if (!foundInvalid) {
|
||||
return false; // No change was made
|
||||
}
|
||||
|
||||
// Otherwise, we need to copy the last valid segment (if any) into 'output'.
|
||||
// This covers the data from 'segmentStart' to the end.
|
||||
if (segmentStart < end) {
|
||||
output.append(reinterpret_cast<const char*>(segmentStart),
|
||||
reinterpret_cast<const char*>(end));
|
||||
}
|
||||
|
||||
// Now replace the original string with our sanitized version
|
||||
str_to_sanitize.swap(output);
|
||||
|
||||
// Indicate we performed a modification
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace tools
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ namespace tools
|
|||
std::error_code replace_file(const std::string& replacement_name, const std::string& replaced_name);
|
||||
uint64_t get_total_system_memory();
|
||||
std::string pretty_print_big_nums(std::uint64_t num);
|
||||
bool sanitize_utf8(std::string& input);
|
||||
std::pair<std::string, std::string> pretty_print_big_nums_to_pair(std::uint64_t num);
|
||||
|
||||
inline crypto::hash get_proof_of_trust_hash(const nodetool::proof_of_trust& pot)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@ namespace tools
|
|||
core_fast_rpc_proxy(currency::core_rpc_server& rpc_srv) :m_rpc(rpc_srv)
|
||||
{}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
virtual bool is_daemon_inbox()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
virtual bool set_connection_addr(const std::string& url) override
|
||||
{
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ namespace tools
|
|||
std::shared_ptr<proxy_diagnostic_info> get_editable_proxy_diagnostic_info() { return m_pdiganostic_info; }
|
||||
virtual bool get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id){ return false; }
|
||||
virtual void set_connectivity(unsigned int connection_timeout, size_t repeats_count) {}
|
||||
// This method determines if the daemons share the same address space as the caller (which may help decide if some RPC calls can be skipped).
|
||||
virtual bool is_daemon_inbox() { return false; }
|
||||
protected:
|
||||
std::shared_ptr<proxy_diagnostic_info> m_pdiganostic_info;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
LOG_ERROR("Core already deinitialised or not initialized yet."); \
|
||||
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response); \
|
||||
ok_response.result.return_code = API_RETURN_CODE_UNINITIALIZED; \
|
||||
return epee::serialization::store_t_to_json(ok_response); \
|
||||
return sanitized_store_to_json(ok_response); \
|
||||
}
|
||||
namespace plain_wallet
|
||||
{
|
||||
|
|
@ -80,6 +80,13 @@ namespace plain_wallet
|
|||
|
||||
typedef epee::json_rpc::response<epee::json_rpc::dummy_result, error> error_response;
|
||||
|
||||
template<class t_struct>
|
||||
std::string sanitized_store_to_json(const t_struct& t_obj)
|
||||
{
|
||||
std::string r = epee::serialization::store_t_to_json(t_obj);
|
||||
tools::sanitize_utf8(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string get_set_working_dir(bool need_to_set = false, const std::string val = "")
|
||||
{
|
||||
|
|
@ -182,7 +189,7 @@ namespace plain_wallet
|
|||
inst_ptr->gwm.quick_clear_wallets_no_save();
|
||||
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
ok_response.result.return_code = API_RETURN_CODE_OK;
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
return sanitized_store_to_json(ok_response);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -197,7 +204,7 @@ namespace plain_wallet
|
|||
LOG_ERROR("Double-initialization in plain_wallet detected.");
|
||||
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
ok_response.result.return_code = API_RETURN_CODE_ALREADY_EXISTS;
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
return sanitized_store_to_json(ok_response);
|
||||
}
|
||||
|
||||
epee::static_helpers::set_or_call_on_destruct(true, static_destroy_handler);
|
||||
|
|
@ -254,7 +261,7 @@ namespace plain_wallet
|
|||
error_response err_result = AUTO_VAL_INIT(err_result);
|
||||
err_result.error.code = API_RETURN_CODE_INTERNAL_ERROR;
|
||||
err_result.error.message = LOCATION_STR + " \nmessage:" + ec.message();
|
||||
return epee::serialization::store_t_to_json(err_result);
|
||||
return sanitized_store_to_json(err_result);
|
||||
}
|
||||
|
||||
std::string app_config_folder = get_app_config_folder();
|
||||
|
|
@ -264,14 +271,14 @@ namespace plain_wallet
|
|||
error_response err_result = AUTO_VAL_INIT(err_result);
|
||||
err_result.error.code = API_RETURN_CODE_INTERNAL_ERROR;
|
||||
err_result.error.message = LOCATION_STR + " \nmessage:" + ec.message();
|
||||
return epee::serialization::store_t_to_json(err_result);
|
||||
return sanitized_store_to_json(err_result);
|
||||
}
|
||||
#endif
|
||||
std::atomic_store(&ginstance_ptr, ptr);
|
||||
#ifndef CAKEWALLET
|
||||
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
ok_response.result.return_code = API_RETURN_CODE_OK;
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
return sanitized_store_to_json(ok_response);
|
||||
#else
|
||||
return API_RETURN_CODE_OK;
|
||||
#endif
|
||||
|
|
@ -299,7 +306,7 @@ namespace plain_wallet
|
|||
{
|
||||
error_response err_result = AUTO_VAL_INIT(err_result);
|
||||
err_result.error.code = ret_code;
|
||||
return epee::serialization::store_t_to_json(err_result);
|
||||
return sanitized_store_to_json(err_result);
|
||||
}
|
||||
return res_str;
|
||||
}
|
||||
|
|
@ -311,13 +318,13 @@ namespace plain_wallet
|
|||
{
|
||||
error_response err_result = AUTO_VAL_INIT(err_result);
|
||||
err_result.error.code = ret_code;
|
||||
return epee::serialization::store_t_to_json(err_result);
|
||||
return sanitized_store_to_json(err_result);
|
||||
}
|
||||
else
|
||||
{
|
||||
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
ok_response.result.return_code = API_RETURN_CODE_OK;
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
return sanitized_store_to_json(ok_response);
|
||||
}
|
||||
}
|
||||
bool is_wallet_exist(const std::string& path)
|
||||
|
|
@ -344,7 +351,7 @@ namespace plain_wallet
|
|||
epee::log_space::log_singletone::truncate_log_files();
|
||||
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
ok_response.result.return_code = API_RETURN_CODE_OK;
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
return sanitized_store_to_json(ok_response);
|
||||
}
|
||||
|
||||
std::string get_connectivity_status()
|
||||
|
|
@ -374,7 +381,7 @@ namespace plain_wallet
|
|||
std::string wallet_files_path = get_wallets_folder();
|
||||
strings_list sl = AUTO_VAL_INIT(sl);
|
||||
epee::file_io_utils::get_folder_content(wallet_files_path, sl.items, true);
|
||||
return epee::serialization::store_t_to_json(sl);
|
||||
return sanitized_store_to_json(sl);
|
||||
}
|
||||
|
||||
std::string get_export_private_info(const std::string& target_dir)
|
||||
|
|
@ -388,18 +395,18 @@ namespace plain_wallet
|
|||
LOG_ERROR("Failed to create target directory(" << full_target_path << "):" << ec.message());
|
||||
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
ok_response.result.return_code = API_RETURN_CODE_FAIL;
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
return sanitized_store_to_json(ok_response);
|
||||
}
|
||||
if(!tools::copy_dir(src_folder_path, full_target_path))
|
||||
{
|
||||
LOG_ERROR("Failed to copy target directory");
|
||||
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
ok_response.result.return_code = API_RETURN_CODE_FAIL;
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
return sanitized_store_to_json(ok_response);
|
||||
}
|
||||
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
ok_response.result.return_code = API_RETURN_CODE_OK;
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
return sanitized_store_to_json(ok_response);
|
||||
}
|
||||
|
||||
std::string delete_wallet(const std::string& file_name)
|
||||
|
|
@ -410,7 +417,7 @@ namespace plain_wallet
|
|||
boost::filesystem::remove(wallet_files_path + file_name, er);
|
||||
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
ok_response.result.return_code = API_RETURN_CODE_OK;
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
return sanitized_store_to_json(ok_response);
|
||||
}
|
||||
|
||||
std::string get_address_info(const std::string& addr)
|
||||
|
|
@ -463,11 +470,11 @@ namespace plain_wallet
|
|||
inst_ptr->gwm.run_wallet(ok_response.result.wallet_id);
|
||||
}
|
||||
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
return sanitized_store_to_json(ok_response);
|
||||
}
|
||||
error_response err_result = AUTO_VAL_INIT(err_result);
|
||||
err_result.error.code = rsp;
|
||||
return epee::serialization::store_t_to_json(err_result);
|
||||
return sanitized_store_to_json(err_result);
|
||||
}
|
||||
|
||||
std::string restore(const std::string& seed, const std::string& path, const std::string& password, const std::string& seed_password)
|
||||
|
|
@ -487,11 +494,11 @@ namespace plain_wallet
|
|||
{
|
||||
inst_ptr->gwm.run_wallet(ok_response.result.wallet_id);
|
||||
}
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
return sanitized_store_to_json(ok_response);
|
||||
}
|
||||
error_response err_result = AUTO_VAL_INIT(err_result);
|
||||
err_result.error.code = rsp;
|
||||
return epee::serialization::store_t_to_json(err_result);
|
||||
return sanitized_store_to_json(err_result);
|
||||
}
|
||||
|
||||
std::string generate(const std::string& path, const std::string& password)
|
||||
|
|
@ -511,11 +518,11 @@ namespace plain_wallet
|
|||
{
|
||||
inst_ptr->gwm.run_wallet(ok_response.result.wallet_id);
|
||||
}
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
return sanitized_store_to_json(ok_response);
|
||||
}
|
||||
error_response err_result = AUTO_VAL_INIT(err_result);
|
||||
err_result.error.code = rsp;
|
||||
return epee::serialization::store_t_to_json(err_result);
|
||||
return sanitized_store_to_json(err_result);
|
||||
}
|
||||
|
||||
std::string get_opened_wallets()
|
||||
|
|
@ -523,7 +530,7 @@ namespace plain_wallet
|
|||
GET_INSTANCE_PTR(inst_ptr);
|
||||
epee::json_rpc::response<std::list<view::open_wallet_response>, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
inst_ptr->gwm.get_opened_wallets(ok_response.result);
|
||||
return epee::serialization::store_t_to_json(ok_response);
|
||||
return sanitized_store_to_json(ok_response);
|
||||
}
|
||||
|
||||
std::string close_wallet(hwallet h)
|
||||
|
|
@ -588,7 +595,7 @@ namespace plain_wallet
|
|||
|
||||
view::api_response ar = AUTO_VAL_INIT(ar);
|
||||
ar.error_code = API_RETURN_CODE_OK;
|
||||
return epee::serialization::store_t_to_json(ar);
|
||||
return sanitized_store_to_json(ar);
|
||||
}
|
||||
|
||||
std::string handle_run_wallet(uint64_t instance_id)
|
||||
|
|
@ -609,7 +616,7 @@ namespace plain_wallet
|
|||
|
||||
view::api_response ar = AUTO_VAL_INIT(ar);
|
||||
ar.error_code = inst_ptr->gwm.run_wallet(instance_id);
|
||||
return epee::serialization::store_t_to_json(ar);
|
||||
return sanitized_store_to_json(ar);
|
||||
}
|
||||
|
||||
std::string handle_configure(const std::string& settings_json)
|
||||
|
|
@ -621,11 +628,11 @@ namespace plain_wallet
|
|||
if (!res)
|
||||
{
|
||||
conf_resp.status = API_RETURN_CODE_BAD_ARG;
|
||||
return epee::serialization::store_t_to_json(conf_resp);
|
||||
return sanitized_store_to_json(conf_resp);
|
||||
}
|
||||
inst_ptr->postponed_run_wallet = conf.postponed_run_wallet;
|
||||
conf_resp.status = API_RETURN_CODE_OK;
|
||||
return epee::serialization::store_t_to_json(conf_resp);
|
||||
return sanitized_store_to_json(conf_resp);
|
||||
}
|
||||
|
||||
std::string sync_call(const std::string& method_name, uint64_t instance_id, const std::string& params)
|
||||
|
|
@ -636,7 +643,7 @@ namespace plain_wallet
|
|||
close_wallet(instance_id);
|
||||
view::api_responce_return_code rc = AUTO_VAL_INIT(rc);
|
||||
rc.return_code = API_RETURN_CODE_OK;
|
||||
res = epee::serialization::store_t_to_json(rc);
|
||||
res = sanitized_store_to_json(rc);
|
||||
}
|
||||
else if (method_name == "open")
|
||||
{
|
||||
|
|
@ -645,7 +652,7 @@ namespace plain_wallet
|
|||
{
|
||||
view::api_response ar = AUTO_VAL_INIT(ar);
|
||||
ar.error_code = "Wrong parameter";
|
||||
res = epee::serialization::store_t_to_json(ar);
|
||||
res = sanitized_store_to_json(ar);
|
||||
}else
|
||||
{
|
||||
res = open(owr.path, owr.pass);
|
||||
|
|
@ -658,7 +665,7 @@ namespace plain_wallet
|
|||
{
|
||||
view::api_response ar = AUTO_VAL_INIT(ar);
|
||||
ar.error_code = "Wrong parameter";
|
||||
res = epee::serialization::store_t_to_json(ar);
|
||||
res = sanitized_store_to_json(ar);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -672,13 +679,13 @@ namespace plain_wallet
|
|||
{
|
||||
view::api_response ar = AUTO_VAL_INIT(ar);
|
||||
ar.error_code = "Wrong parameter";
|
||||
res = epee::serialization::store_t_to_json(ar);
|
||||
res = sanitized_store_to_json(ar);
|
||||
}
|
||||
else
|
||||
{
|
||||
view::api_response_t<view::seed_phrase_info> rsp = AUTO_VAL_INIT(rsp);
|
||||
rsp.error_code = tools::get_seed_phrase_info(sip.seed_phrase, sip.seed_password, rsp.response_data);
|
||||
res = epee::serialization::store_t_to_json(rsp);
|
||||
res = sanitized_store_to_json(rsp);
|
||||
}
|
||||
}
|
||||
else if (method_name == "invoke")
|
||||
|
|
@ -705,7 +712,7 @@ namespace plain_wallet
|
|||
{
|
||||
view::api_response ar = AUTO_VAL_INIT(ar);
|
||||
ar.error_code = "UNKNOWN METHOD";
|
||||
res = epee::serialization::store_t_to_json(ar);
|
||||
res = sanitized_store_to_json(ar);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
@ -748,7 +755,7 @@ namespace plain_wallet
|
|||
wallet_extended_info wei = AUTO_VAL_INIT(wei);
|
||||
inst_ptr->gwm.get_wallet_info(h, wei.wi);
|
||||
inst_ptr->gwm.get_wallet_info_extra(h, wei.wi_extended);
|
||||
return epee::serialization::store_t_to_json(wei);
|
||||
return sanitized_store_to_json(wei);
|
||||
}
|
||||
std::string reset_wallet_password(hwallet h, const std::string& password)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4588,7 +4588,11 @@ void wallet2::get_recent_transfers_history(std::vector<wallet_public::wallet_tra
|
|||
|
||||
if (wti.remote_addresses.size() == 1)
|
||||
{
|
||||
wti.remote_aliases = get_aliases_for_address(wti.remote_addresses[0]);
|
||||
//this code is significantly slowing down when daemon are not "in-the-same-box"
|
||||
if (m_core_proxy->is_daemon_inbox())
|
||||
{
|
||||
wti.remote_aliases = get_aliases_for_address(wti.remote_addresses[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (trs.size() >= count)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue