diff options
50 files changed, 1048 insertions, 600 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5a37403b8..36eab5027 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,6 +2,15 @@ name: ci/gh-actions/cli on: [push, pull_request] +# The below variables reduce repetitions across similar targets +env: + REMOVE_BUNDLED_BOOST : rm -rf /usr/local/share/boost + APT_INSTALL_LINUX: 'sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler ccache' + APT_SET_CONF: | + echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom + echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom + echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom + jobs: build-macos: runs-on: macOS-latest @@ -66,16 +75,13 @@ jobs: key: ccache-ubuntu-build-${{ github.sha }} restore-keys: ccache-ubuntu-build- - name: remove bundled boost - run: sudo rm -rf /usr/local/share/boost + run: ${{env.REMOVE_BUNDLED_BOOST}} - name: set apt conf - run: | - echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom - echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom - echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom + run: ${{env.APT_SET_CONF}} - name: update apt run: sudo apt update - name: install monero dependencies - run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler ccache + run: ${{env.APT_INSTALL_LINUX}} - name: build run: | ccache --max-size=150M @@ -96,16 +102,13 @@ jobs: key: ccache-ubuntu-libwallet-${{ github.sha }} restore-keys: ccache-ubuntu-libwallet- - name: remove bundled boost - run: sudo rm -rf /usr/local/share/boost + run: ${{env.REMOVE_BUNDLED_BOOST}} - name: set apt conf - run: | - echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom - echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom - echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom + run: ${{env.APT_SET_CONF}} - name: update apt run: sudo apt update - name: install monero dependencies - run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler ccache + run: ${{env.APT_INSTALL_LINUX}} - name: build run: | ccache --max-size=150M @@ -129,16 +132,13 @@ jobs: key: test-ubuntu-ccache-${{ github.sha }} restore-keys: test-ubuntu-ccache- - name: remove bundled boost - run: sudo rm -rf /usr/local/share/boost + run: ${{env.REMOVE_BUNDLED_BOOST}} - name: set apt conf - run: | - echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom - echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom - echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom + run: ${{env.APT_SET_CONF}} - name: update apt run: sudo apt update - name: install monero dependencies - run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler ccache + run: ${{env.APT_INSTALL_LINUX}} - name: install Python dependencies run: pip install requests psutil monotonic - name: tests diff --git a/CMakeLists.txt b/CMakeLists.txt index 953707657..511c62a4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,6 +164,18 @@ function (monero_add_minimal_executable name) monero_set_target_no_relink( ${name} ) endfunction() +# Finds all headers in a directory and its subdirs, to be able to search for them and autosave in IDEs. +# +# Parameters: +# - headers_found: Output variable, which will hold the found headers +# - module_root_dir: The search path for the headers. Typically it will be the module's root dir. +macro (monero_find_all_headers headers_found module_root_dir) + file(GLOB ${headers_found} + "${module_root_dir}/*.h*" # h* will include hpps as well. + "${module_root_dir}/**/*.h*" # Any number of subdirs will be included. +) +endmacro() + if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) message(STATUS "Setting default build type: ${CMAKE_BUILD_TYPE}") @@ -513,6 +525,20 @@ add_definitions(-DAUTO_INITIALIZE_EASYLOGGINGPP) set(MONERO_GENERATED_HEADERS_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated_include") include_directories(${MONERO_GENERATED_HEADERS_DIR}) +option(COVERAGE "Enable profiling for test coverage report" OFF) +if(COVERAGE) + message(STATUS "Building with profiling for test coverage report") +endif() +macro (monero_enable_coverage) + if(COVERAGE) + foreach(COV_FLAG -fprofile-arcs -ftest-coverage --coverage) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COV_FLAG}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COV_FLAG}") + endforeach() + endif() +endmacro() + + # Generate header for embedded translations # Generate header for embedded translations, use target toolchain if depends, otherwise use the # lrelease and lupdate binaries from the host @@ -676,13 +702,7 @@ else() set(STATIC_ASSERT_CPP_FLAG "-Dstatic_assert=_Static_assert") endif() - option(COVERAGE "Enable profiling for test coverage report" 0) - - if(COVERAGE) - message(STATUS "Building with profiling for test coverage report") - set(COVERAGE_FLAGS "-fprofile-arcs -ftest-coverage --coverage") - endif() - + monero_enable_coverage() # With GCC 6.1.1 the compiled binary malfunctions due to aliasing. Until that # is fixed in the code (Issue #847), force compiler to be conservative. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-strict-aliasing") @@ -759,8 +779,8 @@ else() message(STATUS "Using C++ security hardening flags: ${CXX_SECURITY_FLAGS}") message(STATUS "Using linker security hardening flags: ${LD_SECURITY_FLAGS}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${COVERAGE_FLAGS} ${PIC_FLAG} ${C_SECURITY_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_CPP_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${COVERAGE_FLAGS} ${PIC_FLAG} ${CXX_SECURITY_FLAGS}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${PIC_FLAG} ${C_SECURITY_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_CPP_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${PIC_FLAG} ${CXX_SECURITY_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LD_SECURITY_FLAGS} ${LD_BACKCOMPAT_FLAGS}") # With GCC 6.1.1 the compiled binary malfunctions due to aliasing. Until that diff --git a/Dockerfile b/Dockerfile index 51fd51e1c..f21f74ac3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -46,7 +46,7 @@ ARG BOOST_VERSION=1_70_0 ARG BOOST_VERSION_DOT=1.70.0 ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778 RUN set -ex \ - && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \ + && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \ && echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \ && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \ && cd boost_${BOOST_VERSION} \ diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 511f0416e..046115bd3 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -26,5 +26,6 @@ # 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. +monero_enable_coverage() add_subdirectory(epee) diff --git a/contrib/depends/packages/boost.mk b/contrib/depends/packages/boost.mk index 0d241928e..4571d4232 100644 --- a/contrib/depends/packages/boost.mk +++ b/contrib/depends/packages/boost.mk @@ -1,6 +1,6 @@ package=boost $(package)_version=1_64_0 -$(package)_download_path=https://dl.bintray.com/boostorg/release/1.64.0/source/ +$(package)_download_path=https://downloads.sourceforge.net/project/boost/boost/1.64.0/ $(package)_file_name=$(package)_$($(package)_version).tar.bz2 $(package)_sha256_hash=7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332 $(package)_dependencies=libiconv diff --git a/contrib/epee/include/memwipe.h b/contrib/epee/include/memwipe.h index c6e8f072c..c6f247913 100644 --- a/contrib/epee/include/memwipe.h +++ b/contrib/epee/include/memwipe.h @@ -32,6 +32,7 @@ #ifdef __cplusplus #include <array> +#include <cstddef> extern "C" { #endif diff --git a/contrib/epee/include/misc_os_dependent.h b/contrib/epee/include/misc_os_dependent.h index 5fffde8d5..522cdf263 100644 --- a/contrib/epee/include/misc_os_dependent.h +++ b/contrib/epee/include/misc_os_dependent.h @@ -47,7 +47,7 @@ #endif #include <iostream> -#include <boost/lexical_cast.hpp> +#include <ctime> #pragma once namespace epee @@ -115,15 +115,7 @@ namespace misc_utils } - - inline std::string get_thread_string_id() - { -#if defined(_WIN32) - return boost::lexical_cast<std::string>(GetCurrentThreadId()); -#elif defined(__GNUC__) - return boost::lexical_cast<std::string>(pthread_self()); -#endif - } + std::string get_thread_string_id(); inline bool get_gmt_time(time_t t, struct tm &tm) { diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index 61e2b30fe..89971bea2 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -42,7 +42,7 @@ #include <boost/make_shared.hpp> #include <boost/thread.hpp> #include "warnings.h" -#include "string_tools.h" +#include "string_tools_lexical.h" #include "misc_language.h" #include "net/local_ip.h" #include "pragma_comp_defs.h" diff --git a/contrib/epee/include/net/http_base.h b/contrib/epee/include/net/http_base.h index bf6589c92..4af4da790 100644 --- a/contrib/epee/include/net/http_base.h +++ b/contrib/epee/include/net/http_base.h @@ -27,14 +27,13 @@ #pragma once -#include <boost/lexical_cast.hpp> -#include <boost/regex.hpp> +#include "memwipe.h" + #include <boost/utility/string_ref.hpp> + #include <string> #include <utility> - -#include "memwipe.h" -#include "string_tools.h" +#include <list> #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "net.http" @@ -66,34 +65,9 @@ namespace net_utils typedef std::list<std::pair<std::string, std::string> > fields_list; - inline - std::string get_value_from_fields_list(const std::string& param_name, const net_utils::http::fields_list& fields) - { - fields_list::const_iterator it = fields.begin(); - for(; it != fields.end(); it++) - if(!string_tools::compare_no_case(param_name, it->first)) - break; - - if(it==fields.end()) - return std::string(); + std::string get_value_from_fields_list(const std::string& param_name, const net_utils::http::fields_list& fields); - return it->second; - } - - - inline - std::string get_value_from_uri_line(const std::string& param_name, const std::string& uri) - { - std::string buff = "([\\?|&])"; - buff += param_name + "=([^&]*)"; - boost::regex match_param(buff.c_str(), boost::regex::icase | boost::regex::normal); - boost::smatch result; - if(boost::regex_search(uri, result, match_param, boost::match_default) && result[0].matched) - { - return result[2]; - } - return std::string(); - } + std::string get_value_from_uri_line(const std::string& param_name, const std::string& uri); static inline void add_field(std::string& out, const boost::string_ref name, const boost::string_ref value) { diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h index 3725ef079..29ef82fb1 100644 --- a/contrib/epee/include/net/http_client.h +++ b/contrib/epee/include/net/http_client.h @@ -30,7 +30,6 @@ #include <ctype.h> #include <boost/shared_ptr.hpp> #include <boost/regex.hpp> -#include <boost/lexical_cast.hpp> #include <boost/optional/optional.hpp> #include <boost/utility/string_ref.hpp> //#include <mbstring.h> @@ -46,6 +45,7 @@ #endif #include "string_tools.h" +#include "string_tools_lexical.h" #include "reg_exp_definer.h" #include "abstract_http_client.h" #include "http_base.h" diff --git a/contrib/epee/include/net/net_parse_helpers.h b/contrib/epee/include/net/net_parse_helpers.h index cf637ba1d..d794dd51c 100644 --- a/contrib/epee/include/net/net_parse_helpers.h +++ b/contrib/epee/include/net/net_parse_helpers.h @@ -24,12 +24,9 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // - - - #pragma once + #include "http_base.h" -#include "reg_exp_definer.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "net" @@ -38,173 +35,8 @@ namespace epee { namespace net_utils { - - inline bool parse_uri_query(const std::string& query, std::list<std::pair<std::string, std::string> >& params) - { - enum state - { - st_param_name, - st_param_val - }; - state st = st_param_name; - std::string::const_iterator start_it = query.begin(); - std::pair<std::string, std::string> e; - for(std::string::const_iterator it = query.begin(); it != query.end(); it++) - { - switch(st) - { - case st_param_name: - if(*it == '=') - { - e.first.assign(start_it, it); - start_it = it;++start_it; - st = st_param_val; - } - break; - case st_param_val: - if(*it == '&') - { - e.second.assign(start_it, it); - start_it = it;++start_it; - params.push_back(e); - e.first.clear();e.second.clear(); - st = st_param_name; - } - break; - default: - LOG_ERROR("Unknown state " << (int)st); - return false; - } - } - if(st == st_param_name) - { - if(start_it != query.end()) - { - e.first.assign(start_it, query.end()); - params.push_back(e); - } - }else - { - if(start_it != query.end()) - e.second.assign(start_it, query.end()); - - if(e.first.size()) - params.push_back(e); - } - return true; - } - - inline - bool parse_uri(const std::string uri, http::uri_content& content) - { - - ///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= - content.m_query_params.clear(); - STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal); - - boost::smatch result; - if(!(boost::regex_search(uri, result, rexp_match_uri, boost::match_default) && result[0].matched)) - { - LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << uri); - content.m_path = uri; - return true; - } - if(result[1].matched) - { - content.m_path = result[1]; - } - if(result[3].matched) - { - content.m_query = result[3]; - } - if(result[5].matched) - { - content.m_fragment = result[5]; - } - if(content.m_query.size()) - { - parse_uri_query(content.m_query, content.m_query_params); - } - return true; - } - - inline - bool parse_url_ipv6(const std::string url_str, http::url_content& content) - { - STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(\\[(.*)\\](:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal); - // 12 3 4 5 6 7 - - content.port = 0; - boost::smatch result; - if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched)) - { - LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri); - //content.m_path = uri; - return false; - } - if(result[2].matched) - { - content.schema = result[2]; - } - if(result[4].matched) - { - content.host = result[4]; - } - else // if host not matched, matching should be considered failed - { - return false; - } - if(result[6].matched) - { - content.port = boost::lexical_cast<uint64_t>(result[6]); - } - if(result[7].matched) - { - content.uri = result[7]; - return parse_uri(result[7], content.m_uri_content); - } - - return true; - } - - inline - bool parse_url(const std::string url_str, http::url_content& content) - { - - if (parse_url_ipv6(url_str, content)) return true; - - ///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= - //STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal); - STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(([^/:]*)(:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal); - // 12 34 5 6 7 - content.port = 0; - boost::smatch result; - if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched)) - { - LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri); - //content.m_path = uri; - return true; - } - if(result[2].matched) - { - content.schema = result[2]; - } - if(result[4].matched) - { - content.host = result[4]; - } - if(result[6].matched) - { - content.port = boost::lexical_cast<uint64_t>(result[6]); - } - if(result[7].matched) - { - content.uri = result[7]; - return parse_uri(result[7], content.m_uri_content); - } - - return true; - } - + bool parse_uri(const std::string uri, http::uri_content& content); + bool parse_url_ipv6(const std::string url_str, http::url_content& content); + bool parse_url(const std::string url_str, http::url_content& content); } } diff --git a/contrib/epee/include/reg_exp_definer.h b/contrib/epee/include/reg_exp_definer.h index eb11c9e10..386a45f9a 100644 --- a/contrib/epee/include/reg_exp_definer.h +++ b/contrib/epee/include/reg_exp_definer.h @@ -29,6 +29,7 @@ #define _REG_EXP_DEFINER_H_ #include <boost/interprocess/detail/atomic.hpp> +#include <boost/regex.hpp> #include "syncobj.h" namespace epee diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h index 2d9317d60..dbbe1906e 100644 --- a/contrib/epee/include/string_tools.h +++ b/contrib/epee/include/string_tools.h @@ -24,33 +24,16 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // - - #ifndef _STRING_TOOLS_H_ #define _STRING_TOOLS_H_ -// Previously pulled in by ASIO, further cleanup still required ... -#ifdef _WIN32 -# include <winsock2.h> -# include <windows.h> -#endif - -#include <string.h> -#include <locale> -#include <cstdlib> -#include <string> -#include <type_traits> -#include <boost/lexical_cast.hpp> -#include <boost/algorithm/string/predicate.hpp> -#include <boost/utility/string_ref.hpp> -#include "misc_log_ex.h" -#include "storages/parserse_base_utils.h" #include "hex.h" -#include "memwipe.h" #include "mlocker.h" -#include "span.h" -#include "warnings.h" +#include <boost/utility/string_ref.hpp> +#include <sstream> +#include <string> +#include <cstdint> #ifndef OUT #define OUT @@ -74,202 +57,38 @@ namespace string_tools { return from_hex::to_string(res, s); } - //---------------------------------------------------------------------------- -PUSH_WARNINGS -DISABLE_GCC_WARNING(maybe-uninitialized) - template<class XType> - inline bool get_xtype_from_string(OUT XType& val, const std::string& str_id) - { - if (std::is_integral<XType>::value && !std::numeric_limits<XType>::is_signed && !std::is_same<XType, bool>::value) - { - for (char c : str_id) - { - if (!epee::misc_utils::parse::isdigit(c)) - return false; - } - } - - try - { - val = boost::lexical_cast<XType>(str_id); - return true; - } - catch(const std::exception& /*e*/) - { - //const char* pmsg = e.what(); - return false; - } - catch(...) - { - return false; - } - - return true; - } -POP_WARNINGS - //---------------------------------------------------------------------------- - template<class XType> - inline bool xtype_to_string(const XType& val, std::string& str) - { - try - { - str = boost::lexical_cast<std::string>(val); - } - catch(...) - { - return false; - } - - return true; - } - //---------------------------------------------------------------------------- - std::string get_ip_string_from_int32(uint32_t ip); - //---------------------------------------------------------------------------- - bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str); - //---------------------------------------------------------------------------- - inline bool parse_peer_from_string(uint32_t& ip, uint16_t& port, const std::string& addres) - { - //parse ip and address - std::string::size_type p = addres.find(':'); - std::string ip_str, port_str; - if(p == std::string::npos) - { - port = 0; - ip_str = addres; - } - else - { - ip_str = addres.substr(0, p); - port_str = addres.substr(p+1, addres.size()); - } - - if(!get_ip_int32_from_string(ip, ip_str)) - { - return false; - } - - if(p != std::string::npos && !get_xtype_from_string(port, port_str)) - { - return false; - } - return true; - } - - inline std::string num_to_string_fast(int64_t val) - { - /* - char buff[30] = {0}; - i64toa_s(val, buff, sizeof(buff)-1, 10); - return buff;*/ - return boost::lexical_cast<std::string>(val); - } - //---------------------------------------------------------------------------- - template<typename T> - inline std::string to_string_hex(const T &val) - { - static_assert(std::is_arithmetic<T>::value, "only arithmetic types"); - std::stringstream ss; - ss << std::hex << val; - std::string s; - ss >> s; - return s; - } - //---------------------------------------------------------------------------- + + std::string get_ip_string_from_int32(uint32_t ip); + bool get_ip_int32_from_string(uint32_t& ip, const std::string& ip_str); + bool parse_peer_from_string(uint32_t& ip, uint16_t& port, const std::string& addres); + std::string num_to_string_fast(int64_t val); - inline bool compare_no_case(const std::string& str1, const std::string& str2) - { - - return !boost::iequals(str1, str2); - } - //---------------------------------------------------------------------------- - inline std::string& get_current_module_name() - { - static std::string module_name; - return module_name; - } - //---------------------------------------------------------------------------- - inline std::string& get_current_module_folder() - { - static std::string module_folder; - return module_folder; - } - //---------------------------------------------------------------------------- + bool compare_no_case(const std::string& str1, const std::string& str2); + std::string& get_current_module_name(); + std::string& get_current_module_folder(); #ifdef _WIN32 - inline std::string get_current_module_path() - { - char pname [5000] = {0}; - GetModuleFileNameA( NULL, pname, sizeof(pname)); - pname[sizeof(pname)-1] = 0; //be happy ;) - return pname; - } + std::string get_current_module_path(); #endif - //---------------------------------------------------------------------------- - inline bool set_module_name_and_folder(const std::string& path_to_process_) - { - std::string path_to_process = path_to_process_; -#ifdef _WIN32 - path_to_process = get_current_module_path(); -#endif - std::string::size_type a = path_to_process.rfind( '\\' ); - if(a == std::string::npos ) - { - a = path_to_process.rfind( '/' ); - } - if ( a != std::string::npos ) - { - get_current_module_name() = path_to_process.substr(a+1, path_to_process.size()); - get_current_module_folder() = path_to_process.substr(0, a); - return true; - }else - return false; - - } - - //---------------------------------------------------------------------------- - inline bool trim_left(std::string& str) - { - for(std::string::iterator it = str.begin(); it!= str.end() && isspace(static_cast<unsigned char>(*it));) - str.erase(str.begin()); - - return true; - } - //---------------------------------------------------------------------------- - inline bool trim_right(std::string& str) - { - - for(std::string::reverse_iterator it = str.rbegin(); it!= str.rend() && isspace(static_cast<unsigned char>(*it));) - str.erase( --((it++).base())); - - return true; - } - //---------------------------------------------------------------------------- - inline std::string& trim(std::string& str) - { - - trim_left(str); - trim_right(str); - return str; - } + bool set_module_name_and_folder(const std::string& path_to_process_); + bool trim_left(std::string& str); + bool trim_right(std::string& str); //---------------------------------------------------------------------------- - inline std::string trim(const std::string& str_) + inline std::string& trim(std::string& str) { - std::string str = str_; trim_left(str); trim_right(str); return str; } //---------------------------------------------------------------------------- - inline std::string pad_string(std::string s, size_t n, char c = ' ', bool prepend = false) + inline std::string trim(const std::string& str_) { - if (s.size() < n) - { - if (prepend) - s = std::string(n - s.size(), c) + s; - else - s.append(n - s.size(), c); - } - return s; + std::string str = str_; + trim_left(str); + trim_right(str); + return str; } + std::string pad_string(std::string s, size_t n, char c = ' ', bool prepend = false); + //---------------------------------------------------------------------------- template<class t_pod_type> std::string pod_to_hex(const t_pod_type& s) @@ -296,64 +115,25 @@ POP_WARNINGS { return hex_to_pod(hex_str, unwrap(s)); } - //---------------------------------------------------------------------------- - bool validate_hex(uint64_t length, const std::string& str); - //---------------------------------------------------------------------------- - inline std::string get_extension(const std::string& str) - { - std::string res; - std::string::size_type pos = str.rfind('.'); - if(std::string::npos == pos) - return res; - - res = str.substr(pos+1, str.size()-pos); - return res; - } - //---------------------------------------------------------------------------- - inline std::string cut_off_extension(const std::string& str) + //---------------------------------------------------------------------------- + template<typename T> + inline std::string to_string_hex(const T &val) { - std::string res; - std::string::size_type pos = str.rfind('.'); - if(std::string::npos == pos) - return str; - - res = str.substr(0, pos); - return res; + static_assert(std::is_arithmetic<T>::value, "only arithmetic types"); + std::stringstream ss; + ss << std::hex << val; + std::string s; + ss >> s; + return s; } - //---------------------------------------------------------------------------- + + bool validate_hex(uint64_t length, const std::string& str); + std::string get_extension(const std::string& str); + std::string cut_off_extension(const std::string& str); + #ifdef _WIN32 - inline std::wstring utf8_to_utf16(const std::string& str) - { - if (str.empty()) - return {}; - int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0); - if (wstr_size == 0) - { - throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); - } - std::wstring wstr(wstr_size, wchar_t{}); - if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size)) - { - throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); - } - return wstr; - } - inline std::string utf16_to_utf8(const std::wstring& wstr) - { - if (wstr.empty()) - return {}; - int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL); - if (str_size == 0) - { - throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); - } - std::string str(str_size, char{}); - if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL)) - { - throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); - } - return str; - } + std::wstring utf8_to_utf16(const std::string& str); + std::string utf16_to_utf8(const std::wstring& wstr); #endif } } diff --git a/contrib/epee/include/string_tools_lexical.h b/contrib/epee/include/string_tools_lexical.h new file mode 100644 index 000000000..01be562bc --- /dev/null +++ b/contrib/epee/include/string_tools_lexical.h @@ -0,0 +1,91 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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. +// + +#ifndef _STRING_TOOLS_LEXICAL_H_ +#define _STRING_TOOLS_LEXICAL_H_ + +#include "warnings.h" +#include "storages/parserse_base_utils.h" +#include <boost/lexical_cast.hpp> // A heavy header, that was extracted from the rest + +#ifndef OUT + #define OUT +#endif + +namespace epee +{ +namespace string_tools +{ +PUSH_WARNINGS +DISABLE_GCC_WARNING(maybe-uninitialized) + template<class XType> + inline bool get_xtype_from_string(OUT XType& val, const std::string& str_id) + { + if (std::is_integral<XType>::value && !std::numeric_limits<XType>::is_signed && !std::is_same<XType, bool>::value) + { + for (char c : str_id) + { + if (!epee::misc_utils::parse::isdigit(c)) + return false; + } + } + + try + { + val = boost::lexical_cast<XType>(str_id); + return true; + } + catch(const std::exception& /*e*/) + { + //const char* pmsg = e.what(); + return false; + } + catch(...) + { + return false; + } + + return true; + } +POP_WARNINGS + + template<class XType> + inline bool xtype_to_string(const XType& val, std::string& str) + { + try + { + str = boost::lexical_cast<std::string>(val); + } + catch(...) + { + return false; + } + + return true; + } +} +} +#endif //_STRING_TOOLS_LEXICAL_H_ diff --git a/contrib/epee/include/tiny_ini.h b/contrib/epee/include/tiny_ini.h index 2bc71fc1a..6ced548eb 100644 --- a/contrib/epee/include/tiny_ini.h +++ b/contrib/epee/include/tiny_ini.h @@ -28,8 +28,6 @@ #ifndef _TINY_INI_H_ #define _TINY_INI_H_ -#include <boost/regex.hpp> -#include <boost/lexical_cast.hpp> #include "string_tools.h" namespace epee @@ -37,20 +35,8 @@ namespace epee namespace tiny_ini { - inline - bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res) - { - std::string expr_str = std::string() + "^("+ param_name +") *=(.*?)$"; - const boost::regex match_ini_entry( expr_str, boost::regex::icase | boost::regex::normal); - boost::smatch result; - if(!boost::regex_search(ini_entry, result, match_ini_entry, boost::match_default)) - return false; - res = result[2]; - string_tools::trim(res); - return true; - } - inline - std::string get_param_value(const std::string& param_name, const std::string& ini_entry) + bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res); + inline std::string get_param_value(const std::string& param_name, const std::string& ini_entry) { std::string buff; get_param_value(param_name, ini_entry, buff); diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt index 132fed355..0f0a6ecad 100644 --- a/contrib/epee/src/CMakeLists.txt +++ b/contrib/epee/src/CMakeLists.txt @@ -28,17 +28,18 @@ set(EPEE_INCLUDE_DIR_BASE "${CMAKE_CURRENT_SOURCE_DIR}/../include") -# Adding headers to the file list, to be able to search for them in IDEs. -file(GLOB EPEE_HEADERS_PUBLIC - "${EPEE_INCLUDE_DIR_BASE}/*.h*" # h* will include hpps as well. - "${EPEE_INCLUDE_DIR_BASE}/**/*.h*" # Any number of subdirs will be included. -) +# Add headers to the file list, to be able to search for them and autosave in IDEs. +monero_find_all_headers(EPEE_HEADERS_PUBLIC "${EPEE_INCLUDE_DIR_BASE}") add_library(epee STATIC byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp wipeable_string.cpp levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp int-util.cpp portable_storage.cpp misc_language.cpp + misc_os_dependent.cpp file_io_utils.cpp + net_parse_helpers.cpp + http_base.cpp + tiny_ini.cpp ${EPEE_HEADERS_PUBLIC} ) diff --git a/contrib/epee/src/abstract_http_client.cpp b/contrib/epee/src/abstract_http_client.cpp index 540917873..3ae09c90e 100644 --- a/contrib/epee/src/abstract_http_client.cpp +++ b/contrib/epee/src/abstract_http_client.cpp @@ -1,6 +1,7 @@ #include "net/abstract_http_client.h" #include "net/http_base.h" #include "net/net_parse_helpers.h" +#include "misc_log_ex.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "net.http" diff --git a/contrib/epee/src/http_base.cpp b/contrib/epee/src/http_base.cpp new file mode 100644 index 000000000..647dfb899 --- /dev/null +++ b/contrib/epee/src/http_base.cpp @@ -0,0 +1,71 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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 "net/http_base.h" +#include "memwipe.h" +#include "string_tools.h" + +#include <boost/regex.hpp> +#include <string> +#include <utility> + +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "net.http" + +namespace epee +{ +namespace net_utils +{ +namespace http +{ + std::string get_value_from_fields_list(const std::string& param_name, const net_utils::http::fields_list& fields) + { + fields_list::const_iterator it = fields.begin(); + for(; it != fields.end(); it++) + if(!string_tools::compare_no_case(param_name, it->first)) + break; + + if(it==fields.end()) + return std::string(); + + return it->second; + } + + std::string get_value_from_uri_line(const std::string& param_name, const std::string& uri) + { + std::string buff = "([\\?|&])"; + buff += param_name + "=([^&]*)"; + boost::regex match_param(buff.c_str(), boost::regex::icase | boost::regex::normal); + boost::smatch result; + if(boost::regex_search(uri, result, match_param, boost::match_default) && result[0].matched) + { + return result[2]; + } + return std::string(); + } +} +} +} diff --git a/contrib/epee/src/misc_os_dependent.cpp b/contrib/epee/src/misc_os_dependent.cpp new file mode 100644 index 000000000..cd4967131 --- /dev/null +++ b/contrib/epee/src/misc_os_dependent.cpp @@ -0,0 +1,44 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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 "misc_os_dependent.h" +#include <boost/lexical_cast.hpp> + +namespace epee +{ +namespace misc_utils +{ + // TODO: (vtnerd) This function is weird since boost::this_thread::get_id() exists but returns a different value. + std::string get_thread_string_id() + { +#if defined(_WIN32) + return boost::lexical_cast<std::string>(GetCurrentThreadId()); +#elif defined(__GNUC__) + return boost::lexical_cast<std::string>(pthread_self()); +#endif + } +} +} diff --git a/contrib/epee/src/net_parse_helpers.cpp b/contrib/epee/src/net_parse_helpers.cpp new file mode 100644 index 000000000..de7843b67 --- /dev/null +++ b/contrib/epee/src/net_parse_helpers.cpp @@ -0,0 +1,206 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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 "net/net_parse_helpers.h" +#include "net/http_base.h" +#include "misc_log_ex.h" +#include "reg_exp_definer.h" +#include <boost/lexical_cast.hpp> + +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "net" + +namespace epee +{ +namespace net_utils +{ + + static bool parse_uri_query(const std::string& query, std::list<std::pair<std::string, std::string> >& params) + { + enum state + { + st_param_name, + st_param_val + }; + state st = st_param_name; + std::string::const_iterator start_it = query.begin(); + std::pair<std::string, std::string> e; + for(std::string::const_iterator it = query.begin(); it != query.end(); it++) + { + switch(st) + { + case st_param_name: + if(*it == '=') + { + e.first.assign(start_it, it); + start_it = it;++start_it; + st = st_param_val; + } + break; + case st_param_val: + if(*it == '&') + { + e.second.assign(start_it, it); + start_it = it;++start_it; + params.push_back(e); + e.first.clear();e.second.clear(); + st = st_param_name; + } + break; + default: + LOG_ERROR("Unknown state " << (int)st); + return false; + } + } + if(st == st_param_name) + { + if(start_it != query.end()) + { + e.first.assign(start_it, query.end()); + params.push_back(e); + } + }else + { + if(start_it != query.end()) + e.second.assign(start_it, query.end()); + + if(e.first.size()) + params.push_back(e); + } + return true; + } + + bool parse_uri(const std::string uri, http::uri_content& content) + { + + ///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= + content.m_query_params.clear(); + STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal); + + boost::smatch result; + if(!(boost::regex_search(uri, result, rexp_match_uri, boost::match_default) && result[0].matched)) + { + LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << uri); + content.m_path = uri; + return true; + } + if(result[1].matched) + { + content.m_path = result[1]; + } + if(result[3].matched) + { + content.m_query = result[3]; + } + if(result[5].matched) + { + content.m_fragment = result[5]; + } + if(content.m_query.size()) + { + parse_uri_query(content.m_query, content.m_query_params); + } + return true; + } + + bool parse_url_ipv6(const std::string url_str, http::url_content& content) + { + STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(\\[(.*)\\](:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal); + // 12 3 4 5 6 7 + + content.port = 0; + boost::smatch result; + if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched)) + { + LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri); + //content.m_path = uri; + return false; + } + if(result[2].matched) + { + content.schema = result[2]; + } + if(result[4].matched) + { + content.host = result[4]; + } + else // if host not matched, matching should be considered failed + { + return false; + } + if(result[6].matched) + { + content.port = boost::lexical_cast<uint64_t>(result[6]); + } + if(result[7].matched) + { + content.uri = result[7]; + return parse_uri(result[7], content.m_uri_content); + } + + return true; + } + + bool parse_url(const std::string url_str, http::url_content& content) + { + + if (parse_url_ipv6(url_str, content)) return true; + + ///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= + //STATIC_REGEXP_EXPR_1(rexp_match_uri, "^([^?#]*)(\\?([^#]*))?(#(.*))?", boost::regex::icase | boost::regex::normal); + STATIC_REGEXP_EXPR_1(rexp_match_uri, "^(([^:]*?)://)?(([^/:]*)(:(\\d+))?)(.*)?", boost::regex::icase | boost::regex::normal); + // 12 34 5 6 7 + content.port = 0; + boost::smatch result; + if(!(boost::regex_search(url_str, result, rexp_match_uri, boost::match_default) && result[0].matched)) + { + LOG_PRINT_L1("[PARSE URI] regex not matched for uri: " << rexp_match_uri); + //content.m_path = uri; + return true; + } + if(result[2].matched) + { + content.schema = result[2]; + } + if(result[4].matched) + { + content.host = result[4]; + } + if(result[6].matched) + { + content.port = boost::lexical_cast<uint64_t>(result[6]); + } + if(result[7].matched) + { + content.uri = result[7]; + return parse_uri(result[7], content.m_uri_content); + } + + return true; + } + +} +} diff --git a/contrib/epee/src/string_tools.cpp b/contrib/epee/src/string_tools.cpp index fd0254016..984a151b5 100644 --- a/contrib/epee/src/string_tools.cpp +++ b/contrib/epee/src/string_tools.cpp @@ -25,6 +25,29 @@ // #include "string_tools.h" +#include "string_tools_lexical.h" + + +// Previously pulled in by ASIO, further cleanup still required ... +#ifdef _WIN32 +# include <winsock2.h> +# include <windows.h> +#endif + +#include <locale> +#include <cstdlib> +#include <string> +#include <type_traits> +#include <boost/lexical_cast.hpp> +#include <boost/algorithm/string/predicate.hpp> +#include <boost/utility/string_ref.hpp> +#include "misc_log_ex.h" +#include "storages/parserse_base_utils.h" +#include "hex.h" +#include "memwipe.h" +#include "mlocker.h" +#include "span.h" +#include "warnings.h" #include <ctype.h> @@ -68,6 +91,180 @@ namespace string_tools return false; return true; } + //---------------------------------------------------------------------------- + bool parse_peer_from_string(uint32_t& ip, uint16_t& port, const std::string& addres) + { + //parse ip and address + std::string::size_type p = addres.find(':'); + std::string ip_str, port_str; + if(p == std::string::npos) + { + port = 0; + ip_str = addres; + } + else + { + ip_str = addres.substr(0, p); + port_str = addres.substr(p+1, addres.size()); + } + + if(!get_ip_int32_from_string(ip, ip_str)) + { + return false; + } + + if(p != std::string::npos && !get_xtype_from_string(port, port_str)) + { + return false; + } + return true; + } + + std::string num_to_string_fast(int64_t val) + { + /* + char buff[30] = {0}; + i64toa_s(val, buff, sizeof(buff)-1, 10); + return buff;*/ + return boost::lexical_cast<std::string>(val); + } + + + bool compare_no_case(const std::string& str1, const std::string& str2) + { + + return !boost::iequals(str1, str2); + } + //---------------------------------------------------------------------------- + std::string& get_current_module_name() + { + static std::string module_name; + return module_name; + } + //---------------------------------------------------------------------------- + std::string& get_current_module_folder() + { + static std::string module_folder; + return module_folder; + } + +#ifdef _WIN32 + std::string get_current_module_path() + { + char pname [5000] = {0}; + GetModuleFileNameA( NULL, pname, sizeof(pname)); + pname[sizeof(pname)-1] = 0; //be happy ;) + return pname; + } +#endif + + bool set_module_name_and_folder(const std::string& path_to_process_) + { + std::string path_to_process = path_to_process_; +#ifdef _WIN32 + path_to_process = get_current_module_path(); +#endif + std::string::size_type a = path_to_process.rfind( '\\' ); + if(a == std::string::npos ) + { + a = path_to_process.rfind( '/' ); + } + if ( a != std::string::npos ) + { + get_current_module_name() = path_to_process.substr(a+1, path_to_process.size()); + get_current_module_folder() = path_to_process.substr(0, a); + return true; + }else + return false; + + } + + //---------------------------------------------------------------------------- + bool trim_left(std::string& str) + { + for(std::string::iterator it = str.begin(); it!= str.end() && isspace(static_cast<unsigned char>(*it));) + str.erase(str.begin()); + + return true; + } + //---------------------------------------------------------------------------- + bool trim_right(std::string& str) + { + + for(std::string::reverse_iterator it = str.rbegin(); it!= str.rend() && isspace(static_cast<unsigned char>(*it));) + str.erase( --((it++).base())); + + return true; + } + //---------------------------------------------------------------------------- + std::string pad_string(std::string s, size_t n, char c, bool prepend) + { + if (s.size() < n) + { + if (prepend) + s = std::string(n - s.size(), c) + s; + else + s.append(n - s.size(), c); + } + return s; + } + + std::string get_extension(const std::string& str) + { + std::string res; + std::string::size_type pos = str.rfind('.'); + if(std::string::npos == pos) + return res; + + res = str.substr(pos+1, str.size()-pos); + return res; + } + //---------------------------------------------------------------------------- + std::string cut_off_extension(const std::string& str) + { + std::string res; + std::string::size_type pos = str.rfind('.'); + if(std::string::npos == pos) + return str; + + res = str.substr(0, pos); + return res; + } + //---------------------------------------------------------------------------- +#ifdef _WIN32 + std::wstring utf8_to_utf16(const std::string& str) + { + if (str.empty()) + return {}; + int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0); + if (wstr_size == 0) + { + throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); + } + std::wstring wstr(wstr_size, wchar_t{}); + if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size)) + { + throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); + } + return wstr; + } + std::string utf16_to_utf8(const std::wstring& wstr) + { + if (wstr.empty()) + return {}; + int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL); + if (str_size == 0) + { + throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); + } + std::string str(str_size, char{}); + if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL)) + { + throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); + } + return str; + } +#endif } } diff --git a/contrib/epee/src/tiny_ini.cpp b/contrib/epee/src/tiny_ini.cpp new file mode 100644 index 000000000..577ebf7c6 --- /dev/null +++ b/contrib/epee/src/tiny_ini.cpp @@ -0,0 +1,46 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of the Andrey N. Sabelnikov 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 OWNER 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 "string_tools.h" +#include <boost/regex.hpp> + +namespace epee +{ +namespace tiny_ini +{ + bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res) + { + std::string expr_str = std::string() + "^("+ param_name +") *=(.*?)$"; + const boost::regex match_ini_entry( expr_str, boost::regex::icase | boost::regex::normal); + boost::smatch result; + if(!boost::regex_search(ini_entry, result, match_ini_entry, boost::match_default)) + return false; + res = result[2]; + string_tools::trim(res); + return true; + } +} +} diff --git a/contrib/gitian/README.md b/contrib/gitian/README.md index e2e1d0b94..0a40d4608 100644 --- a/contrib/gitian/README.md +++ b/contrib/gitian/README.md @@ -36,6 +36,10 @@ This guide explains how to set up the environment, and how to start the builds. You need to create a new user called `gitianuser` and be logged in as that user. The user needs `sudo` access. +```bash +sudo adduser gitianuser +sudo usermod -aG sudo gitianuser +``` LXC --- @@ -83,7 +87,7 @@ Docker Prepare for building with docker: ```bash -sudo apt-get install git make curl docker.io +sudo bash -c 'apt-get update && apt-get upgrade -y && apt-get install git curl docker.io' ``` Consider adding `gitianuser` to the `docker` group after reading about [the security implications](https://docs.docker.com/v17.09/engine/installation/linux/linux-postinstall/): @@ -96,13 +100,12 @@ sudo usermod -aG docker gitianuser Optionally add yourself to the docker group. Note that this will give docker root access to your system. ```bash -sudo usermod -aG docker gitianuser +sudo usermod -aG docker $USER ``` Manual Building ------------------- -The instructions below use the automated script [gitian-build.py](gitian-build.py) which only works in Ubuntu. ======= The script automatically installs some packages with apt. If you are not running it on a debian-like system, pass `--no-apt` along with the other arguments to it. It calls all available .yml descriptors, which in turn pass the build configurations for different platforms to gitian. @@ -122,17 +125,23 @@ cp monero/contrib/gitian/gitian-build.py . ### Setup the required environment -Setup for LXC: +Common setup part: ```bash -GH_USER=fluffypony -VERSION=v0.17.0.0 +su - gitianuser -./gitian-build.py --setup $GH_USER $VERSION +GH_USER=YOUR_GITHUB_USER_NAME +VERSION=v0.17.2.0 ``` Where `GH_USER` is your Github user name and `VERSION` is the version tag you want to build. +Setup for LXC: + +```bash +./gitian-build.py --setup $GH_USER $VERSION +``` + Setup for docker: ```bash @@ -145,8 +154,10 @@ fork the [gitian.sigs repository](https://github.com/monero-project/gitian.sigs) or pass the signed assert file back to your build machine. ```bash -git clone git@github.com:monero-project/gitian.sigs.git -git remote add $GH_USER git@github.com:$GH_USER/gitian.sigs.git +git clone https://github.com/monero-project/gitian.sigs/ +pushd gitian.sigs +git remote add $GH_USER https://github.com/$GH_USER/gitian.sigs +popd ``` Build the binaries @@ -154,13 +165,26 @@ Build the binaries **Note:** if you intend to build MacOS binaries, please follow [these instructions](https://github.com/bitcoin-core/docs/blob/master/gitian-building/gitian-building-mac-os-sdk.md) to get the required SDK. +Currently working MacOS solution: + +```bash +curl -O https://bitcoincore.org/depends-sources/sdks/MacOSX10.11.sdk.tar.gz +mv MacOSX10.11.sdk.tar.gz builder/inputs +``` + To build the most recent tag (pass in `--docker` if using docker): ```bash ./gitian-build.py --detach-sign --no-commit --build $GH_USER $VERSION ``` -To speed up the build, use `-j 5 --memory 5000` as the first arguments, where `5` is the number of CPU's you allocated to the VM plus one, and 5000 is a little bit less than then the MB's of RAM you allocated. If there is memory corruption on your machine, try to tweak these values. +To speed up the build, use `-j 5 --memory 10000` as the first arguments, where `5` is the number of CPU's you allocated to the VM plus one, and 10000 is a little bit less than then the MB's of RAM you allocated. If there is memory corruption on your machine, try to tweak these values. A good rule of thumb is, that Monero currently needs about 2 GB of RAM per core. + +A full example for `docker` would look like the following: + +```bash +./gitian-build.py -j 5 --memory 10000 --docker --detach-sign --no-commit --build $GH_USER $VERSION +``` If all went well, this produces a number of (uncommitted) `.assert` files in the gitian.sigs directory. @@ -171,6 +195,22 @@ Take a look in the assert files and note the SHA256 checksums listed there. You should verify that the checksum that is listed matches each of the binaries you actually built. This may be done on Linux using the `sha256sum` command or on MacOS using `shasum --algorithm 256` for example. +An example script to verify the checksums would be: + +```bash +pushd out/${VERSION} + +for ASSERT in ../../sigs/${VERSION}-*/*/*.assert; do + if ! sha256sum --ignore-missing -c "${ASSERT}" ; then + echo "FAILED for ${ASSERT} ! Please inspect manually." + fi +done + +popd +``` + +Don't ignore the incorrect formatting of the found assert files. These files you'll have to compare manually (currently OSX and FreeBSD). + You can also look in the [gitian.sigs](https://github.com/monero-project/gitian.sigs/) repo and / or [getmonero.org release checksums](https://web.getmonero.org/downloads/hashes.txt) to see if others got the same checksum for the same version tag. If there is ever a mismatch -- **STOP! Something is wrong**. Contact others on IRC / github to figure out what is going on. @@ -181,14 +221,7 @@ Signing assert files If you chose to do detached signing using `--detach-sign` above (recommended), you need to copy these uncommitted changes to your host machine, then sign them using your gpg key like so: ```bash -GH_USER=fluffypony -VERSION=v0.17.0.0 - -gpg --detach-sign ${VERSION}-linux/${GH_USER}/monero-linux-*-build.assert -gpg --detach-sign ${VERSION}-win/${GH_USER}/monero-win-*-build.assert -gpg --detach-sign ${VERSION}-osx/${GH_USER}/monero-osx-*-build.assert -gpg --detach-sign ${VERSION}-android/${GH_USER}/monero-android-*-build.assert -gpg --detach-sign ${VERSION}-freebsd/${GH_USER}/monero-freebsd-*-build.assert +for ASSERT in sigs/${VERSION}-*/*/*.assert; do gpg --detach-sign ${ASSERT}; done ``` This will create a `.sig` file for each `.assert` file above (2 files for each platform). @@ -201,6 +234,7 @@ Make a pull request (both the `.assert` and `.assert.sig` files) to the [monero-project/gitian.sigs](https://github.com/monero-project/gitian.sigs/) repository: ```bash +cd gitian.sigs git checkout -b $VERSION # add your assert and sig files... git commit -S -a -m "Add $GH_USER $VERSION" diff --git a/docs/COMPILING_DEBUGGING_TESTING.md b/docs/COMPILING_DEBUGGING_TESTING.md new file mode 100644 index 000000000..f5c202303 --- /dev/null +++ b/docs/COMPILING_DEBUGGING_TESTING.md @@ -0,0 +1,86 @@ +# Compiling, debugging and testing efficiently + +This document describes ways of compiling, debugging and testing efficiently for various use cases. +The intented audience are developers, who want to leverage newly added tricks to Monero via `CMake`. The document will lower the entry point for these developers. +Before reading this document, please consult section "Build instructions" in the main README.md. +Some information from README.md will be repeated here, but the aim is to go beyond it. + +## Basic compilation + +Monero can be compiled via the main `Makefile`, using one of several targets listed there. +The targets are actually presets for `CMake` calls with various options, plus `make` commands for building or in some cases `make test` for testing. +It is possible to extract these `CMake` calls and modify them for your specific needs. For example, a minimal external cmake command to compile Monero, executed from within a newly created build directory could look like: + +`cmake -S "$DIR_SRC" -DCMAKE_BUILD_TYPE=Release && make` + +where the variable `DIR_SRC` is expected to store the path to the Monero source code. + +## Use cases + +### Test Driven Development (TDD) - shared libraries for release builds + +Building shared libraries spares a lot of disk space and linkage time. By default only the debug builds produce shared libraries. If you'd like to produce dynamic libraries for the release build for the same reasons as it's being done for the debug version, then you need to add the `BUILD_SHARED_LIBS=ON` flag to the `CMake` call, like the following: + +`cmake -S "$DIR_SRC" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON && make` + +A perfect use case for the above call is following the Test Driven Development (TDD) principles. In a nutshell, you'd first write a couple of tests, which describe the (new) requirements of the class/method that you're about to write or modify. The tests will typically compile for quite a long time, so ideally write them once. After you're done with the tests, the only thing left to do is to keep modifying the implementation for as long as the tests are failing. If the implementation is contained properly within a .cpp file, then the only time cost to be paid will be compiling the single source file and generating the implementation's shared library. The test itself will not have to be touched and will pick up the new version of the implementation (via the shared library) upon the next execution of the test. + +### Project generation for IDEs + +CMake allows to generate project files for many IDEs. The list of supported project files can be obtained by writing in the console: + +`cmake -G` + +For instance, in order to generate Makefiles and project files for the Code::Blocks IDE, this part of the call would look like the following: + +`cmake -G "CodeBlocks - Unix Makefiles" (...)` + +The additional artifact of the above call is the `monero.cbp` Code::Blocks project file in the build directory. + +### Debugging in Code::Blocks (CB) + +First prepare the build directory for debugging using the following example command, assuming, that the path to the source dir is being held in the DIR_SRC variable, and using 2 cores: + +`cmake -S "$DIR_SRC" -G "CodeBlocks - Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON && make -j 2` + +After a successful build, open the `monero.cbp` with CB. From the CB's menu bar select the target, that you want debug. Assuming these are unit tests: + +`Build -> Select target -> Select target -> unit_tests` + +In order to lower the turnaround times, we will run a specific portion of code of interest, without having to go through all the time costly initialization and execution of unrelated parts. For this we'll use GTest's capabilities of test filtering. From the build directory run the following command to learn all the registered tests: + +`tests/unit_tests/unit_tests --gtest_list_tests` + +For example, if you're only interested in logging, you'd find in the list the label `logging.` and its subtests. To execute all the logging tests, you'd write in the console: + +`tests/unit_tests/unit_tests --gtest_filter="logging.*"` + +This parameter is what we need to transfer to CB, in order to reflect the same behaviour in the CB's debugger. From the main menu select: + +`Project -> Set program's arguments...` + +Then in the `Program's arguments` textbox you'd write in this case: + +`--gtest_filter="logging.*"` + +Verify if the expected UTs are being properly executed with `F9` or select: + +`Build -> Build and run` + +If everything looks fine, then after setting some breakpoints of your choice, the target is ready for debugging in CB via: + +`Debug -> Start/Continue` + +## To be done (and merged): +### Multihost parallel compilation +https://github.com/monero-project/monero/pull/7160 + +### Faster core_tests with caching +https://github.com/monero-project/monero/pull/5821 + +### Precompiled headers +https://github.com/monero-project/monero/pull/7216 + +### Unity builds +https://github.com/monero-project/monero/pull/7217 + diff --git a/external/db_drivers/liblmdb/mdb.c b/external/db_drivers/liblmdb/mdb.c index 96c741f66..6314d5775 100644 --- a/external/db_drivers/liblmdb/mdb.c +++ b/external/db_drivers/liblmdb/mdb.c @@ -4882,9 +4882,6 @@ mdb_env_open2(MDB_env *env, int prev) #endif env->me_maxpg = env->me_mapsize / env->me_psize; - if (env->me_txns) - env->me_txns->mti_txnid = meta.mm_txnid; - #if MDB_DEBUG { MDB_meta *meta = mdb_env_pick_meta(env); @@ -4984,6 +4981,9 @@ static int ESECT mdb_env_share_locks(MDB_env *env, int *excl) { int rc = 0; + MDB_meta *meta = mdb_env_pick_meta(env); + + env->me_txns->mti_txnid = meta->mm_txnid; #ifdef _WIN32 { diff --git a/external/easylogging++/CMakeLists.txt b/external/easylogging++/CMakeLists.txt index 35fb86552..fcda54547 100644 --- a/external/easylogging++/CMakeLists.txt +++ b/external/easylogging++/CMakeLists.txt @@ -31,6 +31,7 @@ cmake_minimum_required(VERSION 2.8.7) project(easylogging CXX) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +monero_enable_coverage() find_package(Threads) find_package(Backtrace) diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index 3e4532d4e..b0c4a25d8 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -32,6 +32,7 @@ #include <boost/algorithm/string.hpp> #include "wipeable_string.h" #include "string_tools.h" +#include "string_tools_lexical.h" #include "serialization/string.h" #include "cryptonote_format_utils.h" #include "cryptonote_config.h" diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index afc81f552..685968c08 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -2310,7 +2310,7 @@ skip: const uint32_t peer_stripe = tools::get_pruning_stripe(context.m_pruning_seed); const uint32_t first_stripe = tools::get_pruning_stripe(span.first, context.m_remote_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES); const uint32_t last_stripe = tools::get_pruning_stripe(span.first + span.second - 1, context.m_remote_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES); - if ((((first_stripe && peer_stripe != first_stripe) || (last_stripe && peer_stripe != last_stripe)) && !m_sync_pruned_blocks) || (m_sync_pruned_blocks && req.prune)) + if (((first_stripe && peer_stripe != first_stripe) || (last_stripe && peer_stripe != last_stripe)) && !m_sync_pruned_blocks) { MDEBUG(context << "We need full data, but the peer does not have it, dropping peer"); return false; diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index abca614cc..14233bf29 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -31,6 +31,7 @@ #include "net/parse.h" #include "daemon/command_parser_executor.h" #include <boost/filesystem.hpp> +#include <boost/algorithm/string/predicate.hpp> #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "daemon" diff --git a/src/device_trezor/device_trezor.cpp b/src/device_trezor/device_trezor.cpp index 7c3e8785d..c2070b0d1 100644 --- a/src/device_trezor/device_trezor.cpp +++ b/src/device_trezor/device_trezor.cpp @@ -28,6 +28,8 @@ // #include "device_trezor.hpp" +#include <boost/filesystem.hpp> +#include <boost/algorithm/string/predicate.hpp> namespace hw { namespace trezor { diff --git a/src/device_trezor/device_trezor_base.cpp b/src/device_trezor/device_trezor_base.cpp index 70dc7f539..5f21ecd49 100644 --- a/src/device_trezor/device_trezor_base.cpp +++ b/src/device_trezor/device_trezor_base.cpp @@ -31,6 +31,7 @@ #include "memwipe.h" #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/predicate.hpp> #include <boost/regex.hpp> namespace hw { diff --git a/src/device_trezor/trezor/transport.cpp b/src/device_trezor/trezor/transport.cpp index a56090de0..be95868d0 100644 --- a/src/device_trezor/trezor/transport.cpp +++ b/src/device_trezor/trezor/transport.cpp @@ -38,6 +38,7 @@ #include <boost/asio/ip/udp.hpp> #include <boost/date_time/posix_time/posix_time_types.hpp> #include <boost/format.hpp> +#include <boost/algorithm/string/predicate.hpp> #include "common/apply_permutation.h" #include "transport.hpp" #include "messages/messages-common.pb.h" diff --git a/src/net/i2p_address.cpp b/src/net/i2p_address.cpp index 6c03b3808..ada4eb0d3 100644 --- a/src/net/i2p_address.cpp +++ b/src/net/i2p_address.cpp @@ -38,7 +38,7 @@ #include "net/error.h" #include "serialization/keyvalue_serialization.h" #include "storages/portable_storage.h" -#include "string_tools.h" +#include "string_tools_lexical.h" namespace net { diff --git a/src/net/parse.cpp b/src/net/parse.cpp index 8a98e941a..298576ba4 100644 --- a/src/net/parse.cpp +++ b/src/net/parse.cpp @@ -31,6 +31,7 @@ #include "net/tor_address.h" #include "net/i2p_address.h" #include "string_tools.h" +#include "string_tools_lexical.h" namespace net { diff --git a/src/net/socks_connect.cpp b/src/net/socks_connect.cpp index 9db9d4483..c797a24d4 100644 --- a/src/net/socks_connect.cpp +++ b/src/net/socks_connect.cpp @@ -38,6 +38,7 @@ #include "net/net_utils_base.h" #include "net/socks.h" #include "string_tools.h" +#include "string_tools_lexical.h" namespace net { diff --git a/src/net/tor_address.cpp b/src/net/tor_address.cpp index 4414861e7..a04dcb042 100644 --- a/src/net/tor_address.cpp +++ b/src/net/tor_address.cpp @@ -38,7 +38,7 @@ #include "net/error.h" #include "serialization/keyvalue_serialization.h" #include "storages/portable_storage.h" -#include "string_tools.h" +#include "string_tools_lexical.h" namespace net { diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index e1d6d1e10..a0b8438b2 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -682,11 +682,13 @@ namespace nodetool full_addrs.insert("212.83.175.67:28080"); full_addrs.insert("212.83.172.165:28080"); full_addrs.insert("192.110.160.146:28080"); + full_addrs.insert("88.99.173.38:28080"); } else if (m_nettype == cryptonote::STAGENET) { full_addrs.insert("162.210.173.150:38080"); full_addrs.insert("192.110.160.146:38080"); + full_addrs.insert("88.99.173.38:38080"); } else if (m_nettype == cryptonote::FAKECHAIN) { @@ -701,6 +703,7 @@ namespace nodetool full_addrs.insert("209.250.243.248:18080"); full_addrs.insert("104.238.221.81:18080"); full_addrs.insert("66.85.74.134:18080"); + full_addrs.insert("88.99.173.38:18080"); } return full_addrs; } diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index da6501183..e859a4693 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -608,9 +608,14 @@ void simple_wallet::handle_transfer_exception(const std::exception_ptr &e, bool fail_msg_writer() << e.what(); warn_of_possible_attack = false; } + catch (const tools::error::zero_amount&) + { + fail_msg_writer() << sw::tr("destination amount is zero"); + warn_of_possible_attack = false; + } catch (const tools::error::zero_destination&) { - fail_msg_writer() << sw::tr("one of destinations is zero"); + fail_msg_writer() << sw::tr("transaction has no destination"); warn_of_possible_attack = false; } catch (const tools::error::tx_too_big& e) @@ -5890,7 +5895,7 @@ bool simple_wallet::refresh_main(uint64_t start_height, enum ResetType reset, bo if (reset != ResetNone) { if (reset == ResetSoftKeepKI) - height_pre = m_wallet->hash_m_transfers(-1, transfer_hash_pre); + height_pre = m_wallet->hash_m_transfers(boost::none, transfer_hash_pre); m_wallet->rescan_blockchain(reset == ResetHard, false, reset == ResetSoftKeepKI); } diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 5d9eb7a14..adff042ad 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1565,8 +1565,10 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri setStatusError(writer.str()); } catch (const tools::error::tx_sum_overflow& e) { setStatusError(e.what()); + } catch (const tools::error::zero_amount&) { + setStatusError(tr("destination amount is zero")); } catch (const tools::error::zero_destination&) { - setStatusError(tr("one of destinations is zero")); + setStatusError(tr("transaction has no destination")); } catch (const tools::error::tx_too_big& e) { setStatusError(tr("failed to find a suitable way to split transactions")); } catch (const tools::error::transfer_error& e) { diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 0af896c76..0b310111e 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -37,6 +37,7 @@ #include <boost/algorithm/string/trim.hpp> #include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/join.hpp> +#include <boost/algorithm/string/predicate.hpp> #include <boost/asio/ip/address.hpp> #include <boost/range/adaptor/transformed.hpp> #include <boost/preprocessor/stringize.hpp> @@ -8760,7 +8761,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent // throw if total amount overflows uint64_t for(auto& dt: dsts) { - THROW_WALLET_EXCEPTION_IF(0 == dt.amount, error::zero_destination); + THROW_WALLET_EXCEPTION_IF(0 == dt.amount, error::zero_amount); needed_money += dt.amount; LOG_PRINT_L2("transfer: adding " << print_money(dt.amount) << ", for a total of " << print_money (needed_money)); THROW_WALLET_EXCEPTION_IF(needed_money < dt.amount, error::tx_sum_overflow, dsts, fee, m_nettype); @@ -8919,7 +8920,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry // throw if total amount overflows uint64_t for(auto& dt: dsts) { - THROW_WALLET_EXCEPTION_IF(0 == dt.amount, error::zero_destination); + THROW_WALLET_EXCEPTION_IF(0 == dt.amount, error::zero_amount); needed_money += dt.amount; LOG_PRINT_L2("transfer: adding " << print_money(dt.amount) << ", for a total of " << print_money (needed_money)); THROW_WALLET_EXCEPTION_IF(needed_money < dt.amount, error::tx_sum_overflow, dsts, fee, m_nettype); @@ -9892,14 +9893,14 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp needed_money = 0; for(auto& dt: dsts) { - THROW_WALLET_EXCEPTION_IF(0 == dt.amount, error::zero_destination); + THROW_WALLET_EXCEPTION_IF(0 == dt.amount, error::zero_amount); needed_money += dt.amount; LOG_PRINT_L2("transfer: adding " << print_money(dt.amount) << ", for a total of " << print_money (needed_money)); THROW_WALLET_EXCEPTION_IF(needed_money < dt.amount, error::tx_sum_overflow, dsts, 0, m_nettype); } // throw if attempting a transaction with no money - THROW_WALLET_EXCEPTION_IF(needed_money == 0, error::zero_destination); + THROW_WALLET_EXCEPTION_IF(needed_money == 0, error::zero_amount); std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> unlocked_balance_per_subaddr = unlocked_balance_per_subaddress(subaddr_account, false); std::map<uint32_t, uint64_t> balance_per_subaddr = balance_per_subaddress(subaddr_account, false); @@ -12227,7 +12228,7 @@ uint64_t wallet2::get_approximate_blockchain_height() const // Calculated blockchain height uint64_t approx_blockchain_height = fork_block + (time(NULL) - fork_time)/seconds_per_block; // testnet got some huge rollbacks, so the estimation is way off - static const uint64_t approximate_testnet_rolled_back_blocks = 303967; + static const uint64_t approximate_testnet_rolled_back_blocks = 342100; if (m_nettype == TESTNET && approx_blockchain_height > approximate_testnet_rolled_back_blocks) approx_blockchain_height -= approximate_testnet_rolled_back_blocks; LOG_PRINT_L2("Calculated blockchain height: " << approx_blockchain_height); @@ -14188,15 +14189,15 @@ void wallet2::hash_m_transfer(const transfer_details & transfer, crypto::hash &h KECCAK_CTX state; keccak_init(&state); keccak_update(&state, (const uint8_t *) transfer.m_txid.data, sizeof(transfer.m_txid.data)); - keccak_update(&state, (const uint8_t *) transfer.m_internal_output_index, sizeof(transfer.m_internal_output_index)); - keccak_update(&state, (const uint8_t *) transfer.m_global_output_index, sizeof(transfer.m_global_output_index)); - keccak_update(&state, (const uint8_t *) transfer.m_amount, sizeof(transfer.m_amount)); + keccak_update(&state, (const uint8_t *) &transfer.m_internal_output_index, sizeof(transfer.m_internal_output_index)); + keccak_update(&state, (const uint8_t *) &transfer.m_global_output_index, sizeof(transfer.m_global_output_index)); + keccak_update(&state, (const uint8_t *) &transfer.m_amount, sizeof(transfer.m_amount)); keccak_finish(&state, (uint8_t *) hash.data); } //---------------------------------------------------------------------------------------------------- -uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const +uint64_t wallet2::hash_m_transfers(boost::optional<uint64_t> transfer_height, crypto::hash &hash) const { - CHECK_AND_ASSERT_THROW_MES(transfer_height > (int64_t)m_transfers.size(), "Hash height is greater than number of transfers"); + CHECK_AND_ASSERT_THROW_MES(!transfer_height || *transfer_height <= m_transfers.size(), "Hash height is greater than number of transfers"); KECCAK_CTX state; crypto::hash tmp_hash{}; @@ -14204,12 +14205,12 @@ uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash) keccak_init(&state); for(const transfer_details & transfer : m_transfers){ - if (transfer_height >= 0 && current_height >= (uint64_t)transfer_height){ + if (transfer_height && current_height >= *transfer_height){ break; } hash_m_transfer(transfer, tmp_hash); - keccak_update(&state, (const uint8_t *) transfer.m_block_height, sizeof(transfer.m_block_height)); + keccak_update(&state, (const uint8_t *) &transfer.m_block_height, sizeof(transfer.m_block_height)); keccak_update(&state, (const uint8_t *) tmp_hash.data, sizeof(tmp_hash.data)); current_height += 1; } @@ -14221,23 +14222,28 @@ uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash) void wallet2::finish_rescan_bc_keep_key_images(uint64_t transfer_height, const crypto::hash &hash) { // Compute hash of m_transfers, if differs there had to be BC reorg. - crypto::hash new_transfers_hash{}; - hash_m_transfers((int64_t) transfer_height, new_transfers_hash); + if (transfer_height <= m_transfers.size()) { + crypto::hash new_transfers_hash{}; + hash_m_transfers(transfer_height, new_transfers_hash); - if (new_transfers_hash != hash) - { - // Soft-Reset to avoid inconsistency in case of BC reorg. - clear_soft(false); // keep_key_images works only with soft reset. - THROW_WALLET_EXCEPTION_IF(true, error::wallet_internal_error, "Transfers changed during rescan, soft or hard rescan is needed"); - } + if (new_transfers_hash == hash) { + // Restore key images in m_transfers from m_key_images + for(auto it = m_key_images.begin(); it != m_key_images.end(); it++) + { + THROW_WALLET_EXCEPTION_IF(it->second >= m_transfers.size(), + error::wallet_internal_error, + "Key images cache contains illegal transfer offset"); + m_transfers[it->second].m_key_image = it->first; + m_transfers[it->second].m_key_image_known = true; + } - // Restore key images in m_transfers from m_key_images - for(auto it = m_key_images.begin(); it != m_key_images.end(); it++) - { - THROW_WALLET_EXCEPTION_IF(it->second >= m_transfers.size(), error::wallet_internal_error, "Key images cache contains illegal transfer offset"); - m_transfers[it->second].m_key_image = it->first; - m_transfers[it->second].m_key_image_known = true; + return; + } } + + // Soft-Reset to avoid inconsistency in case of BC reorg. + clear_soft(false); // keep_key_images works only with soft reset. + THROW_WALLET_EXCEPTION_IF(true, error::wallet_internal_error, "Transfers changed during rescan, soft or hard rescan is needed"); } //---------------------------------------------------------------------------------------------------- uint64_t wallet2::get_bytes_sent() const diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index e96a6b51c..facf9878d 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1547,7 +1547,7 @@ private: bool is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_height); void hash_m_transfer(const transfer_details & transfer, crypto::hash &hash) const; - uint64_t hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const; + uint64_t hash_m_transfers(boost::optional<uint64_t> transfer_height, crypto::hash &hash) const; void finish_rescan_bc_keep_key_images(uint64_t transfer_height, const crypto::hash &hash); void enable_dns(bool enable) { m_use_dns = enable; } void set_offline(bool offline = true); diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index 4a89ed81a..011780f43 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -83,6 +83,7 @@ namespace tools // tx_rejected // tx_sum_overflow // tx_too_big + // zero_amount // zero_destination // wallet_rpc_error * // daemon_busy @@ -750,10 +751,18 @@ namespace tools uint64_t m_tx_weight_limit; }; //---------------------------------------------------------------------------------------------------- + struct zero_amount: public transfer_error + { + explicit zero_amount(std::string&& loc) + : transfer_error(std::move(loc), "destination amount is zero") + { + } + }; + //---------------------------------------------------------------------------------------------------- struct zero_destination : public transfer_error { explicit zero_destination(std::string&& loc) - : transfer_error(std::move(loc), "destination amount is zero") + : transfer_error(std::move(loc), "transaction has no destination") { } }; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index b39a40b64..0b200ae60 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -822,7 +822,7 @@ namespace tools if (at_least_one_destination && dsts.empty()) { er.code = WALLET_RPC_ERROR_CODE_ZERO_DESTINATION; - er.message = "No destinations for this transfer"; + er.message = "Transaction has no destination"; return false; } @@ -3359,6 +3359,11 @@ namespace tools er.code = WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY; er.message = e.what(); } + catch (const tools::error::zero_amount& e) + { + er.code = WALLET_RPC_ERROR_CODE_ZERO_AMOUNT; + er.message = e.what(); + } catch (const tools::error::zero_destination& e) { er.code = WALLET_RPC_ERROR_CODE_ZERO_DESTINATION; diff --git a/src/wallet/wallet_rpc_server_error_codes.h b/src/wallet/wallet_rpc_server_error_codes.h index f7c5bb0e1..b991029a9 100644 --- a/src/wallet/wallet_rpc_server_error_codes.h +++ b/src/wallet/wallet_rpc_server_error_codes.h @@ -76,4 +76,5 @@ #define WALLET_RPC_ERROR_CODE_NON_DETERMINISTIC -43 #define WALLET_RPC_ERROR_CODE_INVALID_LOG_LEVEL -44 #define WALLET_RPC_ERROR_CODE_ATTRIBUTE_NOT_FOUND -45 +#define WALLET_RPC_ERROR_CODE_ZERO_AMOUNT -46 #define WALLET_RPC_ERROR_CODE_INVALID_SIGNATURE_TYPE -47 diff --git a/tests/functional_tests/make_test_signature.cc b/tests/functional_tests/make_test_signature.cc index 07cc3eea6..cb1723847 100644 --- a/tests/functional_tests/make_test_signature.cc +++ b/tests/functional_tests/make_test_signature.cc @@ -28,6 +28,7 @@ #include <stdio.h> #include "misc_language.h" +#include "misc_log_ex.h" #include "string_tools.h" #include "rpc/rpc_payment_signature.h" diff --git a/tests/unit_tests/get_xtype_from_string.cpp b/tests/unit_tests/get_xtype_from_string.cpp index 78bbe6657..17492ed19 100644 --- a/tests/unit_tests/get_xtype_from_string.cpp +++ b/tests/unit_tests/get_xtype_from_string.cpp @@ -31,6 +31,7 @@ #include "gtest/gtest.h" #include <string_tools.h> +#include <string_tools_lexical.h> using namespace epee::string_tools; diff --git a/tests/unit_tests/node_server.cpp b/tests/unit_tests/node_server.cpp index 775feace8..2c80acda5 100644 --- a/tests/unit_tests/node_server.cpp +++ b/tests/unit_tests/node_server.cpp @@ -449,7 +449,6 @@ TEST(cryptonote_protocol_handler, race_condition) }; struct net_node_t: commands_handler_t, p2p_endpoint_t { using span_t = epee::span<const uint8_t>; - using string_t = std::string; using zone_t = epee::net_utils::zone; using uuid_t = boost::uuids::uuid; using relay_t = cryptonote::relay_method; @@ -462,12 +461,9 @@ TEST(cryptonote_protocol_handler, race_condition) using subnets = std::map<epee::net_utils::ipv4_network_subnet, time_t>; using hosts = std::map<std::string, time_t>; }; - struct slice { - using bytes = epee::byte_slice; - }; shared_state_ptr shared_state; core_protocol_ptr core_protocol; - virtual int invoke(int command, const span_t in, slice::bytes &out, context_t &context) override { + virtual int invoke(int command, const span_t in, epee::byte_stream &out, context_t &context) override { if (core_protocol) { if (command == messages::handshake::ID) { return epee::net_utils::buff_to_t_adapter<void, typename messages::handshake::request, typename messages::handshake::response>( @@ -491,7 +487,7 @@ TEST(cryptonote_protocol_handler, race_condition) virtual int notify(int command, const span_t in, context_t &context) override { if (core_protocol) { bool handled; - slice::bytes out; + epee::byte_stream out; return core_protocol->handle_invoke_map(true, command, in, out, context, handled); } else @@ -527,22 +523,16 @@ TEST(cryptonote_protocol_handler, race_condition) else return {}; } - virtual bool invoke_command_to_peer(int command, const span_t in, string_t& out, const contexts::basic& context) override { - if (shared_state) - return shared_state->invoke(command, in, out, context.m_connection_id); - else - return {}; - } - virtual bool invoke_notify_to_peer(int command, const span_t in, const contexts::basic& context) override { + virtual bool invoke_notify_to_peer(int command, epee::levin::message_writer in, const contexts::basic& context) override { if (shared_state) - return shared_state->notify(command, in, context.m_connection_id); + return shared_state->send(in.finalize_notify(command), context.m_connection_id); else return {}; } - virtual bool relay_notify_to_list(int command, const span_t in, connections_t connections) override { + virtual bool relay_notify_to_list(int command, epee::levin::message_writer in, connections_t connections) override { if (shared_state) { for (auto &e: connections) - shared_state->notify(command, in, e.second); + shared_state->send(in.finalize_notify(command), e.second); } return {}; } diff --git a/utils/build_scripts/android32.Dockerfile b/utils/build_scripts/android32.Dockerfile index a2d0edbb3..c0931ce05 100644 --- a/utils/build_scripts/android32.Dockerfile +++ b/utils/build_scripts/android32.Dockerfile @@ -44,7 +44,7 @@ ARG BOOST_VERSION=1_68_0 ARG BOOST_VERSION_DOT=1.68.0 ARG BOOST_HASH=7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7 RUN set -ex \ - && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \ + && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \ && echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \ && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \ && rm -f boost_${BOOST_VERSION}.tar.bz2 \ diff --git a/utils/build_scripts/android64.Dockerfile b/utils/build_scripts/android64.Dockerfile index eca2d4da1..3a62da464 100644 --- a/utils/build_scripts/android64.Dockerfile +++ b/utils/build_scripts/android64.Dockerfile @@ -44,7 +44,7 @@ ARG BOOST_VERSION=1_68_0 ARG BOOST_VERSION_DOT=1.68.0 ARG BOOST_HASH=7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7 RUN set -ex \ - && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \ + && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \ && echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \ && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \ && rm -f boost_${BOOST_VERSION}.tar.bz2 \ diff --git a/utils/gpg_keys/mj-xmr.asc b/utils/gpg_keys/mj-xmr.asc new file mode 100644 index 000000000..e02d3e511 --- /dev/null +++ b/utils/gpg_keys/mj-xmr.asc @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBGBxrvMBEADD7dDjSfrtiuQJEuMMMGYt3wGQ1iJdiLWe4THJDbtPDCLdBxh4 +fpYGMVkUYT8LJFkf41JD/hAIKMNQHdw7qmZcfN9F/9U+jInHRYBM1dbA/mHs8Jhi +YEGrD+v7c5fEuFXANW7z2uPjszw67tv3K5z8pFkt6K0pCgnxSKBu10WYkV0fvnxz +e3naXAnWQQ/qeGP2xT2F3S+bn5GvCTPw1pI1HAaFcYVD+XZpNdKQHnHMWlDrQ0qe +zymqrknjMmtD70Z7gEOogNxjd2QXUsQDq7XwxfHnhVZHHm98O95gh4Uw2Pve/TMI +f0ItA+MYp+hDqN7wmq3TjNSVI9L02m/RgpO7cxpEgQ9QFYJo3dHC8cP7x/uqH3vI +usYjOJtzq3UZWn4hnHRviEMYSDPtfFmO5CRElueVsRTiG0h7cyQYZ8HrEC9qDyR8 +vn0shqrUbcwsplyhwtpoyuJKcK/mFnmETUQ7ZF5NqgIlOaU7Du8WBt84YrDKRe5q +TKMTtDEf4PrejqhYvb7GNOK3D/LJ/dZTJIdETZ2rRCCftgKjTLJr9fRSrQnxw5NQ +8fnnK/O8JNpRvnDvR2HlmI8w/sgEDT99U4XgSi9BIUrM8HYkNykENXsk2BvEIGEN +txXwZKDJmxK787+y4WX2JfbhFGPNCXxuwrXUqNhKy4Qit140Z7WH6UIvSwARAQAB +tEdtai14bXIgKEJlY2F1c2UgV29ybGQgZG9taW5hdGlvbiBzaG91bGQgYmUgZnVu +LikgPG1qeG1yQHByb3Rvbm1haWwuY29tPokCVAQTAQoAPhYhBLMwkesQonK53VcC ++sEBv5QJNFHgBQJgca7zAhsDBQkJZgGABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheA +AAoJEMEBv5QJNFHgPykP/0YOJYU0ap8BpAtG9Dfv46UPy77XMw2ag2AJ0MYPrqy6 +omjha15qLHeXxCr3CJNYa4EEvX0hahSGn4k3VmcDHVYYpD4f/RZfu8fBpk0xQtsv +wF7zuAn0KSeg7maopdWfcPn02uTOm2crzTMMm5scXZ/YmMviUFPsgpyIkM5oCre6 +/RhIK953OUpgc/JKIlhpABA7KBTWUbc18BGHHdcPntVKrIxrIvzchVwI2P8KDQki +NS33Fc9EoOlDuzbTkQldZJrsEsMZWKfzoNNlZsLtroaS6SlqQNllYjSEJx7ccjEU ++zvMGLXhxqL7XTFO1HdvacWwPsSPR8MXrwUFcKrDDzC57rHNPrHncPY1JwEkN0Aj +V3VzTM+5QPvo6QQ+aNISxy9Hs470SpLDmmBl//Dn4qbFWSqAQ3qSD7S34MgW0FeC +4L1/uTsDokkx+ZIf7WQUl2p4vi8/puFw2y3VLs4WGaUYko1gjhoFIDs3gP7YIeE9 +Lp+6/+RxMkuSGTrHM9rcpeClp3jEN/I7n/epKpJOSgroN+/RdbOOnVECC7+kWkM0 +U9fPi+O3fRIlaR+Q8NWkokgkbtw6gYV3bKnW78AnF5INs3rrtOH1WtGSp7ghKP4p +7GE5cCIbUsB3dT6Ifo5tAi3faYFyhUZ2GsYNM0fsge10OwtPs+4YbSuurWUyIwuW +uQINBGBxrvMBEACxiDPPivT0Tv4DWtkGZ7tHRF0IT9nSZuL5F+qMX4D3hef3RfVY +4hxAQe2elvMU4PV/3neaRyiWSd4/Q8DnWrGQGvn3gxx8AHZTQwv/01Ae0InyNI9t +pzpBCMvOY73dba1JRklEMMyJPAUrdvmyRTEuZEIAxoVlaKKSAr4oeaENGLwWxB4o +NsAPxKNWw8drGQfJixMA+IeqeMzRjo6o5gJzrlaTb3+S78a1rD0pMmY7s6j3LqmF +kd0L/JlGrs+ILCxXjddg6FRL/qUtvOZX+jdogb1hKvPFCMMc1BfUdq9WbrCpoj54 +OhBnO+yCHi2faUi0YP8Fumu6RTCDN+MK0nEji+peaJApHf15ZVd9DAX9NzRl/iLb +sMjf4KBE2BI6FaUpdzkTbH6F713O2ZGWGEROBTjKucO3OkjGfHKf9rxdGRt37I/z +b59xRzSn91Vz1nEXCmDSO/iPAGZ3bQKh+zSGwjwJsZrBRCvS34AhGaEs8un6nd9M +FoMClpyjmm3W6WUZnELmcdlKhY2xbi5Yub21+mrjjjS6BuFpSYIC1xKJrCdpXtAm +i8x5mcKbY24uRuqsY9pQrDHVXK/Pwj6+k9rGwbe5P6VkbZOpJ2pWSL68EoxIo1zp +bv6moIJtxipydUOD2k76W0oGplexoxtW5f1WKcb3ykJRRrdPQxtPaPK14QARAQAB +iQI8BBgBCgAmFiEEszCR6xCicrndVwL6wQG/lAk0UeAFAmBxrvMCGwwFCQlmAYAA +CgkQwQG/lAk0UeClZhAAwQa+XO2GhCfZgrYOOSR5h2iib5k8OWiTsV68/DHOMsFJ +1WVDsqjlNEOhPPg0CbH4FMHJOndcsjJb+Rs6Y35YsgTmQl1SHlJXZinV1AJ+IaW/ +Esx+qOpoGUzCzCrjGpwSYHxGSQ52WpLvTaHbosH3x2XXTZ2znOdwTlFB/36Yco3c +ROWVLT/FhjugxTP0KddZR9Lu7ThK7txQhTQp5oBwWgpv0YAPaRPA+BpvrtzI7xSx +2AOMtr7jiGAu0yFL5WestRy37UmunxS8Rd8PGILcfFBIvfqNTMwU55SW1nS9XbRh +bUb/iil+Ly6lVsGAPW7iUgEUO7HtsPxeF+Bk/Hh+ZCHglQrGpzGcPmgbG3IiMF9H +nISbh6sFrkDXjyLNP1zl6wg0cTyk12OcYo0nX4jp1CY3Oztd3rVdcMT8Qot4JSHj +rDx+b3FTErVCnitEeALuBt/JSNH0VMcgOmFen9goJRVXcW/Dnsb+7QWXooj3aC++ +O6eghDN1YyJClQqLxvVThr7pdlMiWgWzHLmRkI2o84r14qOC15yTh7qr3Y5LOMPN +px9K2f9f2l6KJ0w7vgKwa6pYiVf1AAw2Ym98LAJn+6v9+nRx9mSq9Nw+M5eo9DXW +gclwPV1SSWUls8jjOmluI6/j8TE9JMBy5UKX1g6TOKJWW6wXcOUfzNVtG1oRNPA= +=egkb +-----END PGP PUBLIC KEY BLOCK----- |