diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/data/fuzz/base58/ENC1 | 0 | ||||
-rw-r--r-- | tests/data/fuzz/base58/ENC2 | 1 | ||||
-rw-r--r-- | tests/data/fuzz/http-client/RESP1 | 8 | ||||
-rw-r--r-- | tests/data/fuzz/levin/LEVIN1 | bin | 0 -> 33 bytes | |||
-rw-r--r-- | tests/data/fuzz/load-from-binary/BINARY1 | bin | 0 -> 10 bytes | |||
-rw-r--r-- | tests/data/fuzz/load-from-json/JSON1 | 1 | ||||
-rw-r--r-- | tests/data/fuzz/parse-url/URL1 | 1 | ||||
-rw-r--r-- | tests/data/fuzz/parse-url/URL2 | 1 | ||||
-rw-r--r-- | tests/fuzz/CMakeLists.txt | 77 | ||||
-rw-r--r-- | tests/fuzz/base58.cpp | 74 | ||||
-rw-r--r-- | tests/fuzz/fuzzer.cpp | 33 | ||||
-rw-r--r-- | tests/fuzz/http-client.cpp | 98 | ||||
-rw-r--r-- | tests/fuzz/levin.cpp | 345 | ||||
-rw-r--r-- | tests/fuzz/load_from_binary.cpp | 76 | ||||
-rw-r--r-- | tests/fuzz/load_from_json.cpp | 76 | ||||
-rw-r--r-- | tests/fuzz/parse_url.cpp | 74 |
16 files changed, 833 insertions, 32 deletions
diff --git a/tests/data/fuzz/base58/ENC1 b/tests/data/fuzz/base58/ENC1 new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/data/fuzz/base58/ENC1 diff --git a/tests/data/fuzz/base58/ENC2 b/tests/data/fuzz/base58/ENC2 new file mode 100644 index 000000000..73da627e4 --- /dev/null +++ b/tests/data/fuzz/base58/ENC2 @@ -0,0 +1 @@ +9zZBkWRgMNPEnVofRFqWK9MKBwgXNyKELBJSttxb1t2UhDM114URntt5iYcXzXusoHZygfSojsbviXZhnP9pJ4p2SDcv81L
\ No newline at end of file diff --git a/tests/data/fuzz/http-client/RESP1 b/tests/data/fuzz/http-client/RESP1 new file mode 100644 index 000000000..3046dc886 --- /dev/null +++ b/tests/data/fuzz/http-client/RESP1 @@ -0,0 +1,8 @@ +HTTP/1.1 200 Ok
+Server: Epee-based
+Content-Length: 5
+Content-Type: text/plain
+Last-Modified: Mon, 11 Dec 2017 09:03:03 GMT
+Accept-Ranges: bytes
+
+foo
diff --git a/tests/data/fuzz/levin/LEVIN1 b/tests/data/fuzz/levin/LEVIN1 Binary files differnew file mode 100644 index 000000000..51a640c61 --- /dev/null +++ b/tests/data/fuzz/levin/LEVIN1 diff --git a/tests/data/fuzz/load-from-binary/BINARY1 b/tests/data/fuzz/load-from-binary/BINARY1 Binary files differnew file mode 100644 index 000000000..c99d7e7bc --- /dev/null +++ b/tests/data/fuzz/load-from-binary/BINARY1 diff --git a/tests/data/fuzz/load-from-json/JSON1 b/tests/data/fuzz/load-from-json/JSON1 new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/tests/data/fuzz/load-from-json/JSON1 @@ -0,0 +1 @@ +{}
\ No newline at end of file diff --git a/tests/data/fuzz/parse-url/URL1 b/tests/data/fuzz/parse-url/URL1 new file mode 100644 index 000000000..e56ea71e3 --- /dev/null +++ b/tests/data/fuzz/parse-url/URL1 @@ -0,0 +1 @@ +127.0.0.1
\ No newline at end of file diff --git a/tests/data/fuzz/parse-url/URL2 b/tests/data/fuzz/parse-url/URL2 new file mode 100644 index 000000000..b66e7de9a --- /dev/null +++ b/tests/data/fuzz/parse-url/URL2 @@ -0,0 +1 @@ +iframe_test.html?api_url=http://api.vk.com/api.php&api_id=3289090&api_settings=1&viewer_id=562964060&viewer_type=0&sid=0aad8d1c5713130f9ca0076f2b7b47e532877424961367d81e7fa92455f069be7e21bc3193cbd0be11895&secret=368ebbc0ef&access_token=668bc03f43981d883f73876ffff4aa8564254b359cc745dfa1b3cde7bdab2e94105d8f6d8250717569c0a7&user_id=0&group_id=0&is_app_user=1&auth_key=d2f7a895ca5ff3fdb2a2a8ae23fe679a&language=0&parent_language=0&ad_info=ElsdCQBaQlxiAQRdFUVUXiN2AVBzBx5pU1BXIgZUJlIEAWcgAUoLQg==&referrer=unknown&lc_name=9834b6a3&hash=
\ No newline at end of file diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt index 853d46a12..5d58f9a3c 100644 --- a/tests/fuzz/CMakeLists.txt +++ b/tests/fuzz/CMakeLists.txt @@ -89,3 +89,80 @@ set_property(TARGET cold-transaction_fuzz_tests PROPERTY FOLDER "tests") +add_executable(load-from-binary_fuzz_tests load_from_binary.cpp fuzzer.cpp) +target_link_libraries(load-from-binary_fuzz_tests + PRIVATE + common + epee + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${EXTRA_LIBRARIES}) +set_property(TARGET load-from-binary_fuzz_tests + PROPERTY + FOLDER "tests") + +add_executable(load-from-json_fuzz_tests load_from_json.cpp fuzzer.cpp) +target_link_libraries(load-from-json_fuzz_tests + PRIVATE + common + epee + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${EXTRA_LIBRARIES}) +set_property(TARGET load-from-json_fuzz_tests + PROPERTY + FOLDER "tests") + +add_executable(base58_fuzz_tests base58.cpp fuzzer.cpp) +target_link_libraries(base58_fuzz_tests + PRIVATE + common + epee + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${EXTRA_LIBRARIES}) +set_property(TARGET base58_fuzz_tests + PROPERTY + FOLDER "tests") + +add_executable(parse-url_fuzz_tests parse_url.cpp fuzzer.cpp) +target_link_libraries(parse-url_fuzz_tests + PRIVATE + epee + ${Boost_REGEX_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_SYSTEM_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${EXTRA_LIBRARIES}) +set_property(TARGET parse-url_fuzz_tests + PROPERTY + FOLDER "tests") + +add_executable(http-client_fuzz_tests http-client.cpp fuzzer.cpp) +target_link_libraries(http-client_fuzz_tests + PRIVATE + epee + ${Boost_THREAD_LIBRARY} + ${Boost_REGEX_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_SYSTEM_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${EXTRA_LIBRARIES}) +set_property(TARGET http-client_fuzz_tests + PROPERTY + FOLDER "tests") + +add_executable(levin_fuzz_tests levin.cpp fuzzer.cpp) +target_link_libraries(levin_fuzz_tests + PRIVATE + common + epee + ${Boost_THREAD_LIBRARY} + ${Boost_REGEX_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${EXTRA_LIBRARIES}) +set_property(TARGET levin_fuzz_tests + PROPERTY + FOLDER "tests") + diff --git a/tests/fuzz/base58.cpp b/tests/fuzz/base58.cpp new file mode 100644 index 000000000..aea62f721 --- /dev/null +++ b/tests/fuzz/base58.cpp @@ -0,0 +1,74 @@ +// Copyright (c) 2017, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "include_base_utils.h" +#include "file_io_utils.h" +#include "common/base58.h" +#include "fuzzer.h" + +class Base58Fuzzer: public Fuzzer +{ +public: + Base58Fuzzer() {} + virtual int init(); + virtual int run(const std::string &filename); +}; + +int Base58Fuzzer::init() +{ + return 0; +} + +int Base58Fuzzer::run(const std::string &filename) +{ + std::string s; + + if (!epee::file_io_utils::load_file_to_string(filename, s)) + { + std::cout << "Error: failed to load file " << filename << std::endl; + return 1; + } + try + { + std::string data; + tools::base58::decode(s, data); + } + catch (const std::exception &e) + { + std::cerr << "Failed to load from binary: " << e.what() << std::endl; + return 1; + } + return 0; +} + +int main(int argc, const char **argv) +{ + Base58Fuzzer fuzzer; + return run_fuzzer(argc, argv, fuzzer); +} + diff --git a/tests/fuzz/fuzzer.cpp b/tests/fuzz/fuzzer.cpp index ede3fcc40..686a5e5f0 100644 --- a/tests/fuzz/fuzzer.cpp +++ b/tests/fuzz/fuzzer.cpp @@ -44,41 +44,11 @@ static int __AFL_LOOP(int) } #endif -using namespace epee; -using namespace boost::program_options; - int run_fuzzer(int argc, const char **argv, Fuzzer &fuzzer) { - TRY_ENTRY(); - tools::on_startup(); - string_tools::set_module_name_and_folder(argv[0]); - - //set up logging options - mlog_configure(mlog_get_default_log_path("fuzztests.log"), true); - mlog_set_log("*:FATAL,logging:none"); - - options_description desc_options("Allowed options"); - command_line::add_arg(desc_options, command_line::arg_help); - - variables_map vm; - bool r = command_line::handle_error_helper(desc_options, [&]() - { - store(parse_command_line(argc, argv, desc_options), vm); - notify(vm); - return true; - }); - if (!r) - return 1; - - if (command_line::get_arg(vm, command_line::arg_help)) - { - std::cout << desc_options << std::endl; - return 0; - } - if (argc < 2) { - std::cout << desc_options << std::endl; + std::cout << "usage: " << argv[0] << " " << "<filename>" << std::endl; return 1; } @@ -94,6 +64,5 @@ int run_fuzzer(int argc, const char **argv, Fuzzer &fuzzer) return ret; } - CATCH_ENTRY_L0("fuzzer_main", 1); return 0; } diff --git a/tests/fuzz/http-client.cpp b/tests/fuzz/http-client.cpp new file mode 100644 index 000000000..21560df21 --- /dev/null +++ b/tests/fuzz/http-client.cpp @@ -0,0 +1,98 @@ +// Copyright (c) 2017, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "include_base_utils.h" +#include "file_io_utils.h" +#include "net/http_client.h" +#include "fuzzer.h" + +class dummy_client +{ +public: + bool connect(const std::string& addr, int port, std::chrono::milliseconds timeout, bool ssl = false, const std::string& bind_ip = "0.0.0.0") { return true; } + bool connect(const std::string& addr, const std::string& port, std::chrono::milliseconds timeout, bool ssl = false, const std::string& bind_ip = "0.0.0.0") { return true; } + bool disconnect() { return true; } + bool send(const std::string& buff, std::chrono::milliseconds timeout) { return true; } + bool send(const void* data, size_t sz) { return true; } + bool is_connected() { return true; } + bool recv(std::string& buff, std::chrono::milliseconds timeout) + { + buff = data; + data.clear(); + return true; + } + + void set_test_data(const std::string &s) { data = s; } + +private: + std::string data; +}; + +class HTTPClientFuzzer: public Fuzzer +{ +public: + HTTPClientFuzzer() {} + virtual int init(); + virtual int run(const std::string &filename); + +private: + epee::net_utils::http::http_simple_client_template<dummy_client> client; +}; + +int HTTPClientFuzzer::init() +{ + return 0; +} + +int HTTPClientFuzzer::run(const std::string &filename) +{ + std::string s; + + if (!epee::file_io_utils::load_file_to_string(filename, s)) + { + std::cout << "Error: failed to load file " << filename << std::endl; + return 1; + } + try + { + client.test(s, std::chrono::milliseconds(1000)); + } + catch (const std::exception &e) + { + std::cerr << "Failed to test http client: " << e.what() << std::endl; + return 1; + } + return 0; +} + +int main(int argc, const char **argv) +{ + HTTPClientFuzzer fuzzer; + return run_fuzzer(argc, argv, fuzzer); +} + diff --git a/tests/fuzz/levin.cpp b/tests/fuzz/levin.cpp new file mode 100644 index 000000000..2fd60ae50 --- /dev/null +++ b/tests/fuzz/levin.cpp @@ -0,0 +1,345 @@ +// Copyright (c) 2017, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "include_base_utils.h" +#include "file_io_utils.h" +#include "net/net_utils_base.h" +#include "net/abstract_tcp_server2.h" +#include "storages/levin_abstract_invoke2.h" +#include "net/levin_protocol_handler_async.h" +#include "fuzzer.h" + +namespace +{ + class call_counter + { + public: + call_counter() : m_counter(0) { } + + // memory_order_relaxed is enough for call counter + void inc() volatile { m_counter.fetch_add(1, std::memory_order_relaxed); } + size_t get() volatile const { return m_counter.load(std::memory_order_relaxed); } + void reset() volatile { m_counter.store(0, std::memory_order_relaxed); } + + private: + std::atomic<size_t> m_counter; + }; + + struct test_levin_connection_context : public epee::net_utils::connection_context_base + { + }; + + typedef epee::levin::async_protocol_handler_config<test_levin_connection_context> test_levin_protocol_handler_config; + typedef epee::levin::async_protocol_handler<test_levin_connection_context> test_levin_protocol_handler; + + struct test_levin_commands_handler : public epee::levin::levin_commands_handler<test_levin_connection_context> + { + test_levin_commands_handler() + : m_return_code(LEVIN_OK) + , m_last_command(-1) + { + } + + virtual int invoke(int command, const std::string& in_buff, std::string& buff_out, test_levin_connection_context& context) + { + m_invoke_counter.inc(); + boost::unique_lock<boost::mutex> lock(m_mutex); + m_last_command = command; + m_last_in_buf = in_buff; + buff_out = m_invoke_out_buf; + return m_return_code; + } + + virtual int notify(int command, const std::string& in_buff, test_levin_connection_context& context) + { + m_notify_counter.inc(); + boost::unique_lock<boost::mutex> lock(m_mutex); + m_last_command = command; + m_last_in_buf = in_buff; + return m_return_code; + } + + virtual void callback(test_levin_connection_context& context) + { + m_callback_counter.inc(); + //std::cout << "test_levin_commands_handler::callback()" << std::endl; + } + + virtual void on_connection_new(test_levin_connection_context& context) + { + m_new_connection_counter.inc(); + //std::cout << "test_levin_commands_handler::on_connection_new()" << std::endl; + } + + virtual void on_connection_close(test_levin_connection_context& context) + { + m_close_connection_counter.inc(); + //std::cout << "test_levin_commands_handler::on_connection_close()" << std::endl; + } + + size_t invoke_counter() const { return m_invoke_counter.get(); } + size_t notify_counter() const { return m_notify_counter.get(); } + size_t callback_counter() const { return m_callback_counter.get(); } + size_t new_connection_counter() const { return m_new_connection_counter.get(); } + size_t close_connection_counter() const { return m_close_connection_counter.get(); } + + int return_code() const { return m_return_code; } + void return_code(int v) { m_return_code = v; } + + const std::string& invoke_out_buf() const { return m_invoke_out_buf; } + void invoke_out_buf(const std::string& v) { m_invoke_out_buf = v; } + + int last_command() const { return m_last_command; } + const std::string& last_in_buf() const { return m_last_in_buf; } + + private: + call_counter m_invoke_counter; + call_counter m_notify_counter; + call_counter m_callback_counter; + call_counter m_new_connection_counter; + call_counter m_close_connection_counter; + + boost::mutex m_mutex; + + int m_return_code; + std::string m_invoke_out_buf; + + int m_last_command; + std::string m_last_in_buf; + }; + + class test_connection : public epee::net_utils::i_service_endpoint + { + public: + test_connection(boost::asio::io_service& io_service, test_levin_protocol_handler_config& protocol_config) + : m_io_service(io_service) + , m_protocol_handler(this, protocol_config, m_context) + , m_send_return(true) + { + } + + void start() + { + m_protocol_handler.after_init_connection(); + } + + // Implement epee::net_utils::i_service_endpoint interface + virtual bool do_send(const void* ptr, size_t cb) + { + m_send_counter.inc(); + boost::unique_lock<boost::mutex> lock(m_mutex); + m_last_send_data.append(reinterpret_cast<const char*>(ptr), cb); + return m_send_return; + } + + virtual bool close() { return true; } + virtual bool call_run_once_service_io() { return true; } + virtual bool request_callback() { return true; } + virtual boost::asio::io_service& get_io_service() { return m_io_service; } + virtual bool add_ref() { return true; } + virtual bool release() { return true; } + + size_t send_counter() const { return m_send_counter.get(); } + + const std::string& last_send_data() const { return m_last_send_data; } + void reset_last_send_data() { boost::unique_lock<boost::mutex> lock(m_mutex); m_last_send_data.clear(); } + + bool send_return() const { return m_send_return; } + void send_return(bool v) { m_send_return = v; } + + public: + test_levin_connection_context m_context; + test_levin_protocol_handler m_protocol_handler; + + private: + boost::asio::io_service& m_io_service; + + call_counter m_send_counter; + boost::mutex m_mutex; + + std::string m_last_send_data; + + bool m_send_return; + }; + +#if 0 + class async_protocol_handler_test : public ::testing::Test + { + public: + const static uint64_t invoke_timeout = 5 * 1000; + const static size_t max_packet_size = 10 * 1024 * 1024; + + typedef std::unique_ptr<test_connection> test_connection_ptr; + + async_protocol_handler_test(): + m_pcommands_handler(new test_levin_commands_handler()), + m_commands_handler(*m_pcommands_handler) + { + m_handler_config.set_handler(m_pcommands_handler, [](epee::levin::levin_commands_handler<test_levin_connection_context> *handler) { delete handler; }); + m_handler_config.m_invoke_timeout = invoke_timeout; + m_handler_config.m_max_packet_size = max_packet_size; + } + + virtual void SetUp() + { + } + + protected: + test_connection_ptr create_connection(bool start = true) + { + test_connection_ptr conn(new test_connection(m_io_service, m_handler_config)); + if (start) + { + conn->start(); + } + return conn; + } + + protected: + boost::asio::io_service m_io_service; + test_levin_protocol_handler_config m_handler_config; + test_levin_commands_handler *m_pcommands_handler, &m_commands_handler; + }; + + class positive_test_connection_to_levin_protocol_handler_calls : public async_protocol_handler_test + { + }; + + class test_levin_protocol_handler__hanle_recv_with_invalid_data : public async_protocol_handler_test + { + public: + static const int expected_command = 5615871; + static const int expected_return_code = 782546; + + test_levin_protocol_handler__hanle_recv_with_invalid_data() + : m_expected_invoke_out_buf(512, 'y') + { + } + + virtual void SetUp() + { + async_protocol_handler_test::SetUp(); + + m_conn = create_connection(); + + m_in_data.assign(256, 't'); + + m_req_head.m_signature = LEVIN_SIGNATURE; + m_req_head.m_cb = m_in_data.size(); + m_req_head.m_have_to_return_data = true; + m_req_head.m_command = expected_command; + m_req_head.m_return_code = LEVIN_OK; + m_req_head.m_flags = LEVIN_PACKET_REQUEST; + m_req_head.m_protocol_version = LEVIN_PROTOCOL_VER_1; + + m_commands_handler.return_code(expected_return_code); + m_commands_handler.invoke_out_buf(m_expected_invoke_out_buf); + } + + protected: + void prepare_buf() + { + m_buf.assign(reinterpret_cast<const char*>(&m_req_head), sizeof(m_req_head)); + m_buf += m_in_data; + } + + protected: + test_connection_ptr m_conn; + epee::levin::bucket_head2 m_req_head; + std::string m_in_data; + std::string m_buf; + std::string m_expected_invoke_out_buf; + }; +#endif +} + +class LevinFuzzer: public Fuzzer +{ +public: + LevinFuzzer() {} //: handler(endpoint, config, context) {} + virtual int init(); + virtual int run(const std::string &filename); + +private: + //epee::net_utils::connection_context_base context; + //epee::levin::async_protocol_handler<> handler; +}; + +int LevinFuzzer::init() +{ + return 0; +} + +int LevinFuzzer::run(const std::string &filename) +{ + std::string s; + +// + epee::levin::bucket_head2 req_head; + req_head.m_signature = LEVIN_SIGNATURE; + req_head.m_cb = 0; + req_head.m_have_to_return_data = true; + req_head.m_command = 2000; + req_head.m_flags = LEVIN_PACKET_REQUEST; + req_head.m_protocol_version = LEVIN_PROTOCOL_VER_1; + FILE *f=fopen("/tmp/out.levin", "w"); + fwrite(&req_head,sizeof(req_head),1, f); + fclose(f); +// + if (!epee::file_io_utils::load_file_to_string(filename, s)) + { + std::cout << "Error: failed to load file " << filename << std::endl; + return 1; + } + try + { + //std::unique_ptr<test_connection> conn = new test(); + boost::asio::io_service io_service; + test_levin_protocol_handler_config m_handler_config; + test_levin_commands_handler *m_pcommands_handler = new test_levin_commands_handler(); + m_handler_config.set_handler(m_pcommands_handler, [](epee::levin::levin_commands_handler<test_levin_connection_context> *handler) { delete handler; }); + std::unique_ptr<test_connection> conn(new test_connection(io_service, m_handler_config)); + conn->start(); + //m_commands_handler.invoke_out_buf(expected_out_data); + //m_commands_handler.return_code(expected_return_code); + conn->m_protocol_handler.handle_recv(s.data(), s.size()); + } + catch (const std::exception &e) + { + std::cerr << "Failed to test http client: " << e.what() << std::endl; + return 1; + } + return 0; +} + +int main(int argc, const char **argv) +{ + LevinFuzzer fuzzer; + return run_fuzzer(argc, argv, fuzzer); +} + diff --git a/tests/fuzz/load_from_binary.cpp b/tests/fuzz/load_from_binary.cpp new file mode 100644 index 000000000..3c8dd177b --- /dev/null +++ b/tests/fuzz/load_from_binary.cpp @@ -0,0 +1,76 @@ +// Copyright (c) 2017, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "include_base_utils.h" +#include "file_io_utils.h" +#include "serialization/keyvalue_serialization.h" +#include "storages/portable_storage_template_helper.h" +#include "storages/portable_storage_base.h" +#include "fuzzer.h" + +class PortableStorageFuzzer: public Fuzzer +{ +public: + PortableStorageFuzzer() {} + virtual int init(); + virtual int run(const std::string &filename); +}; + +int PortableStorageFuzzer::init() +{ + return 0; +} + +int PortableStorageFuzzer::run(const std::string &filename) +{ + std::string s; + + if (!epee::file_io_utils::load_file_to_string(filename, s)) + { + std::cout << "Error: failed to load file " << filename << std::endl; + return 1; + } + try + { + epee::serialization::portable_storage ps; + ps.load_from_binary(s); + } + catch (const std::exception &e) + { + std::cerr << "Failed to load from binary: " << e.what() << std::endl; + return 1; + } + return 0; +} + +int main(int argc, const char **argv) +{ + PortableStorageFuzzer fuzzer; + return run_fuzzer(argc, argv, fuzzer); +} + diff --git a/tests/fuzz/load_from_json.cpp b/tests/fuzz/load_from_json.cpp new file mode 100644 index 000000000..5d39c89a6 --- /dev/null +++ b/tests/fuzz/load_from_json.cpp @@ -0,0 +1,76 @@ +// Copyright (c) 2017, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "include_base_utils.h" +#include "file_io_utils.h" +#include "serialization/keyvalue_serialization.h" +#include "storages/portable_storage_template_helper.h" +#include "storages/portable_storage_base.h" +#include "fuzzer.h" + +class PortableStorageFuzzer: public Fuzzer +{ +public: + PortableStorageFuzzer() {} + virtual int init(); + virtual int run(const std::string &filename); +}; + +int PortableStorageFuzzer::init() +{ + return 0; +} + +int PortableStorageFuzzer::run(const std::string &filename) +{ + std::string s; + + if (!epee::file_io_utils::load_file_to_string(filename, s)) + { + std::cout << "Error: failed to load file " << filename << std::endl; + return 1; + } + try + { + epee::serialization::portable_storage ps; + ps.load_from_json(s); + } + catch (const std::exception &e) + { + std::cerr << "Failed to load from binary: " << e.what() << std::endl; + return 1; + } + return 0; +} + +int main(int argc, const char **argv) +{ + PortableStorageFuzzer fuzzer; + return run_fuzzer(argc, argv, fuzzer); +} + diff --git a/tests/fuzz/parse_url.cpp b/tests/fuzz/parse_url.cpp new file mode 100644 index 000000000..bf3a3bdd4 --- /dev/null +++ b/tests/fuzz/parse_url.cpp @@ -0,0 +1,74 @@ +// Copyright (c) 2017, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "include_base_utils.h" +#include "file_io_utils.h" +#include "net/net_parse_helpers.h" +#include "fuzzer.h" + +class ParseURLFuzzer: public Fuzzer +{ +public: + ParseURLFuzzer() {} + virtual int init(); + virtual int run(const std::string &filename); +}; + +int ParseURLFuzzer::init() +{ + return 0; +} + +int ParseURLFuzzer::run(const std::string &filename) +{ + std::string s; + + if (!epee::file_io_utils::load_file_to_string(filename, s)) + { + std::cout << "Error: failed to load file " << filename << std::endl; + return 1; + } + try + { + epee::net_utils::http::url_content url; + epee::net_utils::parse_url(s, url); + } + catch (const std::exception &e) + { + std::cerr << "Failed to load from binary: " << e.what() << std::endl; + return 1; + } + return 0; +} + +int main(int argc, const char **argv) +{ + ParseURLFuzzer fuzzer; + return run_fuzzer(argc, argv, fuzzer); +} + |