mirror of
https://github.com/XRPLF/rippled.git
synced 2026-02-03 13:35:25 +00:00
Compare commits
22 Commits
copilot/ad
...
pratik/Fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6334be1ff0 | ||
|
|
a9c3bb84ba | ||
|
|
ca99e40290 | ||
|
|
7612c1af0c | ||
|
|
67e40be1ab | ||
|
|
0132174a7b | ||
|
|
8773cc4bbf | ||
|
|
dabdadfff5 | ||
|
|
bfe2cd7893 | ||
|
|
0584c20f36 | ||
|
|
3ced0b27b7 | ||
|
|
f83b27f7dd | ||
|
|
cdb41b5376 | ||
|
|
f223c89a9f | ||
|
|
efe07c09f3 | ||
|
|
79cde8b199 | ||
|
|
2078ce01cf | ||
|
|
2770a9cdf3 | ||
|
|
05ef3b1ad8 | ||
|
|
7dd4dbe285 | ||
|
|
b32a5f2c08 | ||
|
|
df76002a44 |
@@ -89,6 +89,7 @@ words:
|
||||
- endmacro
|
||||
- exceptioned
|
||||
- Falco
|
||||
- fcontext
|
||||
- finalizers
|
||||
- firewalled
|
||||
- fmtdur
|
||||
@@ -101,6 +102,7 @@ words:
|
||||
- gpgcheck
|
||||
- gpgkey
|
||||
- hotwallet
|
||||
- hwaddress
|
||||
- ifndef
|
||||
- inequation
|
||||
- insuf
|
||||
@@ -213,6 +215,7 @@ words:
|
||||
- soci
|
||||
- socidb
|
||||
- sslws
|
||||
- stackful
|
||||
- statsd
|
||||
- STATSDCOLLECTOR
|
||||
- stissue
|
||||
|
||||
10
.github/scripts/strategy-matrix/generate.py
vendored
10
.github/scripts/strategy-matrix/generate.py
vendored
@@ -242,10 +242,12 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
# names get truncated.
|
||||
# Add Address and Thread (both coupled with UB) sanitizers for specific bookworm distros.
|
||||
# GCC-Asan rippled-embedded tests are failing because of https://github.com/google/sanitizers/issues/856
|
||||
if (
|
||||
os["distro_version"] == "bookworm"
|
||||
and f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20"
|
||||
):
|
||||
if os[
|
||||
"distro_version"
|
||||
] == "bookworm" and f"{os['compiler_name']}-{os['compiler_version']}" in [
|
||||
"clang-20",
|
||||
"gcc-13",
|
||||
]:
|
||||
# Add ASAN + UBSAN configuration.
|
||||
configurations.append(
|
||||
{
|
||||
|
||||
17
.github/workflows/reusable-build-test-config.yml
vendored
17
.github/workflows/reusable-build-test-config.yml
vendored
@@ -205,14 +205,18 @@ jobs:
|
||||
- name: Set sanitizer options
|
||||
if: ${{ !inputs.build_only && env.SANITIZERS_ENABLED == 'true' }}
|
||||
run: |
|
||||
echo "ASAN_OPTIONS=print_stacktrace=1:detect_container_overflow=0:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/asan.supp" >> ${GITHUB_ENV}
|
||||
echo "TSAN_OPTIONS=second_deadlock_stack=1:halt_on_error=0:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/tsan.supp" >> ${GITHUB_ENV}
|
||||
echo "UBSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/ubsan.supp" >> ${GITHUB_ENV}
|
||||
echo "LSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/lsan.supp" >> ${GITHUB_ENV}
|
||||
echo "ASAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-asan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/asan.supp" >> ${GITHUB_ENV}
|
||||
echo "TSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-tsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/tsan.supp" >> ${GITHUB_ENV}
|
||||
echo "UBSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-ubsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/ubsan.supp" >> ${GITHUB_ENV}
|
||||
echo "LSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-lsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/lsan.supp" >> ${GITHUB_ENV}
|
||||
|
||||
- name: Run the separate tests
|
||||
# We continue on error here because we want to try the Embedded tests before
|
||||
# failing. This will give us details on all the failures at once.
|
||||
continue-on-error: true
|
||||
if: ${{ !inputs.build_only }}
|
||||
working-directory: ${{ env.BUILD_DIR }}
|
||||
id: separate_tests
|
||||
# Windows locks some of the build files while running tests, and parallel jobs can collide
|
||||
env:
|
||||
BUILD_TYPE: ${{ inputs.build_type }}
|
||||
@@ -231,6 +235,11 @@ jobs:
|
||||
run: |
|
||||
./xrpld --unittest --unittest-jobs "${BUILD_NPROC}"
|
||||
|
||||
# Pipeline should fail if the separate tests failed.
|
||||
- name: Check results of the SeparateTests
|
||||
if: ${{ !inputs.build_only && steps.separate_tests.outcome == 'failure' }}
|
||||
run: exit 1
|
||||
|
||||
- name: Debug failure (Linux)
|
||||
if: ${{ failure() && runner.os == 'Linux' && !inputs.build_only }}
|
||||
run: |
|
||||
|
||||
@@ -34,16 +34,16 @@ target_link_libraries(xrpl_boost
|
||||
if(Boost_COMPILER)
|
||||
target_link_libraries(xrpl_boost INTERFACE Boost::disable_autolinking)
|
||||
endif()
|
||||
if(SANITIZERS_ENABLED AND is_clang)
|
||||
# TODO: gcc does not support -fsanitize-blacklist...can we do something else
|
||||
# for gcc ?
|
||||
if(NOT Boost_INCLUDE_DIRS AND TARGET Boost::headers)
|
||||
get_target_property(Boost_INCLUDE_DIRS Boost::headers INTERFACE_INCLUDE_DIRECTORIES)
|
||||
endif()
|
||||
message(STATUS "Adding [${Boost_INCLUDE_DIRS}] to sanitizer blacklist")
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt "src:${Boost_INCLUDE_DIRS}/*")
|
||||
target_compile_options(opts
|
||||
INTERFACE
|
||||
# ignore boost headers for sanitizing
|
||||
-fsanitize-blacklist=${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt)
|
||||
endif()
|
||||
# if(SANITIZERS_ENABLED AND is_clang)
|
||||
# # TODO: gcc does not support -fsanitize-blacklist...can we do something else
|
||||
# # for gcc ?
|
||||
# if(NOT Boost_INCLUDE_DIRS AND TARGET Boost::headers)
|
||||
# get_target_property(Boost_INCLUDE_DIRS Boost::headers INTERFACE_INCLUDE_DIRECTORIES)
|
||||
# endif()
|
||||
# message(STATUS "Adding [${Boost_INCLUDE_DIRS}] to sanitizer blacklist")
|
||||
# file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt "src:${Boost_INCLUDE_DIRS}/*")
|
||||
# target_compile_options(opts
|
||||
# INTERFACE
|
||||
# # ignore boost headers for sanitizing
|
||||
# -fsanitize-blacklist=${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt)
|
||||
# endif()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import re
|
||||
import os
|
||||
|
||||
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
|
||||
|
||||
@@ -126,6 +127,12 @@ class Xrpl(ConanFile):
|
||||
if self.settings.compiler in ["clang", "gcc"]:
|
||||
self.options["boost"].without_cobalt = True
|
||||
|
||||
# Check if environment variable exists
|
||||
if "SANITIZERS" in os.environ:
|
||||
sanitizers = os.environ["SANITIZERS"]
|
||||
if "Address" in sanitizers:
|
||||
self.default_options["fPIC"] = False
|
||||
|
||||
def requirements(self):
|
||||
# Conan 2 requires transitive headers to be specified
|
||||
transitive_headers_opt = (
|
||||
|
||||
8
docs/build/sanitizers.md
vendored
8
docs/build/sanitizers.md
vendored
@@ -89,8 +89,8 @@ cmake --build . --parallel 4
|
||||
**IMPORTANT**: ASAN with Boost produces many false positives. Use these options:
|
||||
|
||||
```bash
|
||||
export ASAN_OPTIONS="print_stacktrace=1:detect_container_overflow=0:suppressions=path/to/asan.supp:halt_on_error=0:log_path=asan.log"
|
||||
export LSAN_OPTIONS="suppressions=path/to/lsan.supp:halt_on_error=0:log_path=lsan.log"
|
||||
export ASAN_OPTIONS="include=sanitizers/suppressions/runtime-asan-options.txt:suppressions=sanitizers/suppressions/asan.supp"
|
||||
export LSAN_OPTIONS="include=sanitizers/suppressions/runtime-lsan-options.txt:suppressions=sanitizers/suppressions/lsan.supp"
|
||||
|
||||
# Run tests
|
||||
./xrpld --unittest --unittest-jobs=5
|
||||
@@ -108,7 +108,7 @@ export LSAN_OPTIONS="suppressions=path/to/lsan.supp:halt_on_error=0:log_path=lsa
|
||||
### ThreadSanitizer (TSan)
|
||||
|
||||
```bash
|
||||
export TSAN_OPTIONS="suppressions=path/to/tsan.supp halt_on_error=0 log_path=tsan.log"
|
||||
export TSAN_OPTIONS="include=sanitizers/suppressions/runtime-tsan-options.txt:suppressions=sanitizers/suppressions/tsan.supp"
|
||||
|
||||
# Run tests
|
||||
./xrpld --unittest --unittest-jobs=5
|
||||
@@ -129,7 +129,7 @@ More details [here](https://github.com/google/sanitizers/wiki/AddressSanitizerLe
|
||||
### UndefinedBehaviorSanitizer (UBSan)
|
||||
|
||||
```bash
|
||||
export UBSAN_OPTIONS="suppressions=path/to/ubsan.supp:print_stacktrace=1:halt_on_error=0:log_path=ubsan.log"
|
||||
export UBSAN_OPTIONS="include=sanitizers/suppressions/runtime-ubsan-options.txt:suppressions=sanitizers/suppressions/ubsan.supp"
|
||||
|
||||
# Run tests
|
||||
./xrpld --unittest --unittest-jobs=5
|
||||
|
||||
@@ -733,8 +733,12 @@ Number::normalizeToRange(T minMantissa, T maxMantissa) const
|
||||
"Number is non-negative for unsigned range.");
|
||||
Number::normalize(negative, mantissa, exponent, minMantissa, maxMantissa);
|
||||
|
||||
auto const sign = negative ? -1 : 1;
|
||||
return std::make_pair(static_cast<T>(sign * mantissa), exponent);
|
||||
// Cast mantissa to signed type first to avoid unsigned integer overflow
|
||||
// when multiplying by negative sign
|
||||
T signedMantissa = static_cast<T>(mantissa);
|
||||
if (negative)
|
||||
signedMantissa = -signedMantissa;
|
||||
return std::make_pair(signedMantissa, exponent);
|
||||
}
|
||||
|
||||
inline constexpr Number
|
||||
|
||||
@@ -366,6 +366,7 @@ public:
|
||||
base_uint&
|
||||
operator&=(base_uint const& b)
|
||||
{
|
||||
XRPL_ASSERT(WIDTH == b.WIDTH, "input size mismatch");
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
data_[i] &= b.data_[i];
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef XRPL_BASICS_CONTRACT_H_INCLUDED
|
||||
#define XRPL_BASICS_CONTRACT_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/sanitizers.h>
|
||||
#include <xrpl/beast/type_name.h>
|
||||
|
||||
#include <exception>
|
||||
@@ -25,7 +26,7 @@ LogThrow(std::string const& title);
|
||||
control to the next matching exception handler, if any.
|
||||
Otherwise, std::terminate will be called.
|
||||
*/
|
||||
[[noreturn]] inline void
|
||||
[[noreturn]] inline void XRPL_NO_SANITIZE_ADDRESS
|
||||
Rethrow()
|
||||
{
|
||||
LogThrow("Re-throwing exception");
|
||||
@@ -33,7 +34,7 @@ Rethrow()
|
||||
}
|
||||
|
||||
template <class E, class... Args>
|
||||
[[noreturn]] inline void
|
||||
[[noreturn]] inline void XRPL_NO_SANITIZE_ADDRESS
|
||||
Throw(Args&&... args)
|
||||
{
|
||||
static_assert(
|
||||
|
||||
7
include/xrpl/basics/sanitizers.h
Normal file
7
include/xrpl/basics/sanitizers.h
Normal file
@@ -0,0 +1,7 @@
|
||||
// Helper to disable ASan/HwASan for specific functions
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define XRPL_NO_SANITIZE_ADDRESS \
|
||||
__attribute__((no_sanitize("address", "hwaddress")))
|
||||
#else
|
||||
#define XRPL_NO_SANITIZE_ADDRESS
|
||||
#endif
|
||||
@@ -30,6 +30,9 @@ public:
|
||||
bool sslVerify,
|
||||
beast::Journal j);
|
||||
|
||||
static void
|
||||
cleanupSSLContext();
|
||||
|
||||
static void
|
||||
get(bool bSSL,
|
||||
boost::asio::io_context& io_context,
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
# The idea is to empty this file gradually by fixing the underlying issues and removing suppressions.
|
||||
# The idea is to empty this file gradually by fixing the underlying issues and removing suppresions.
|
||||
#
|
||||
# ASAN_OPTIONS="print_stacktrace=1:detect_container_overflow=0:suppressions=sanitizers/suppressions/asan.supp:halt_on_error=0"
|
||||
# ASAN_OPTIONS="suppressions=sanitizers/suppressions/asan.supp:halt_on_error=0:detect_stack_use_after_return=0"
|
||||
#
|
||||
# The detect_container_overflow=0 option disables false positives from:
|
||||
# - Boost intrusive containers (slist_iterator.hpp, hashtable.hpp, aged_unordered_container.h)
|
||||
# - Boost context/coroutine stack switching (Workers.cpp, thread.h)
|
||||
# Boost coroutines cause multiple ASAN false positives due to swapcontext/fiber stack switching.
|
||||
# ASAN cannot correctly track stack memory across coroutine context switches, leading to:
|
||||
# - stack-use-after-return errors
|
||||
# - stack-use-after-scope errors
|
||||
# - stack-buffer-overflow errors in seemingly unrelated code (e.g., std::chrono::steady_clock::now())
|
||||
# - stack-buffer-underflow errors in seemingly unrelated code (e.g., xxhasher::retrieveHash(), clock_gettime)
|
||||
#
|
||||
# See: https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow
|
||||
# These are suppressed via:
|
||||
# 1. Runtime option: detect_stack_use_after_return=0 (in ASAN_OPTIONS in CI workflow)
|
||||
# 2. Compile-time flag: -fno-sanitize-address-use-after-scope (in cmake/XrplSanitizers.cmake)
|
||||
#
|
||||
# Note: stack-buffer-overflow false positives from coroutines cannot be fully suppressed
|
||||
# without disabling ASAN entirely for Boost. Clang builds use -fsanitize-blacklist to
|
||||
# exclude Boost headers, but GCC does not support this feature.
|
||||
#
|
||||
# See: https://github.com/google/sanitizers/issues/189
|
||||
|
||||
# Boost
|
||||
interceptor_name:boost/asio
|
||||
|
||||
# Leaks in Doctest tests: xrpl.test.*
|
||||
interceptor_name:src/libxrpl/net/HTTPClient.cpp
|
||||
interceptor_name:src/libxrpl/net/RegisterSSLCerts.cpp
|
||||
interceptor_name:src/tests/libxrpl/net/HTTPClient.cpp
|
||||
interceptor_name:xrpl/net/AutoSocket.h
|
||||
interceptor_name:xrpl/net/HTTPClient.h
|
||||
interceptor_name:xrpl/net/HTTPClientSSLContext.h
|
||||
interceptor_name:xrpl/net/RegisterSSLCerts.h
|
||||
|
||||
# Suppress false positive stack-buffer errors in thread stack allocation
|
||||
# Related to ASan's __asan_handle_no_return warnings (github.com/google/sanitizers/issues/189)
|
||||
# These occur during multi-threaded test initialization on macOS
|
||||
# Boost - false positives from stackful coroutines
|
||||
interceptor_name:clock_gettime
|
||||
interceptor_name:memcpy
|
||||
interceptor_name:__bzero
|
||||
interceptor_name:__asan_memset
|
||||
interceptor_name:__asan_memcpy
|
||||
interceptor_via_fun:assert
|
||||
interceptor_via_fun:static_assert
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
# The idea is to empty this file gradually by fixing the underlying issues and removing suppresions.
|
||||
|
||||
# Suppress leaks detected by asan in rippled code.
|
||||
leak:src/libxrpl/net/HTTPClient.cpp
|
||||
leak:src/libxrpl/net/RegisterSSLCerts.cpp
|
||||
leak:src/tests/libxrpl/net/HTTPClient.cpp
|
||||
leak:xrpl/net/AutoSocket.h
|
||||
leak:xrpl/net/HTTPClient.h
|
||||
leak:xrpl/net/HTTPClientSSLContext.h
|
||||
leak:xrpl/net/RegisterSSLCerts.h
|
||||
leak:ripple::HTTPClient
|
||||
leak:ripple::HTTPClientImp
|
||||
|
||||
# Suppress leaks detected by asan in boost code.
|
||||
leak:boost::asio
|
||||
leak:boost/asio
|
||||
# These are false positives from Boost.Asio SSL internals that use OpenSSL BIO structures.
|
||||
# The BIO structures are managed by OpenSSL's internal reference counting and freed at process exit.
|
||||
|
||||
#leak:boost::asio
|
||||
#leak:boost/asio
|
||||
|
||||
# OpenSSL BIO memory is managed internally and freed at process exit
|
||||
leak:CRYPTO_malloc
|
||||
leak:bio_make_pair
|
||||
leak:BIO_new_bio_pair
|
||||
|
||||
3
sanitizers/suppressions/runtime-asan-options.txt
Normal file
3
sanitizers/suppressions/runtime-asan-options.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
detect_container_overflow=0
|
||||
detect_stack_use_after_return=0
|
||||
debug=true
|
||||
1
sanitizers/suppressions/runtime-lsan-options.txt
Normal file
1
sanitizers/suppressions/runtime-lsan-options.txt
Normal file
@@ -0,0 +1 @@
|
||||
halt_on_error=false
|
||||
3
sanitizers/suppressions/runtime-tsan-options.txt
Normal file
3
sanitizers/suppressions/runtime-tsan-options.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
halt_on_error=false
|
||||
verbosity=1
|
||||
second_deadlock_stack=1
|
||||
1
sanitizers/suppressions/runtime-ubsan-options.txt
Normal file
1
sanitizers/suppressions/runtime-ubsan-options.txt
Normal file
@@ -0,0 +1 @@
|
||||
halt_on_error=false
|
||||
@@ -27,3 +27,8 @@ src:core/JobQueue.cpp
|
||||
src:libxrpl/beast/utility/beast_Journal.cpp
|
||||
src:test/beast/beast_PropertyStream_test.cpp
|
||||
src:src/test/app/Invariants_test.cpp
|
||||
|
||||
# Boost coroutines cause false positive stack-buffer-underflow in xxhasher
|
||||
# This is a known ASAN limitation with stackful coroutines
|
||||
# See: https://github.com/google/sanitizers/issues/189
|
||||
src:beast/hash/xxhasher.h
|
||||
|
||||
@@ -140,6 +140,7 @@ unsigned-integer-overflow:src/libxrpl/protocol/tokens.cpp
|
||||
unsigned-integer-overflow:src/libxrpl/shamap/SHAMap.cpp
|
||||
unsigned-integer-overflow:src/test/app/Batch_test.cpp
|
||||
unsigned-integer-overflow:src/test/app/Invariants_test.cpp
|
||||
unsigned-integer-overflow:src/test/app/Loan_test.cpp
|
||||
unsigned-integer-overflow:src/test/app/NFToken_test.cpp
|
||||
unsigned-integer-overflow:src/test/app/Offer_test.cpp
|
||||
unsigned-integer-overflow:src/test/app/Path_test.cpp
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <numeric>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
@@ -109,7 +110,7 @@ public:
|
||||
int& exponent,
|
||||
internalrep const& minMantissa,
|
||||
internalrep const& maxMantissa,
|
||||
std::string location);
|
||||
std::string_view location);
|
||||
|
||||
// Modify the result to the correctly rounded value
|
||||
template <UnsignedMantissa T>
|
||||
@@ -122,7 +123,7 @@ public:
|
||||
|
||||
// Modify the result to the correctly rounded value
|
||||
void
|
||||
doRound(rep& drops, std::string location);
|
||||
doRound(rep& drops, std::string_view location);
|
||||
|
||||
private:
|
||||
void
|
||||
@@ -252,7 +253,7 @@ Number::Guard::doRoundUp(
|
||||
int& exponent,
|
||||
internalrep const& minMantissa,
|
||||
internalrep const& maxMantissa,
|
||||
std::string location)
|
||||
std::string_view location)
|
||||
{
|
||||
auto r = round();
|
||||
if (r == 1 || (r == 0 && (mantissa & 1) == 1))
|
||||
@@ -268,7 +269,7 @@ Number::Guard::doRoundUp(
|
||||
}
|
||||
bringIntoRange(negative, mantissa, exponent, minMantissa);
|
||||
if (exponent > maxExponent)
|
||||
throw std::overflow_error(location);
|
||||
Throw<std::overflow_error>(std::string(location));
|
||||
}
|
||||
|
||||
template <UnsignedMantissa T>
|
||||
@@ -294,7 +295,7 @@ Number::Guard::doRoundDown(
|
||||
|
||||
// Modify the result to the correctly rounded value
|
||||
void
|
||||
Number::Guard::doRound(rep& drops, std::string location)
|
||||
Number::Guard::doRound(rep& drops, std::string_view location)
|
||||
{
|
||||
auto r = round();
|
||||
if (r == 1 || (r == 0 && (drops & 1) == 1))
|
||||
@@ -308,7 +309,7 @@ Number::Guard::doRound(rep& drops, std::string location)
|
||||
// or "(maxRep + 1) / 10", neither of which will round up when
|
||||
// converting to rep, though the latter might overflow _before_
|
||||
// rounding.
|
||||
throw std::overflow_error(location); // LCOV_EXCL_LINE
|
||||
throw std::overflow_error(std::string(location)); // LCOV_EXCL_LINE
|
||||
}
|
||||
++drops;
|
||||
}
|
||||
@@ -462,10 +463,10 @@ doNormalize(
|
||||
minMantissa,
|
||||
maxMantissa,
|
||||
"Number::normalize 2");
|
||||
XRPL_ASSERT_PARTS(
|
||||
mantissa_ >= minMantissa && mantissa_ <= maxMantissa,
|
||||
"xrpl::doNormalize",
|
||||
"final mantissa fits in range");
|
||||
// XRPL_ASSERT_PARTS(
|
||||
// mantissa_ >= minMantissa && mantissa_ <= maxMantissa,
|
||||
// "xrpl::doNormalize",
|
||||
// "final mantissa fits in range");
|
||||
}
|
||||
|
||||
template <>
|
||||
|
||||
@@ -198,17 +198,17 @@ Value::Value(ValueType type) : type_(type), allocated_(0)
|
||||
}
|
||||
}
|
||||
|
||||
Value::Value(Int value) : type_(intValue)
|
||||
Value::Value(Int value) : type_(intValue), allocated_(0)
|
||||
{
|
||||
value_.int_ = value;
|
||||
}
|
||||
|
||||
Value::Value(UInt value) : type_(uintValue)
|
||||
Value::Value(UInt value) : type_(uintValue), allocated_(0)
|
||||
{
|
||||
value_.uint_ = value;
|
||||
}
|
||||
|
||||
Value::Value(double value) : type_(realValue)
|
||||
Value::Value(double value) : type_(realValue), allocated_(0)
|
||||
{
|
||||
value_.real_ = value;
|
||||
}
|
||||
@@ -236,7 +236,7 @@ Value::Value(StaticString const& value) : type_(stringValue), allocated_(false)
|
||||
value_.string_ = const_cast<char*>(value.c_str());
|
||||
}
|
||||
|
||||
Value::Value(bool value) : type_(booleanValue)
|
||||
Value::Value(bool value) : type_(booleanValue), allocated_(0)
|
||||
{
|
||||
value_.bool_ = value;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,12 @@ HTTPClient::initializeSSLContext(
|
||||
httpClientSSLContext.emplace(sslVerifyDir, sslVerifyFile, sslVerify, j);
|
||||
}
|
||||
|
||||
void
|
||||
HTTPClient::cleanupSSLContext()
|
||||
{
|
||||
httpClientSSLContext.reset();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Fetch a web page via http or https.
|
||||
|
||||
@@ -71,7 +71,7 @@ make_name(std::string const& object, std::string const& field)
|
||||
if (field.empty())
|
||||
return object;
|
||||
|
||||
return object + "." + field;
|
||||
return {object + "." + field};
|
||||
}
|
||||
|
||||
static inline Json::Value
|
||||
|
||||
@@ -77,7 +77,8 @@ SHAMapNodeID::getChildNodeID(unsigned int m) const
|
||||
Throw<std::logic_error>(
|
||||
"Request for child node ID of " + to_string(*this));
|
||||
|
||||
if (id_ != (id_ & depthMask(depth_)))
|
||||
auto const idAtDepth = id_ & depthMask(depth_);
|
||||
if (id_ != idAtDepth)
|
||||
Throw<std::logic_error>("Incorrect mask for " + to_string(*this));
|
||||
|
||||
SHAMapNodeID node{depth_ + 1, id_};
|
||||
|
||||
@@ -156,7 +156,7 @@ private:
|
||||
std::vector<std::string> emptyCfgKeys;
|
||||
struct publisher
|
||||
{
|
||||
publisher(FetchListConfig const& c) : cfg{c}
|
||||
publisher(FetchListConfig const& c) : cfg{c}, isRetry{false}
|
||||
{
|
||||
}
|
||||
std::shared_ptr<TrustedPublisherServer> server;
|
||||
|
||||
@@ -277,6 +277,9 @@ TEST(HTTPClient, case_insensitive_content_length)
|
||||
EXPECT_EQ(resultStatus, 200);
|
||||
EXPECT_EQ(resultData, testBody);
|
||||
}
|
||||
|
||||
// Clean up SSL context to prevent memory leaks
|
||||
HTTPClient::cleanupSSLContext();
|
||||
}
|
||||
|
||||
TEST(HTTPClient, basic_http_request)
|
||||
@@ -298,6 +301,9 @@ TEST(HTTPClient, basic_http_request)
|
||||
EXPECT_FALSE(resultError);
|
||||
EXPECT_EQ(resultStatus, 200);
|
||||
EXPECT_EQ(resultData, testBody);
|
||||
|
||||
// Clean up SSL context to prevent memory leaks
|
||||
HTTPClient::cleanupSSLContext();
|
||||
}
|
||||
|
||||
TEST(HTTPClient, empty_response)
|
||||
@@ -318,6 +324,9 @@ TEST(HTTPClient, empty_response)
|
||||
EXPECT_FALSE(resultError);
|
||||
EXPECT_EQ(resultStatus, 200);
|
||||
EXPECT_TRUE(resultData.empty());
|
||||
|
||||
// Clean up SSL context to prevent memory leaks
|
||||
HTTPClient::cleanupSSLContext();
|
||||
}
|
||||
|
||||
TEST(HTTPClient, different_status_codes)
|
||||
@@ -347,4 +356,7 @@ TEST(HTTPClient, different_status_codes)
|
||||
EXPECT_FALSE(resultError);
|
||||
EXPECT_EQ(resultStatus, static_cast<int>(status));
|
||||
}
|
||||
|
||||
// Clean up SSL context to prevent memory leaks
|
||||
HTTPClient::cleanupSSLContext();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user