mirror of
https://github.com/monero-project/monero.git
synced 2024-11-17 08:17:37 +00:00
Merge pull request #2905
bd1f6029
http_client: rewrite header parsing manually for speed (moneromooo-monero)ec724eb6
tests: add levin fuzz test (moneromooo-monero)f1bdc9a4
tests: add http client fuzz test (moneromooo-monero)0272df9e
add parse_url fuzz test (moneromooo-monero)261b0dd0
tests: add base58 fuzz test (moneromooo-monero)fd052087
fuzz_testing: allow automatically resuming an interrupted job (moneromooo-monero)c80bb0eb
tests: don't init stuff we don't need in fuzz tests - faster (moneromooo-monero)53b83a83
tests: better load-from-binary fuzz test data file (moneromooo-monero)1a379ef6
fuzz_testing: build with ASAN (assumed to be available) (moneromooo-monero)4cd4a431
fuzz_testing: create out directory if needed, and fix filename passing (moneromooo-monero)c27d9092
Makefile: build fuzz tests statically, starts faster (moneromooo-monero)95aa0bf7
add load_from_binary/load_from_json fuzzers (moneromooo-monero)
This commit is contained in:
commit
9d1c4408ad
20 changed files with 967 additions and 116 deletions
|
@ -238,6 +238,16 @@ if(STATIC)
|
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DZMQ_STATIC")
|
||||
endif()
|
||||
|
||||
if(SANITIZE)
|
||||
if (MSVC)
|
||||
message(FATAL_ERROR "Cannot sanitize with MSVC")
|
||||
else()
|
||||
message(STATUS "Using ASAN")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Set default blockchain storage location:
|
||||
# memory was the default in Cryptonote before Monero implimented LMDB, it still works but is unneccessary.
|
||||
# set(DATABASE memory)
|
||||
|
|
2
Makefile
2
Makefile
|
@ -114,7 +114,7 @@ release-static-win32:
|
|||
|
||||
fuzz:
|
||||
mkdir -p build/fuzz
|
||||
cd build/fuzz && cmake -D BUILD_TESTS=ON -D USE_LTO=OFF -D CMAKE_C_COMPILER=afl-gcc -D CMAKE_CXX_COMPILER=afl-g++ -D ARCH="x86-64" -D CMAKE_BUILD_TYPE=fuzz -D BUILD_TAG="linux-x64" ../.. && $(MAKE)
|
||||
cd build/fuzz && cmake -D STATIC=ON -D SANITIZE=ON -D BUILD_TESTS=ON -D USE_LTO=OFF -D CMAKE_C_COMPILER=afl-gcc -D CMAKE_CXX_COMPILER=afl-g++ -D ARCH="x86-64" -D CMAKE_BUILD_TYPE=fuzz -D BUILD_TAG="linux-x64" ../.. && $(MAKE)
|
||||
|
||||
clean:
|
||||
@echo "WARNING: Back-up your wallet if it exists within ./build!" ; \
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
|
||||
#pragma once
|
||||
#include <ctype.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
@ -236,7 +237,8 @@ namespace net_utils
|
|||
namespace http
|
||||
{
|
||||
|
||||
class http_simple_client: public i_target_handler
|
||||
template<typename net_client_type>
|
||||
class http_simple_client_template: public i_target_handler
|
||||
{
|
||||
private:
|
||||
enum reciev_machine_state
|
||||
|
@ -259,7 +261,7 @@ namespace net_utils
|
|||
};
|
||||
|
||||
|
||||
blocked_mode_client m_net_client;
|
||||
net_client_type m_net_client;
|
||||
std::string m_host_buff;
|
||||
std::string m_port;
|
||||
http_client_auth m_auth;
|
||||
|
@ -276,7 +278,7 @@ namespace net_utils
|
|||
bool m_ssl;
|
||||
|
||||
public:
|
||||
explicit http_simple_client()
|
||||
explicit http_simple_client_template()
|
||||
: i_target_handler()
|
||||
, m_net_client()
|
||||
, m_host_buff()
|
||||
|
@ -428,6 +430,15 @@ namespace net_utils
|
|||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
return invoke(uri, "POST", body, timeout, ppresponse_info, additional_params);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool test(const std::string &s, std::chrono::milliseconds timeout) // TEST FUNC ONLY
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_lock);
|
||||
m_net_client.set_test_data(s);
|
||||
m_state = reciev_machine_state_header;
|
||||
return handle_reciev(timeout);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
private:
|
||||
//---------------------------------------------------------------------------
|
||||
inline bool handle_reciev(std::chrono::milliseconds timeout)
|
||||
|
@ -742,87 +753,107 @@ namespace net_utils
|
|||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
inline
|
||||
bool parse_header(http_header_info& body_info, const std::string& m_cache_to_process)
|
||||
{
|
||||
MTRACE("http_stream_filter::parse_cached_header(*)");
|
||||
|
||||
STATIC_REGEXP_EXPR_1(rexp_mach_field,
|
||||
"\n?((Connection)|(Referer)|(Content-Length)|(Content-Type)|(Transfer-Encoding)|(Content-Encoding)|(Host)|(Cookie)|(User-Agent)|(Origin)"
|
||||
// 12 3 4 5 6 7 8 9 10 11
|
||||
"|([\\w-]+?)) ?: ?((.*?)(\r?\n))[^\t ]",
|
||||
//12 13 14 15
|
||||
boost::regex::icase | boost::regex::normal);
|
||||
|
||||
boost::smatch result;
|
||||
std::string::const_iterator it_current_bound = m_cache_to_process.begin();
|
||||
std::string::const_iterator it_end_bound = m_cache_to_process.end();
|
||||
|
||||
|
||||
|
||||
//lookup all fields and fill well-known fields
|
||||
while( boost::regex_search( it_current_bound, it_end_bound, result, rexp_mach_field, boost::match_default) && result[0].matched)
|
||||
{
|
||||
const size_t field_val = 14;
|
||||
//const size_t field_etc_name = 11;
|
||||
|
||||
int i = 2; //start position = 2
|
||||
if(result[i++].matched)//"Connection"
|
||||
body_info.m_connection = result[field_val];
|
||||
else if(result[i++].matched)//"Referrer"
|
||||
body_info.m_referer = result[field_val];
|
||||
else if(result[i++].matched)//"Content-Length"
|
||||
body_info.m_content_length = result[field_val];
|
||||
else if(result[i++].matched)//"Content-Type"
|
||||
body_info.m_content_type = result[field_val];
|
||||
else if(result[i++].matched)//"Transfer-Encoding"
|
||||
body_info.m_transfer_encoding = result[field_val];
|
||||
else if(result[i++].matched)//"Content-Encoding"
|
||||
body_info.m_content_encoding = result[field_val];
|
||||
else if(result[i++].matched)//"Host"
|
||||
{ body_info.m_host = result[field_val];
|
||||
string_tools::trim(body_info.m_host);
|
||||
}
|
||||
else if(result[i++].matched)//"Cookie"
|
||||
body_info.m_cookie = result[field_val];
|
||||
else if(result[i++].matched)//"User-Agent"
|
||||
body_info.m_user_agent = result[field_val];
|
||||
else if(result[i++].matched)//"Origin"
|
||||
body_info.m_origin = result[field_val];
|
||||
else if(result[i++].matched)//e.t.c (HAVE TO BE MATCHED!)
|
||||
body_info.m_etc_fields.emplace_back(result[12], result[field_val]);
|
||||
else
|
||||
{CHECK_AND_ASSERT_MES(false, false, "http_stream_filter::parse_cached_header() not matched last entry in:"<<m_cache_to_process);}
|
||||
|
||||
it_current_bound = result[(int)result.size()-1]. first;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
inline
|
||||
bool analize_first_response_line()
|
||||
inline bool parse_header(http_header_info& body_info, const std::string& m_cache_to_process)
|
||||
{
|
||||
MTRACE("http_stream_filter::parse_cached_header(*)");
|
||||
|
||||
//First line response, look like this: "HTTP/1.1 200 OK"
|
||||
STATIC_REGEXP_EXPR_1(rexp_match_first_response_line, "^HTTP/(\\d+).(\\d+) ((\\d)\\d{2})( [^\n]*)?\r?\n", boost::regex::icase | boost::regex::normal);
|
||||
// 1 2 34 5
|
||||
//size_t match_len = 0;
|
||||
boost::smatch result;
|
||||
if(boost::regex_search( m_header_cache, result, rexp_match_first_response_line, boost::match_default) && result[0].matched)
|
||||
const char *ptr = m_cache_to_process.c_str();
|
||||
while (ptr[0] != '\r' || ptr[1] != '\n')
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(result[1].matched&&result[2].matched, false, "http_stream_filter::handle_invoke_reply_line() assert failed...");
|
||||
m_response_info.m_http_ver_hi = boost::lexical_cast<int>(result[1]);
|
||||
m_response_info.m_http_ver_lo = boost::lexical_cast<int>(result[2]);
|
||||
m_response_info.m_response_code = boost::lexical_cast<int>(result[3]);
|
||||
|
||||
m_header_cache.erase(to_nonsonst_iterator(m_header_cache, result[0].first), to_nonsonst_iterator(m_header_cache, result[0].second));
|
||||
return true;
|
||||
}else
|
||||
{
|
||||
LOG_ERROR("http_stream_filter::handle_invoke_reply_line(): Failed to match first response line:" << m_header_cache);
|
||||
return false;
|
||||
// optional \n
|
||||
if (*ptr == '\n')
|
||||
++ptr;
|
||||
// an identifier composed of letters or -
|
||||
const char *key_pos = ptr;
|
||||
while (isalnum(*ptr) || *ptr == '_' || *ptr == '-')
|
||||
++ptr;
|
||||
const char *key_end = ptr;
|
||||
// optional space (not in RFC, but in previous code)
|
||||
if (*ptr == ' ')
|
||||
++ptr;
|
||||
CHECK_AND_ASSERT_MES(*ptr == ':', true, "http_stream_filter::parse_cached_header() invalid header in: " << m_cache_to_process);
|
||||
++ptr;
|
||||
// optional whitespace, but not newlines - line folding is obsolete, let's ignore it
|
||||
while (isblank(*ptr))
|
||||
++ptr;
|
||||
const char *value_pos = ptr;
|
||||
while (*ptr != '\r' && *ptr != '\n')
|
||||
++ptr;
|
||||
const char *value_end = ptr;
|
||||
// optional trailing whitespace
|
||||
while (value_end > value_pos && isblank(*(value_end-1)))
|
||||
--value_end;
|
||||
if (*ptr == '\r')
|
||||
++ptr;
|
||||
CHECK_AND_ASSERT_MES(*ptr == '\n', true, "http_stream_filter::parse_cached_header() invalid header in: " << m_cache_to_process);
|
||||
++ptr;
|
||||
|
||||
const std::string key = std::string(key_pos, key_end - key_pos);
|
||||
const std::string value = std::string(value_pos, value_end - value_pos);
|
||||
if (!key.empty())
|
||||
{
|
||||
if (!string_tools::compare_no_case(key, "Connection"))
|
||||
body_info.m_connection = value;
|
||||
else if(!string_tools::compare_no_case(key, "Referrer"))
|
||||
body_info.m_referer = value;
|
||||
else if(!string_tools::compare_no_case(key, "Content-Length"))
|
||||
body_info.m_content_length = value;
|
||||
else if(!string_tools::compare_no_case(key, "Content-Type"))
|
||||
body_info.m_content_type = value;
|
||||
else if(!string_tools::compare_no_case(key, "Transfer-Encoding"))
|
||||
body_info.m_transfer_encoding = value;
|
||||
else if(!string_tools::compare_no_case(key, "Content-Encoding"))
|
||||
body_info.m_content_encoding = value;
|
||||
else if(!string_tools::compare_no_case(key, "Host"))
|
||||
body_info.m_host = value;
|
||||
else if(!string_tools::compare_no_case(key, "Cookie"))
|
||||
body_info.m_cookie = value;
|
||||
else if(!string_tools::compare_no_case(key, "User-Agent"))
|
||||
body_info.m_user_agent = value;
|
||||
else if(!string_tools::compare_no_case(key, "Origin"))
|
||||
body_info.m_origin = value;
|
||||
else
|
||||
body_info.m_etc_fields.emplace_back(key, value);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
inline bool analize_first_response_line()
|
||||
{
|
||||
//First line response, look like this: "HTTP/1.1 200 OK"
|
||||
const char *ptr = m_header_cache.c_str();
|
||||
CHECK_AND_ASSERT_MES(!memcmp(ptr, "HTTP/", 5), false, "Invalid first response line: " + m_header_cache);
|
||||
ptr += 5;
|
||||
CHECK_AND_ASSERT_MES(isdigit(*ptr), false, "Invalid first response line: " + m_header_cache);
|
||||
unsigned long ul;
|
||||
char *end;
|
||||
ul = strtoul(ptr, &end, 10);
|
||||
CHECK_AND_ASSERT_MES(ul <= INT_MAX && *end =='.', false, "Invalid first response line: " + m_header_cache);
|
||||
m_response_info.m_http_ver_hi = ul;
|
||||
ptr = end + 1;
|
||||
CHECK_AND_ASSERT_MES(isdigit(*ptr), false, "Invalid first response line: " + m_header_cache + ", ptr: " << ptr);
|
||||
ul = strtoul(ptr, &end, 10);
|
||||
CHECK_AND_ASSERT_MES(ul <= INT_MAX && isblank(*end), false, "Invalid first response line: " + m_header_cache + ", ptr: " << ptr);
|
||||
m_response_info.m_http_ver_lo = ul;
|
||||
ptr = end + 1;
|
||||
while (isblank(*ptr))
|
||||
++ptr;
|
||||
CHECK_AND_ASSERT_MES(isdigit(*ptr), false, "Invalid first response line: " + m_header_cache);
|
||||
ul = strtoul(ptr, &end, 10);
|
||||
CHECK_AND_ASSERT_MES(ul >= 100 && ul <= 999 && isspace(*end), false, "Invalid first response line: " + m_header_cache);
|
||||
m_response_info.m_response_code = ul;
|
||||
ptr = end;
|
||||
// ignore the optional text, till the end
|
||||
while (*ptr != '\r' && *ptr != '\n')
|
||||
++ptr;
|
||||
if (*ptr == '\r')
|
||||
++ptr;
|
||||
CHECK_AND_ASSERT_MES(*ptr == '\n', false, "Invalid first response line: " << m_header_cache);
|
||||
++ptr;
|
||||
|
||||
m_header_cache.erase(0, ptr - m_header_cache.c_str());
|
||||
return true;
|
||||
}
|
||||
inline
|
||||
bool set_reply_content_encoder()
|
||||
|
@ -957,6 +988,7 @@ namespace net_utils
|
|||
return true;
|
||||
}
|
||||
};
|
||||
typedef http_simple_client_template<blocked_mode_client> http_simple_client;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,20 @@ fi
|
|||
type="$1"
|
||||
if test -z "$type"
|
||||
then
|
||||
echo "usage: $0 block|transaction|signature|cold-outputs|cold-transaction"
|
||||
echo "usage: $0 block|transaction|signature|cold-outputs|cold-transaction|load-from-binary|load-from-json|base58|parse-url|http-client|levin"
|
||||
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 ;;
|
||||
block|transaction|signature|cold-outputs|cold-transaction|load-from-binary|load-from-json|base58|parse-url|http-client|levin) ;;
|
||||
*) echo "usage: $0 block|transaction|signature|cold-outputs|cold-transaction|load-from-binary|load-from-json|base58|parse-url|http-client|levin"; 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
|
||||
if test -d "fuzz-out/$type"
|
||||
then
|
||||
dir="-"
|
||||
else
|
||||
dir="tests/data/fuzz/$type"
|
||||
fi
|
||||
|
||||
mkdir -p fuzz-out
|
||||
afl-fuzz -i "$dir" -m none -t 250 -o fuzz-out/$type build/fuzz/tests/fuzz/${type}_fuzz_tests @@
|
||||
|
|
0
tests/data/fuzz/base58/ENC1
Normal file
0
tests/data/fuzz/base58/ENC1
Normal file
1
tests/data/fuzz/base58/ENC2
Normal file
1
tests/data/fuzz/base58/ENC2
Normal file
|
@ -0,0 +1 @@
|
|||
9zZBkWRgMNPEnVofRFqWK9MKBwgXNyKELBJSttxb1t2UhDM114URntt5iYcXzXusoHZygfSojsbviXZhnP9pJ4p2SDcv81L
|
8
tests/data/fuzz/http-client/RESP1
Normal file
8
tests/data/fuzz/http-client/RESP1
Normal file
|
@ -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
|
BIN
tests/data/fuzz/levin/LEVIN1
Normal file
BIN
tests/data/fuzz/levin/LEVIN1
Normal file
Binary file not shown.
BIN
tests/data/fuzz/load-from-binary/BINARY1
Normal file
BIN
tests/data/fuzz/load-from-binary/BINARY1
Normal file
Binary file not shown.
1
tests/data/fuzz/load-from-json/JSON1
Normal file
1
tests/data/fuzz/load-from-json/JSON1
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
1
tests/data/fuzz/parse-url/URL1
Normal file
1
tests/data/fuzz/parse-url/URL1
Normal file
|
@ -0,0 +1 @@
|
|||
127.0.0.1
|
1
tests/data/fuzz/parse-url/URL2
Normal file
1
tests/data/fuzz/parse-url/URL2
Normal file
|
@ -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=
|
|
@ -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")
|
||||
|
||||
|
|
74
tests/fuzz/base58.cpp
Normal file
74
tests/fuzz/base58.cpp
Normal file
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
98
tests/fuzz/http-client.cpp
Normal file
98
tests/fuzz/http-client.cpp
Normal file
|
@ -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);
|
||||
}
|
||||
|
345
tests/fuzz/levin.cpp
Normal file
345
tests/fuzz/levin.cpp
Normal file
|
@ -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);
|
||||
}
|
||||
|
76
tests/fuzz/load_from_binary.cpp
Normal file
76
tests/fuzz/load_from_binary.cpp
Normal file
|
@ -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);
|
||||
}
|
||||
|
76
tests/fuzz/load_from_json.cpp
Normal file
76
tests/fuzz/load_from_json.cpp
Normal file
|
@ -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);
|
||||
}
|
||||
|
74
tests/fuzz/parse_url.cpp
Normal file
74
tests/fuzz/parse_url.cpp
Normal file
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in a new issue