aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/epee/include/console_handler.h12
-rw-r--r--contrib/epee/include/misc_log_ex.h1
-rw-r--r--contrib/epee/include/net/abstract_tcp_server2.inl6
-rw-r--r--contrib/epee/include/net/http_protocol_handler.inl2
-rw-r--r--contrib/epee/include/net/levin_client.inl4
-rw-r--r--contrib/epee/include/net/levin_client_async.h2
-rw-r--r--contrib/epee/include/net/levin_helper.h4
-rw-r--r--contrib/epee/include/net/levin_protocol_handler.h4
-rw-r--r--contrib/epee/include/net/levin_protocol_handler_async.h35
-rw-r--r--contrib/epee/include/net/net_helper.h2
-rw-r--r--contrib/epee/include/net/net_utils_base.h8
-rw-r--r--contrib/epee/include/readline_buffer.h13
-rw-r--r--contrib/epee/include/serialization/keyvalue_serialization.h7
-rw-r--r--contrib/epee/include/serialization/keyvalue_serialization_overloads.h1
-rw-r--r--contrib/epee/include/storages/portable_storage.h2
-rw-r--r--contrib/epee/src/mlog.cpp4
-rw-r--r--contrib/epee/src/readline_buffer.cpp121
-rwxr-xr-xcontrib/fuzz_testing/fuzz.sh21
18 files changed, 183 insertions, 66 deletions
diff --git a/contrib/epee/include/console_handler.h b/contrib/epee/include/console_handler.h
index bb20faa65..e780ad4de 100644
--- a/contrib/epee/include/console_handler.h
+++ b/contrib/epee/include/console_handler.h
@@ -315,7 +315,11 @@ namespace epee
if (!m_prompt.empty())
{
#ifdef HAVE_READLINE
- m_stdin_reader.get_readline_buffer().set_prompt(m_prompt);
+ std::string color_prompt = "\001\033[1;33m\002" + m_prompt;
+ if (' ' != m_prompt.back())
+ color_prompt += " ";
+ color_prompt += "\001\033[0m\002";
+ m_stdin_reader.get_readline_buffer().set_prompt(color_prompt);
#else
epee::set_console_color(epee::console_color_yellow, true);
std::cout << m_prompt;
@@ -370,6 +374,9 @@ namespace epee
}
else
{
+#ifdef HAVE_READLINE
+ rdln::suspend_readline pause_readline;
+#endif
std::cout << "unknown command: " << command << std::endl;
std::cout << usage;
}
@@ -473,6 +480,9 @@ namespace epee
lookup::mapped_type & vt = m_command_handlers[cmd];
vt.first = hndlr;
vt.second = usage;
+#ifdef HAVE_READLINE
+ rdln::readline_buffer::add_completion(cmd);
+#endif
}
bool process_command_vec(const std::vector<std::string>& cmd)
diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h
index 6eeb1441f..ec4bcbe2d 100644
--- a/contrib/epee/include/misc_log_ex.h
+++ b/contrib/epee/include/misc_log_ex.h
@@ -60,6 +60,7 @@
#define MCDEBUG(cat,x) CLOG(DEBUG,cat) << x
#define MCTRACE(cat,x) CLOG(TRACE,cat) << x
#define MCLOG(level,cat,x) ELPP_WRITE_LOG(el::base::Writer, level, el::base::DispatchAction::NormalLog, cat) << x
+#define MCLOG_FILE(level,cat,x) ELPP_WRITE_LOG(el::base::Writer, level, el::base::DispatchAction::FileOnlyLog, cat) << x
#define MCLOG_COLOR(level,cat,color,x) MCLOG(level,cat,"\033[1;" color "m" << x << "\033[0m")
#define MCLOG_RED(level,cat,x) MCLOG_COLOR(level,cat,"31",x)
diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl
index 0fbd9ed28..61276e761 100644
--- a/contrib/epee/include/net/abstract_tcp_server2.inl
+++ b/contrib/epee/include/net/abstract_tcp_server2.inl
@@ -209,14 +209,14 @@ PRAGMA_WARNING_DISABLE_VS(4355)
bool connection<t_protocol_handler>::add_ref()
{
TRY_ENTRY();
- //_dbg3("[sock " << socket_.native_handle() << "] add_ref, m_peer_number=" << mI->m_peer_number);
- CRITICAL_REGION_LOCAL(m_self_refs_lock);
- //_dbg3("[sock " << socket_.native_handle() << "] add_ref 2, m_peer_number=" << mI->m_peer_number);
// Use safe_shared_from_this, because of this is public method and it can be called on the object being deleted
auto self = safe_shared_from_this();
if(!self)
return false;
+ //_dbg3("[sock " << socket_.native_handle() << "] add_ref, m_peer_number=" << mI->m_peer_number);
+ CRITICAL_REGION_LOCAL(self->m_self_refs_lock);
+ //_dbg3("[sock " << socket_.native_handle() << "] add_ref 2, m_peer_number=" << mI->m_peer_number);
if(m_was_shutdown)
return false;
m_self_refs.push_back(self);
diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl
index d9eca2479..c92a13bcc 100644
--- a/contrib/epee/include/net/http_protocol_handler.inl
+++ b/contrib/epee/include/net/http_protocol_handler.inl
@@ -547,7 +547,7 @@ namespace net_utils
LOG_PRINT_L3("HTTP_RESPONSE_HEAD: << \r\n" << response_data);
m_psnd_hndlr->do_send((void*)response_data.data(), response_data.size());
- if(response.m_body.size())
+ if(response.m_body.size() && (query_info.m_http_method != http::http_method_head))
m_psnd_hndlr->do_send((void*)response.m_body.data(), response.m_body.size());
return res;
}
diff --git a/contrib/epee/include/net/levin_client.inl b/contrib/epee/include/net/levin_client.inl
index 50a01aaa5..ab7c32c32 100644
--- a/contrib/epee/include/net/levin_client.inl
+++ b/contrib/epee/include/net/levin_client.inl
@@ -99,7 +99,7 @@ int levin_client_impl::invoke(int command, const std::string& in_buff, std::stri
if(head.m_signature!=LEVIN_SIGNATURE)
{
- LOG_PRINT_L1("Signature missmatch in response");
+ LOG_PRINT_L1("Signature mismatch in response");
return -1;
}
@@ -160,7 +160,7 @@ inline
if(head.m_signature!=LEVIN_SIGNATURE)
{
- LOG_PRINT_L1("Signature missmatch in response");
+ LOG_PRINT_L1("Signature mismatch in response");
return -1;
}
diff --git a/contrib/epee/include/net/levin_client_async.h b/contrib/epee/include/net/levin_client_async.h
index 4b48070d6..337d345c4 100644
--- a/contrib/epee/include/net/levin_client_async.h
+++ b/contrib/epee/include/net/levin_client_async.h
@@ -408,7 +408,7 @@ namespace levin
if(head.m_signature!=LEVIN_SIGNATURE)
{
- LOG_ERROR("Signature missmatch in response");
+ LOG_ERROR("Signature mismatch in response");
return false;
}
diff --git a/contrib/epee/include/net/levin_helper.h b/contrib/epee/include/net/levin_helper.h
index c51d7244b..05560dd90 100644
--- a/contrib/epee/include/net/levin_helper.h
+++ b/contrib/epee/include/net/levin_helper.h
@@ -94,7 +94,7 @@ namespace levin
}
if(head.m_cb != buff.size()-sizeof(levin::bucket_head))
{
- LOG_PRINT_L3("sizes missmatch, at load_struct_from_levin_message");
+ LOG_PRINT_L3("sizes mismatch, at load_struct_from_levin_message");
return false;
}
@@ -121,7 +121,7 @@ namespace levin
}
if(head.m_cb != buff.size()-sizeof(levin::bucket_head))
{
- LOG_ERROR("sizes missmatch, at load_struct_from_levin_message");
+ LOG_ERROR("sizes mismatch, at load_struct_from_levin_message");
return false;
}
diff --git a/contrib/epee/include/net/levin_protocol_handler.h b/contrib/epee/include/net/levin_protocol_handler.h
index 3e1b8493a..fbc9727e2 100644
--- a/contrib/epee/include/net/levin_protocol_handler.h
+++ b/contrib/epee/include/net/levin_protocol_handler.h
@@ -103,7 +103,7 @@ namespace levin
{
if(m_cach_in_buffer.size() >= sizeof(uint64_t) && *((uint64_t*)m_cach_in_buffer.data()) != LEVIN_SIGNATURE)
{
- LOG_ERROR_CC(m_conn_context, "Signature missmatch on accepted connection");
+ LOG_ERROR_CC(m_conn_context, "Signature mismatch on accepted connection");
return false;
}
is_continue = false;
@@ -113,7 +113,7 @@ namespace levin
bucket_head* phead = (bucket_head*)m_cach_in_buffer.data();
if(LEVIN_SIGNATURE != phead->m_signature)
{
- LOG_ERROR_CC(m_conn_context, "Signature missmatch on accepted connection");
+ LOG_ERROR_CC(m_conn_context, "Signature mismatch on accepted connection");
return false;
}
m_current_head = *phead;
diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h
index 5ef782206..8aa0faba1 100644
--- a/contrib/epee/include/net/levin_protocol_handler_async.h
+++ b/contrib/epee/include/net/levin_protocol_handler_async.h
@@ -144,7 +144,6 @@ public:
virtual void cancel()=0;
virtual bool cancel_timer()=0;
virtual void reset_timer()=0;
- virtual void timeout_handler(const boost::system::error_code& error)=0;
};
template <class callback_t>
struct anvoke_handler: invoke_response_handler_base
@@ -157,9 +156,15 @@ public:
{
MDEBUG(con.get_context_ref() << "anvoke_handler, timeout: " << timeout);
m_timer.expires_from_now(boost::posix_time::milliseconds(timeout));
- m_timer.async_wait([this](const boost::system::error_code& ec)
+ m_timer.async_wait([&con, command, cb, timeout](const boost::system::error_code& ec)
{
- timeout_handler(ec);
+ if(ec == boost::asio::error::operation_aborted)
+ return;
+ MINFO(con.get_context_ref() << "Timeout on invoke operation happened, command: " << command << " timeout: " << timeout);
+ std::string fake;
+ cb(LEVIN_ERROR_CONNECTION_TIMEDOUT, fake, con.get_context_ref());
+ con.close();
+ con.finish_outer_call();
});
m_timer_started = true;
}
@@ -174,16 +179,6 @@ public:
bool m_timer_cancelled;
uint64_t m_timeout;
int m_command;
- virtual void timeout_handler(const boost::system::error_code& error)
- {
- if(error == boost::asio::error::operation_aborted)
- return;
- MINFO(m_con.get_context_ref() << "Timeout on invoke operation happened, command: " << m_command << " timeout: " << m_timeout);
- std::string fake;
- m_cb(LEVIN_ERROR_CONNECTION_TIMEDOUT, fake, m_con.get_context_ref());
- m_con.close();
- m_con.finish_outer_call();
- }
virtual bool handle(int res, const std::string& buff, typename async_protocol_handler::connection_context& context)
{
if(!cancel_timer())
@@ -220,10 +215,20 @@ public:
boost::system::error_code ignored_ec;
if (!m_cancel_timer_called && m_timer.cancel(ignored_ec) > 0)
{
+ callback_t& cb = m_cb;
+ uint64_t timeout = m_timeout;
+ async_protocol_handler& con = m_con;
+ int command = m_command;
m_timer.expires_from_now(boost::posix_time::milliseconds(m_timeout));
- m_timer.async_wait([this](const boost::system::error_code& ec)
+ m_timer.async_wait([&con, cb, command, timeout](const boost::system::error_code& ec)
{
- timeout_handler(ec);
+ if(ec == boost::asio::error::operation_aborted)
+ return;
+ MINFO(con.get_context_ref() << "Timeout on invoke operation happened, command: " << command << " timeout: " << timeout);
+ std::string fake;
+ cb(LEVIN_ERROR_CONNECTION_TIMEDOUT, fake, con.get_context_ref());
+ con.close();
+ con.finish_outer_call();
});
}
}
diff --git a/contrib/epee/include/net/net_helper.h b/contrib/epee/include/net/net_helper.h
index 432169990..1d808cc4c 100644
--- a/contrib/epee/include/net/net_helper.h
+++ b/contrib/epee/include/net/net_helper.h
@@ -473,7 +473,7 @@ namespace net_utils
if(bytes_transfered != buff.size())
{
- LOG_ERROR("Transferred missmatch with transfer_at_least value: m_bytes_transferred=" << bytes_transfered << " at_least value=" << buff.size());
+ LOG_ERROR("Transferred mismatch with transfer_at_least value: m_bytes_transferred=" << bytes_transfered << " at_least value=" << buff.size());
return false;
}
diff --git a/contrib/epee/include/net/net_utils_base.h b/contrib/epee/include/net/net_utils_base.h
index 1884412dc..ef3a1d146 100644
--- a/contrib/epee/include/net/net_utils_base.h
+++ b/contrib/epee/include/net/net_utils_base.h
@@ -115,10 +115,9 @@ namespace net_utils
std::string host_str() const { return (*this) ? (*this)->host_str() : "<none>"; }
bool is_loopback() const { return (*this)->is_loopback(); }
bool is_local() const { return (*this)->is_local(); }
- const std::type_info &type() const { return typeid(**this); }
uint8_t get_type_id() const { return (*this)->get_type_id(); }
- template<typename Type> Type &as() { if (type() != typeid(Type)) throw std::runtime_error("Bad type"); return *(Type*)get(); }
- template<typename Type> const Type &as() const { if (type() != typeid(Type)) throw std::runtime_error("Bad type"); return *(const Type*)get(); }
+ template<typename Type> Type &as() { if (get_type_id() != Type::ID) throw std::runtime_error("Bad type"); return *(Type*)get(); }
+ template<typename Type> const Type &as() const { if (get_type_id() != Type::ID) throw std::runtime_error("Bad type"); return *(const Type*)get(); }
BEGIN_KV_SERIALIZE_MAP()
uint8_t type = is_store ? this_ref.get_type_id() : 0;
@@ -156,7 +155,6 @@ namespace net_utils
const network_address m_remote_address;
const bool m_is_income;
const time_t m_started;
- bool m_in_timedsync;
time_t m_last_recv;
time_t m_last_send;
uint64_t m_recv_cnt;
@@ -172,7 +170,6 @@ namespace net_utils
m_remote_address(remote_address),
m_is_income(is_income),
m_started(time(NULL)),
- m_in_timedsync(false),
m_last_recv(last_recv),
m_last_send(last_send),
m_recv_cnt(recv_cnt),
@@ -185,7 +182,6 @@ namespace net_utils
m_remote_address(new ipv4_network_address(0,0)),
m_is_income(false),
m_started(time(NULL)),
- m_in_timedsync(false),
m_last_recv(0),
m_last_send(0),
m_recv_cnt(0),
diff --git a/contrib/epee/include/readline_buffer.h b/contrib/epee/include/readline_buffer.h
index 916d14f01..8dd082a70 100644
--- a/contrib/epee/include/readline_buffer.h
+++ b/contrib/epee/include/readline_buffer.h
@@ -3,6 +3,8 @@
#include <streambuf>
#include <sstream>
#include <iostream>
+#include <vector>
+#include <algorithm>
namespace rdln
{
@@ -19,12 +21,23 @@ namespace rdln
}
void get_line(std::string& line) const;
void set_prompt(const std::string& prompt);
+ static void add_completion(const std::string& command)
+ {
+ if(std::find(completion_commands.begin(), completion_commands.end(), command) != completion_commands.end())
+ return;
+ completion_commands.push_back(command);
+ }
+ static const std::vector<std::string>& get_completions()
+ {
+ return completion_commands;
+ }
protected:
virtual int sync();
private:
std::streambuf* m_cout_buf;
+ static std::vector<std::string> completion_commands;
};
class suspend_readline
diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h
index bf2c8dacd..f4442e46c 100644
--- a/contrib/epee/include/serialization/keyvalue_serialization.h
+++ b/contrib/epee/include/serialization/keyvalue_serialization.h
@@ -70,6 +70,12 @@ public: \
#define KV_SERIALIZE_N(varialble, val_name) \
epee::serialization::selector<is_store>::serialize(this_ref.varialble, stg, hparent_section, val_name);
+#define KV_SERIALIZE_OPT_N(variable, val_name, default_value) \
+ do { \
+ if (!epee::serialization::selector<is_store>::serialize(this_ref.variable, stg, hparent_section, val_name)) \
+ this_ref.variable = default_value; \
+ } while (0);
+
#define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, val_name) \
epee::serialization::selector<is_store>::serialize_t_val_as_blob(this_ref.varialble, stg, hparent_section, val_name);
@@ -86,6 +92,7 @@ public: \
#define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, #varialble)
#define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, #varialble) //skip is_pod compile time check
#define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble) KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, #varialble)
+#define KV_SERIALIZE_OPT(variable,default_value) KV_SERIALIZE_OPT_N(variable, #variable, default_value)
}
diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
index 33486d9ec..1a58cab99 100644
--- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
+++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
@@ -126,7 +126,6 @@ namespace epee
static bool serialize_stl_container_pod_val_as_blob(const stl_container& container, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
{
if(!container.size()) return true;
- typename stl_container::const_iterator it = container.begin();
std::string mb;
mb.resize(sizeof(typename stl_container::value_type)*container.size());
typename stl_container::value_type* p_elem = (typename stl_container::value_type*)mb.data();
diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/storages/portable_storage.h
index ba9292306..2023e2f2a 100644
--- a/contrib/epee/include/storages/portable_storage.h
+++ b/contrib/epee/include/storages/portable_storage.h
@@ -158,7 +158,7 @@ namespace epee
pbuff->m_signature_b != PORTABLE_STORAGE_SIGNATUREB
)
{
- LOG_ERROR("portable_storage: wrong binary format - signature missmatch");
+ LOG_ERROR("portable_storage: wrong binary format - signature mismatch");
return false;
}
if(pbuff->m_ver != PORTABLE_STORAGE_FORMAT_VER)
diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp
index 3be992374..39661a1a0 100644
--- a/contrib/epee/src/mlog.cpp
+++ b/contrib/epee/src/mlog.cpp
@@ -94,7 +94,7 @@ static const char *get_default_categories(int level)
categories = "*:WARNING,net:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,stacktrace:INFO,logging:INFO";
break;
case 1:
- categories = "*:WARNING,global:INFO,stacktrace:INFO,logging:INFO";
+ categories = "*:WARNING,global:INFO,stacktrace:INFO,logging:INFO,msgwriter:INFO";
break;
case 2:
categories = "*:DEBUG";
@@ -139,7 +139,7 @@ void mlog_configure(const std::string &filename_base, bool console)
{
monero_log = get_default_categories(0);
}
- mlog_set_categories(monero_log);
+ mlog_set_log(monero_log);
}
void mlog_set_categories(const char *categories)
diff --git a/contrib/epee/src/readline_buffer.cpp b/contrib/epee/src/readline_buffer.cpp
index 2d17103b3..ce8260ef6 100644
--- a/contrib/epee/src/readline_buffer.cpp
+++ b/contrib/epee/src/readline_buffer.cpp
@@ -5,6 +5,8 @@
#include <unistd.h>
#include <mutex>
#include <condition_variable>
+#include <boost/thread.hpp>
+#include <boost/algorithm/string.hpp>
static int process_input();
static void install_line_handler();
@@ -12,15 +14,18 @@ static void remove_line_handler();
static std::string last_line;
static std::string last_prompt;
-std::mutex line_mutex, sync_mutex;
+std::mutex line_mutex, sync_mutex, process_mutex;
std::condition_variable have_line;
+std::vector<std::string> rdln::readline_buffer::completion_commands = {"exit"};
+
namespace
{
rdln::readline_buffer* current = NULL;
}
rdln::suspend_readline::suspend_readline()
+: m_buffer(NULL), m_restart(false)
{
m_buffer = current;
if(!m_buffer)
@@ -46,6 +51,7 @@ rdln::readline_buffer::readline_buffer()
void rdln::readline_buffer::start()
{
+ std::unique_lock<std::mutex> lock(process_mutex);
if(m_cout_buf != NULL)
return;
m_cout_buf = std::cout.rdbuf();
@@ -55,6 +61,8 @@ void rdln::readline_buffer::start()
void rdln::readline_buffer::stop()
{
+ std::unique_lock<std::mutex> lock(process_mutex);
+ have_line.notify_all();
if(m_cout_buf == NULL)
return;
std::cout.rdbuf(m_cout_buf);
@@ -74,15 +82,24 @@ void rdln::readline_buffer::set_prompt(const std::string& prompt)
last_prompt = prompt;
if(m_cout_buf == NULL)
return;
+ std::lock_guard<std::mutex> lock(sync_mutex);
rl_set_prompt(last_prompt.c_str());
rl_redisplay();
}
int rdln::readline_buffer::process()
{
+ process_mutex.lock();
if(m_cout_buf == NULL)
+ {
+ process_mutex.unlock();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds( 1 ));
return 0;
- return process_input();
+ }
+ int count = process_input();
+ process_mutex.unlock();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds( 1 ));
+ return count;
}
int rdln::readline_buffer::sync()
@@ -100,8 +117,7 @@ int rdln::readline_buffer::sync()
do
{
- char x = this->sgetc();
- m_cout_buf->sputc(x);
+ m_cout_buf->sputc( this->sgetc() );
}
while ( this->snextc() != EOF );
@@ -114,19 +130,18 @@ int rdln::readline_buffer::sync()
return 0;
}
-static fd_set fds;
-
static int process_input()
{
int count;
struct timeval t;
+ fd_set fds;
t.tv_sec = 0;
t.tv_usec = 1000;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
- count = select(FD_SETSIZE, &fds, NULL, NULL, &t);
+ count = select(STDIN_FILENO + 1, &fds, NULL, NULL, &t);
if (count < 1)
{
return count;
@@ -137,41 +152,55 @@ static int process_input()
static void handle_line(char* line)
{
- if (line != NULL)
- {
- std::lock_guard<std::mutex> lock(sync_mutex);
- rl_set_prompt(last_prompt.c_str());
- rl_already_prompted = 1;
- return;
- }
- rl_set_prompt("");
- rl_replace_line("", 0);
- rl_redisplay();
- rl_set_prompt(last_prompt.c_str());
+ // This function never gets called now as we are trapping newlines.
+ // However, it still needs to be present for readline to know we are
+ // manually handling lines.
+ rl_done = 1;
+ return;
}
static int handle_enter(int x, int y)
{
std::lock_guard<std::mutex> lock(sync_mutex);
char* line = NULL;
-
+
line = rl_copy_text(0, rl_end);
+ std::string test_line = line;
+ boost::trim_right(test_line);
+
+ rl_crlf();
+ rl_on_new_line();
+
+ if(test_line.empty())
+ {
+ last_line = "";
+ rl_set_prompt(last_prompt.c_str());
+ rl_replace_line("", 1);
+ rl_redisplay();
+ have_line.notify_one();
+ return 0;
+ }
+
rl_set_prompt("");
rl_replace_line("", 1);
rl_redisplay();
- if (strcmp(line, "") != 0)
+ if (!test_line.empty())
{
- last_line = line;
- add_history(line);
- have_line.notify_one();
+ last_line = test_line;
+ add_history(test_line.c_str());
+ history_set_pos(history_length);
}
free(line);
-
- rl_set_prompt(last_prompt.c_str());
- rl_redisplay();
-
- rl_done = 1;
+
+ if(last_line != "exit" && last_line != "q")
+ {
+ rl_set_prompt(last_prompt.c_str());
+ rl_replace_line("", 1);
+ rl_redisplay();
+ }
+
+ have_line.notify_one();
return 0;
}
@@ -182,15 +211,51 @@ static int startup_hook()
return 0;
}
+static char* completion_matches(const char* text, int state)
+{
+ static size_t list_index;
+ static size_t len;
+
+ if(state == 0)
+ {
+ list_index = 0;
+ len = strlen(text);
+ }
+
+ const std::vector<std::string>& completions = rdln::readline_buffer::get_completions();
+ for(; list_index<completions.size(); )
+ {
+ const std::string& cmd = completions[list_index++];
+ if(cmd.compare(0, len, text) == 0)
+ {
+ return strdup(cmd.c_str());
+ }
+ }
+
+ return NULL;
+}
+
+static char** attempted_completion(const char* text, int start, int end)
+{
+ rl_attempted_completion_over = 1;
+ return rl_completion_matches(text, completion_matches);
+}
+
static void install_line_handler()
{
rl_startup_hook = startup_hook;
+ rl_attempted_completion_function = attempted_completion;
rl_callback_handler_install("", handle_line);
+ stifle_history(500);
}
static void remove_line_handler()
{
+ rl_replace_line("", 0);
+ rl_set_prompt("");
+ rl_redisplay();
rl_unbind_key(RETURN);
+ rl_unbind_key(NEWLINE);
rl_callback_handler_remove();
}
diff --git a/contrib/fuzz_testing/fuzz.sh b/contrib/fuzz_testing/fuzz.sh
new file mode 100755
index 000000000..35b74f7e4
--- /dev/null
+++ b/contrib/fuzz_testing/fuzz.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+AFLFUZZ=$(which afl-fuzz)
+if ! test -x "$AFLFUZZ"
+then
+ echo "afl-fuzz not found - install american-fuzzy-lop"
+ exit 1
+fi
+
+type="$1"
+if test -z "$type"
+then
+ echo "usage: $0 block|transaction|signature|cold-outputs|cold-transaction"
+ exit 1
+fi
+case "$type" in
+ block|transaction|signature|cold-outputs|cold-transaction) ;;
+ *) echo "usage: $0 block|transaction|signature|cold-outputs|cold-transaction"; exit 1 ;;
+esac
+
+afl-fuzz -i tests/data/fuzz/$type -m 150 -t 250 -o fuzz-out/$type build/fuzz/tests/fuzz/${type}_fuzz_tests