diff --git a/.travis.yml b/.travis.yml index 7078fd092..8f871c09a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,12 +43,15 @@ matrix: - os: linux compiler: clang env: - - COMPILER=clang++-5.0 + - COMPILER=clang++-7 - CMAKE_OPTIONS=-DJSON_Sanitizer=ON + - UBSAN_OPTIONS=print_stacktrace=1,suppressions=$(pwd)/test/src/UBSAN.supp addons: apt: - sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-5.0'] - packages: ['g++-6', 'clang-5.0', 'ninja-build'] + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-7'] + packages: ['g++-6', 'clang-7', 'ninja-build'] + before_script: + - export PATH=$PATH:/usr/lib/llvm-7/bin # cppcheck - os: linux @@ -330,7 +333,7 @@ script: # compile and execute unit tests - mkdir -p build && cd build - cmake .. ${CMAKE_OPTIONS} -DJSON_MultipleHeaders=${MULTIPLE_HEADERS} -GNinja && cmake --build . --config Release - - ctest -C Release -V -j + - ctest -C Release --timeout 2700 -V -j - cd .. # check if homebrew works (only checks develop branch) diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp index db9eaf2bd..c3ac5aa8f 100644 --- a/include/nlohmann/detail/conversions/to_json.hpp +++ b/include/nlohmann/detail/conversions/to_json.hpp @@ -154,7 +154,10 @@ struct external_constructor j.m_type = value_t::array; j.m_value = value_t::array; j.m_value.array->resize(arr.size()); - std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin()); + if (arr.size() > 0) + { + std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin()); + } j.assert_invariant(); } }; diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index b7b11de03..9512a771e 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -131,9 +131,8 @@ class input_stream_adapter : public input_adapter_protocol class input_buffer_adapter : public input_adapter_protocol { public: - JSON_HEDLEY_NON_NULL(2) input_buffer_adapter(const char* b, const std::size_t l) noexcept - : cursor(b), limit(b + l) + : cursor(b), limit(b == nullptr ? nullptr : (b + l)) {} // delete because of pointer members @@ -147,6 +146,7 @@ class input_buffer_adapter : public input_adapter_protocol { if (JSON_HEDLEY_LIKELY(cursor < limit)) { + assert(cursor != nullptr and limit != nullptr); return std::char_traits::to_int_type(*(cursor++)); } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 2a32a8296..e54c3e41f 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3489,7 +3489,10 @@ struct external_constructor j.m_type = value_t::array; j.m_value = value_t::array; j.m_value.array->resize(arr.size()); - std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin()); + if (arr.size() > 0) + { + std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin()); + } j.assert_invariant(); } }; @@ -3882,9 +3885,8 @@ class input_stream_adapter : public input_adapter_protocol class input_buffer_adapter : public input_adapter_protocol { public: - JSON_HEDLEY_NON_NULL(2) input_buffer_adapter(const char* b, const std::size_t l) noexcept - : cursor(b), limit(b + l) + : cursor(b), limit(b == nullptr ? nullptr : (b + l)) {} // delete because of pointer members @@ -3898,6 +3900,7 @@ class input_buffer_adapter : public input_adapter_protocol { if (JSON_HEDLEY_LIKELY(cursor < limit)) { + assert(cursor != nullptr and limit != nullptr); return std::char_traits::to_int_type(*(cursor++)); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b73dfc9ad..e13d31bba 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,7 +6,7 @@ option(JSON_Coverage "Build test suite with coverage information" OFF) if(JSON_Sanitizer) message(STATUS "Building test suite with Clang sanitizer") if(NOT MSVC) - set(CMAKE_CXX_FLAGS "-g -O2 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer") + set(CMAKE_CXX_FLAGS "-g -O0 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fsanitize-recover=unsigned-integer-overflow") endif() endif() @@ -71,7 +71,7 @@ set_target_properties(doctest_main PROPERTIES COMPILE_DEFINITIONS "$<$:_SCL_SECURE_NO_WARNINGS>" COMPILE_OPTIONS "$<$:/EHsc;$<$:/Od>>" ) -if (${CMAKE_VERSION} VERSION_LESS "3.8.0") +if (${CMAKE_VERSION} VERSION_LESS "3.8.0") target_compile_features(doctest_main PUBLIC cxx_range_for) else() target_compile_features(doctest_main PUBLIC cxx_std_11) @@ -92,7 +92,7 @@ if(MSVC) # Disable warning C4566: character represented by universal-character-name '\uFF01' cannot be represented in the current code page (1252) # Disable warning C4996: 'nlohmann::basic_json::operator <<': was declared deprecated set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4389 /wd4309 /wd4566 /wd4996") - + # https://github.com/nlohmann/json/issues/1114 set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj") endif() diff --git a/test/src/UBSAN.supp b/test/src/UBSAN.supp new file mode 100644 index 000000000..b19f04369 --- /dev/null +++ b/test/src/UBSAN.supp @@ -0,0 +1 @@ +unsigned-integer-overflow:stl_bvector.h