diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index c24332628..440710427 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -43,6 +43,16 @@ jobs: - name: build run: cmake --build build --target ${{ matrix.target }} + ci_test_single_header: + runs-on: ubuntu-latest + container: ghcr.io/nlohmann/json-ci:v2.4.0 + steps: + - uses: actions/checkout@v3 + - name: cmake + run: cmake -S . -B build -DJSON_CI=On + - name: build + run: cmake --build build --target ci_test_single_header + ci_cmake_options: runs-on: ubuntu-latest container: ghcr.io/nlohmann/json-ci:v2.4.0 diff --git a/CMakeLists.txt b/CMakeLists.txt index 632e6dec2..aae5fb6e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,7 +43,7 @@ option(JSON_Diagnostics "Use extended diagnostic messages." O option(JSON_ImplicitConversions "Enable implicit conversions." ON) option(JSON_LegacyDiscardedValueComparison "Enable legacy discarded value comparison." OFF) option(JSON_Install "Install CMake targets during install step." ${MAIN_PROJECT}) -option(JSON_MultipleHeaders "Use non-amalgamated version of the library." OFF) +option(JSON_MultipleHeaders "Use non-amalgamated version of the library." ON) option(JSON_SystemInclude "Include as system headers (skip for clang-tidy)." OFF) if (JSON_CI) diff --git a/cmake/ci.cmake b/cmake/ci.cmake index d813a1773..8704d4a54 100644 --- a/cmake/ci.cmake +++ b/cmake/ci.cmake @@ -416,7 +416,7 @@ set(GCC_CXXFLAGS add_custom_target(ci_test_gcc COMMAND CXX=${GCC_TOOL} CXXFLAGS="${GCC_CXXFLAGS}" ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug -GNinja - -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON + -DJSON_BuildTests=ON -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_gcc COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_gcc COMMAND cd ${PROJECT_BINARY_DIR}/build_gcc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure @@ -426,7 +426,7 @@ add_custom_target(ci_test_gcc add_custom_target(ci_test_clang COMMAND CXX=${CLANG_TOOL} CXXFLAGS="${CLANG_CXXFLAGS}" ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug -GNinja - -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON + -DJSON_BuildTests=ON -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang COMMAND cd ${PROJECT_BINARY_DIR}/build_clang && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure @@ -468,7 +468,7 @@ endforeach() add_custom_target(ci_test_noexceptions COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug -GNinja - -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON -DCMAKE_CXX_FLAGS=-DJSON_NOEXCEPTION -DDOCTEST_TEST_FILTER=--no-throw + -DJSON_BuildTests=ON -DCMAKE_CXX_FLAGS=-DJSON_NOEXCEPTION -DDOCTEST_TEST_FILTER=--no-throw -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_noexceptions COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_noexceptions COMMAND cd ${PROJECT_BINARY_DIR}/build_noexceptions && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure @@ -482,7 +482,7 @@ add_custom_target(ci_test_noexceptions add_custom_target(ci_test_noimplicitconversions COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug -GNinja - -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON -DJSON_ImplicitConversions=OFF + -DJSON_BuildTests=ON -DJSON_ImplicitConversions=OFF -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_noimplicitconversions COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_noimplicitconversions COMMAND cd ${PROJECT_BINARY_DIR}/build_noimplicitconversions && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure @@ -496,7 +496,7 @@ add_custom_target(ci_test_noimplicitconversions add_custom_target(ci_test_diagnostics COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug -GNinja - -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON -DJSON_Diagnostics=ON + -DJSON_BuildTests=ON -DJSON_Diagnostics=ON -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_diagnostics COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_diagnostics COMMAND cd ${PROJECT_BINARY_DIR}/build_diagnostics && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure @@ -510,7 +510,7 @@ add_custom_target(ci_test_diagnostics add_custom_target(ci_test_legacycomparison COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug -GNinja - -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON -DJSON_LegacyDiscardedValueComparison=ON + -DJSON_BuildTests=ON -DJSON_LegacyDiscardedValueComparison=ON -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_legacycomparison COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_legacycomparison COMMAND cd ${PROJECT_BINARY_DIR}/build_legacycomparison && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure @@ -524,11 +524,18 @@ add_custom_target(ci_test_legacycomparison add_custom_target(ci_test_coverage COMMAND CXX=g++ ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_CXX_FLAGS="--coverage;-fprofile-arcs;-ftest-coverage" - -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON + -DJSON_BuildTests=ON -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_coverage COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_coverage COMMAND cd ${PROJECT_BINARY_DIR}/build_coverage && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMAND CXX=g++ ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_CXX_FLAGS="-m32;--coverage;-fprofile-arcs;-ftest-coverage" + -DJSON_BuildTests=ON -DJSON_32bitTest=ONLY + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_coverage32 + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_coverage32 + COMMAND cd ${PROJECT_BINARY_DIR}/build_coverage32 && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMAND ${LCOV_TOOL} --directory . --capture --output-file json.info --rc lcov_branch_coverage=1 COMMAND ${LCOV_TOOL} -e json.info ${SRC_FILES} --output-file json.info.filtered --rc lcov_branch_coverage=1 COMMAND ${CMAKE_SOURCE_DIR}/tests/thirdparty/imapdl/filterbr.py json.info.filtered > json.info.filtered.noexcept @@ -581,6 +588,20 @@ add_custom_target(ci_test_amalgamation COMMENT "Check amalgamation and indentation" ) +############################################################################### +# Build and test using the amalgamated header +############################################################################### + +add_custom_target(ci_test_single_header + COMMAND CXX=${GCC_TOOL} CXXFLAGS="${GCC_CXXFLAGS}" ${CMAKE_COMMAND} + -DCMAKE_BUILD_TYPE=Debug -GNinja + -DJSON_BuildTests=ON -DJSON_MultipleHeader=OFF -DJSON_FastTests=ON + -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_single_header + COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_single_header + COMMAND cd ${PROJECT_BINARY_DIR}/build_single_header && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure + COMMENT "Compile and test single-header version" +) + ############################################################################### # Valgrind. ############################################################################### @@ -664,7 +685,7 @@ add_custom_target(ci_clang_tidy COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_CXX_CLANG_TIDY=${CLANG_TIDY_TOOL} - -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON + -DJSON_BuildTests=ON -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_tidy COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_tidy COMMENT "Check code with Clang-Tidy" @@ -691,7 +712,7 @@ add_custom_target(ci_pvs_studio add_custom_target(ci_infer COMMAND mkdir -p ${PROJECT_BINARY_DIR}/build_infer - COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} compile -- ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${PROJECT_SOURCE_DIR} -DJSON_BuildTests=ON -DJSON_MultipleHeaders=ON + COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} compile -- ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${PROJECT_SOURCE_DIR} -DJSON_BuildTests=ON COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} run -- make COMMENT "Check code with Infer" ) diff --git a/cmake/test.cmake b/cmake/test.cmake index 89b7c6ec7..b8b1250fb 100644 --- a/cmake/test.cmake +++ b/cmake/test.cmake @@ -211,3 +211,32 @@ function(json_test_add_test_for file) _json_test_add_test(${test_name} ${file} ${args_MAIN} ${cxx_standard}) endforeach() endfunction() + +############################################################################# +# json_test_should_build_32bit_test( +# ) +# +# Check if the 32bit unit test should be built based on the value of +# and store the result in the variables and +# . +############################################################################# + +function(json_test_should_build_32bit_test build_32bit_var build_32bit_only_var input) + set(${build_32bit_only_var} OFF PARENT_SCOPE) + string(TOUPPER "${input}" ${build_32bit_var}) + if("${${build_32bit_var}}" STREQUAL AUTO) + # check if compiler is targeting 32bit by default + include(CheckTypeSize) + check_type_size("size_t" sizeof_size_t LANGUAGE CXX) + if(sizeof_size_t AND ${sizeof_size_t} EQUAL 4) + message(STATUS "Auto-enabling 32bit unit test.") + set(${build_32bit_var} ON) + else() + set(${build_32bit_var} OFF) + endif() + elseif("${${build_32bit_var}}" STREQUAL ONLY) + set(${build_32bit_only_var} ON PARENT_SCOPE) + endif() + + set(${build_32bit_var} "${${build_32bit_var}}" PARENT_SCOPE) +endfunction() diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 9332af3e6..f5871ddf6 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -618,7 +618,8 @@ class binary_reader case 0x95: case 0x96: case 0x97: - return get_cbor_array(static_cast(static_cast(current) & 0x1Fu), tag_handler); + return get_cbor_array( + conditional_static_cast(static_cast(current) & 0x1Fu), tag_handler); case 0x98: // array (one-byte uint8_t for n follows) { @@ -635,13 +636,13 @@ class binary_reader case 0x9A: // array (four-byte uint32_t for n follow) { std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); + return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast(len), tag_handler); } case 0x9B: // array (eight-byte uint64_t for n follow) { std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast(len), tag_handler); + return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast(len), tag_handler); } case 0x9F: // array (indefinite length) @@ -672,7 +673,7 @@ class binary_reader case 0xB5: case 0xB6: case 0xB7: - return get_cbor_object(static_cast(static_cast(current) & 0x1Fu), tag_handler); + return get_cbor_object(conditional_static_cast(static_cast(current) & 0x1Fu), tag_handler); case 0xB8: // map (one-byte uint8_t for n follows) { @@ -689,13 +690,13 @@ class binary_reader case 0xBA: // map (four-byte uint32_t for n follow) { std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); + return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast(len), tag_handler); } case 0xBB: // map (eight-byte uint64_t for n follow) { std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast(len), tag_handler); + return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast(len), tag_handler); } case 0xBF: // map (indefinite length) @@ -1342,7 +1343,7 @@ class binary_reader case 0x8D: case 0x8E: case 0x8F: - return get_msgpack_object(static_cast(static_cast(current) & 0x0Fu)); + return get_msgpack_object(conditional_static_cast(static_cast(current) & 0x0Fu)); // fixarray case 0x90: @@ -1361,7 +1362,7 @@ class binary_reader case 0x9D: case 0x9E: case 0x9F: - return get_msgpack_array(static_cast(static_cast(current) & 0x0Fu)); + return get_msgpack_array(conditional_static_cast(static_cast(current) & 0x0Fu)); // fixstr case 0xA0: @@ -1498,7 +1499,7 @@ class binary_reader case 0xDD: // array 32 { std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast(len)); + return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast(len)); } case 0xDE: // map 16 @@ -1510,7 +1511,7 @@ class binary_reader case 0xDF: // map 32 { std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast(len)); + return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast(len)); } // negative fixint @@ -2081,9 +2082,8 @@ class binary_reader } if (!value_in_range_of(number)) { - // undo coverage exclusion once the 32bit test is run as part of CI (#3524) - return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, // LCOV_EXCL_LINE - exception_message(input_format, "integer value overflow", "size"), nullptr)); // LCOV_EXCL_LINE + return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, + exception_message(input_format, "integer value overflow", "size"), nullptr)); } result = static_cast(number); return true; @@ -2115,7 +2115,7 @@ class binary_reader { return false; } - result = static_cast(number); + result = conditional_static_cast(number); return true; } @@ -2132,9 +2132,8 @@ class binary_reader } if (!value_in_range_of(number)) { - // undo coverage exclusion once the 32bit test is run as part of CI (#3524) - return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, // LCOV_EXCL_LINE - exception_message(input_format, "integer value overflow", "size"), nullptr)); // LCOV_EXCL_LINE + return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, + exception_message(input_format, "integer value overflow", "size"), nullptr)); } result = detail::conditional_static_cast(number); return true; diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 4a73ce5d3..4a9c4bf83 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -9310,7 +9310,8 @@ class binary_reader case 0x95: case 0x96: case 0x97: - return get_cbor_array(static_cast(static_cast(current) & 0x1Fu), tag_handler); + return get_cbor_array( + conditional_static_cast(static_cast(current) & 0x1Fu), tag_handler); case 0x98: // array (one-byte uint8_t for n follows) { @@ -9327,13 +9328,13 @@ class binary_reader case 0x9A: // array (four-byte uint32_t for n follow) { std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); + return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast(len), tag_handler); } case 0x9B: // array (eight-byte uint64_t for n follow) { std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast(len), tag_handler); + return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast(len), tag_handler); } case 0x9F: // array (indefinite length) @@ -9364,7 +9365,7 @@ class binary_reader case 0xB5: case 0xB6: case 0xB7: - return get_cbor_object(static_cast(static_cast(current) & 0x1Fu), tag_handler); + return get_cbor_object(conditional_static_cast(static_cast(current) & 0x1Fu), tag_handler); case 0xB8: // map (one-byte uint8_t for n follows) { @@ -9381,13 +9382,13 @@ class binary_reader case 0xBA: // map (four-byte uint32_t for n follow) { std::uint32_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); + return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast(len), tag_handler); } case 0xBB: // map (eight-byte uint64_t for n follow) { std::uint64_t len{}; - return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast(len), tag_handler); + return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast(len), tag_handler); } case 0xBF: // map (indefinite length) @@ -10034,7 +10035,7 @@ class binary_reader case 0x8D: case 0x8E: case 0x8F: - return get_msgpack_object(static_cast(static_cast(current) & 0x0Fu)); + return get_msgpack_object(conditional_static_cast(static_cast(current) & 0x0Fu)); // fixarray case 0x90: @@ -10053,7 +10054,7 @@ class binary_reader case 0x9D: case 0x9E: case 0x9F: - return get_msgpack_array(static_cast(static_cast(current) & 0x0Fu)); + return get_msgpack_array(conditional_static_cast(static_cast(current) & 0x0Fu)); // fixstr case 0xA0: @@ -10190,7 +10191,7 @@ class binary_reader case 0xDD: // array 32 { std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast(len)); + return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast(len)); } case 0xDE: // map 16 @@ -10202,7 +10203,7 @@ class binary_reader case 0xDF: // map 32 { std::uint32_t len{}; - return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast(len)); + return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast(len)); } // negative fixint @@ -10773,9 +10774,8 @@ class binary_reader } if (!value_in_range_of(number)) { - // undo coverage exclusion once the 32bit test is run as part of CI (#3524) - return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, // LCOV_EXCL_LINE - exception_message(input_format, "integer value overflow", "size"), nullptr)); // LCOV_EXCL_LINE + return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, + exception_message(input_format, "integer value overflow", "size"), nullptr)); } result = static_cast(number); return true; @@ -10807,7 +10807,7 @@ class binary_reader { return false; } - result = static_cast(number); + result = conditional_static_cast(number); return true; } @@ -10824,9 +10824,8 @@ class binary_reader } if (!value_in_range_of(number)) { - // undo coverage exclusion once the 32bit test is run as part of CI (#3524) - return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, // LCOV_EXCL_LINE - exception_message(input_format, "integer value overflow", "size"), nullptr)); // LCOV_EXCL_LINE + return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, + exception_message(input_format, "integer value overflow", "size"), nullptr)); } result = detail::conditional_static_cast(number); return true; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ef87c4909..8f9240f1a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.13) option(JSON_Valgrind "Execute test suite with Valgrind." OFF) option(JSON_FastTests "Skip expensive/slow tests." OFF) -option(JSON_32bitTest "Enable the 32bit unit test." OFF) +set(JSON_32bitTest AUTO CACHE STRING "Enable the 32bit unit test (ON/OFF/AUTO/ONLY).") set(JSON_TestStandards "" CACHE STRING "The list of standards to test explicitly.") include(test) @@ -34,40 +34,32 @@ endif() # test_main library with shared code to speed up build and common settings ############################################################################# -set(test_main_SOURCES src/unit.cpp) -set(test_main_COMPILE_DEFINITIONS PUBLIC +add_library(test_main OBJECT src/unit.cpp) +target_compile_definitions(test_main PUBLIC DOCTEST_CONFIG_SUPER_FAST_ASSERTS JSON_TEST_KEEP_MACROS) -set(test_main_COMPILE_FEATURES PRIVATE cxx_std_11) -set(test_main_COMPILE_OPTIONS - PUBLIC - $<$:/EHsc;$<$:/Od>> - # MSVC: Force to always compile with W4 - # 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 - $<$:/W4 /wd4566 /wd4996> - # https://github.com/nlohmann/json/issues/1114 - $<$:/bigobj> $<$:-Wa,-mbig-obj> +target_compile_features(test_main PRIVATE cxx_std_11) +target_compile_options(test_main PUBLIC + $<$:/EHsc;$<$:/Od>> + # MSVC: Force to always compile with W4 + # 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 + $<$:/W4 /wd4566 /wd4996> + # https://github.com/nlohmann/json/issues/1114 + $<$:/bigobj> $<$:-Wa,-mbig-obj> - # https://github.com/nlohmann/json/pull/3229 - $<$:-diag-disable=2196> + # https://github.com/nlohmann/json/pull/3229 + $<$:-diag-disable=2196> - $<$>:-Wno-deprecated;-Wno-float-equal> - $<$:-Wno-deprecated-declarations> - $<$:-diag-disable=1786>) -set(test_main_INCLUDE_DIRECTORIES PUBLIC + $<$>:-Wno-deprecated;-Wno-float-equal> + $<$:-Wno-deprecated-declarations> + $<$:-diag-disable=1786>) +target_include_directories(test_main PUBLIC thirdparty/doctest thirdparty/fifo_map ${PROJECT_BINARY_DIR}/include) -set(test_main_LINK_LIBRARIES PUBLIC ${NLOHMANN_JSON_TARGET_NAME}) - -add_library(test_main OBJECT ${test_main_SOURCES}) -target_compile_definitions(test_main ${test_main_COMPILE_DEFINITIONS}) -target_compile_features(test_main ${test_main_COMPILE_FEATURES}) -target_compile_options(test_main ${test_main_COMPILE_OPTIONS}) -target_include_directories(test_main ${test_main_INCLUDE_DIRECTORIES}) -target_link_libraries(test_main ${test_main_LINK_LIBRARIES}) +target_link_libraries(test_main PUBLIC ${NLOHMANN_JSON_TARGET_NAME}) ############################################################################# # define test- and standard-specific build settings @@ -124,23 +116,21 @@ message(STATUS "${msg}") # *DO* use json_test_set_test_options() above this line +json_test_should_build_32bit_test(json_32bit_test json_32bit_test_only "${JSON_32bitTest}") file(GLOB files src/unit-*.cpp) -list(FILTER files EXCLUDE REGEX "src/unit-32bit.cpp") +if(json_32bit_test_only) + set(files src/unit-32bit.cpp) +elseif(NOT json_32bit_test) + list(FILTER files EXCLUDE REGEX src/unit-32bit.cpp) +endif() + foreach(file ${files}) json_test_add_test_for(${file} MAIN test_main CXX_STANDARDS ${test_cxx_standards} ${test_force}) endforeach() -if(JSON_32bitTest) - add_library(test_main32 OBJECT ${test_main_SOURCES}) - target_compile_definitions(test_main32 ${test_main_COMPILE_DEFINITIONS}) - target_compile_features(test_main32 ${test_main_COMPILE_FEATURES}) - target_compile_options(test_main32 ${test_main_COMPILE_OPTIONS} -m32) - target_include_directories(test_main32 ${test_main_INCLUDE_DIRECTORIES}) - target_link_libraries(test_main32 ${test_main_LINK_LIBRARIES}) - target_link_options(test_main32 PUBLIC -m32) - - json_test_add_test_for("src/unit-32bit.cpp" MAIN test_main32 - CXX_STANDARDS ${test_cxx_standards} ${test_force}) +if(json_32bit_test_only) + # Skip all other tests in this file + return() endif() # test legacy comparison of discarded values diff --git a/tests/src/unit-32bit.cpp b/tests/src/unit-32bit.cpp index 711dda5a0..25da44f4d 100644 --- a/tests/src/unit-32bit.cpp +++ b/tests/src/unit-32bit.cpp @@ -98,18 +98,14 @@ TEST_CASE("BJData") { SECTION("array") { - SECTION("optimized array: no size following type") - { - std::vector v = {'[', '$', 'i', 2}; - json _; - CHECK_THROWS_WITH_AS(_ = json::from_bjdata(v), "[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing BJData size: expected '#' after type information; last byte: 0x02", json::parse_error&); - } - - SECTION("optimized array: negative size") + SECTION("optimized array: integer value overflow") { + std::vector vL = {'[', '#', 'L', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F}; std::vector vM = {'[', '$', 'M', '#', '[', 'I', 0x00, 0x20, 'M', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFF, ']'}; json _; + CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vL), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&); + CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vM), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&); } } diff --git a/tests/src/unit-bjdata.cpp b/tests/src/unit-bjdata.cpp index 974ee3a0a..ab046a602 100644 --- a/tests/src/unit-bjdata.cpp +++ b/tests/src/unit-bjdata.cpp @@ -2649,14 +2649,27 @@ TEST_CASE("BJData") CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vL), "[json.exception.parse_error.113] parse error at byte 11: syntax error while parsing BJData size: count in an optimized container must be positive", json::parse_error&); CHECK(json::from_bjdata(vL, true, false).is_discarded()); -#if SIZE_MAX == 0xffffffff - CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vM), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&); -#else +#if SIZE_MAX != 0xffffffff CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vM), "[json.exception.out_of_range.408] syntax error while parsing BJData size: excessive ndarray size caused overflow", json::out_of_range&); #endif CHECK(json::from_bjdata(vM, true, false).is_discarded()); } + SECTION("optimized array: integer value overflow") + { + std::vector vL = {'[', '#', 'L', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F}; + std::vector vM = {'[', '$', 'M', '#', '[', 'I', 0x00, 0x20, 'M', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFF, ']'}; + + json _; +#if SIZE_MAX == 0xffffffff + CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vL), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&); +#endif + +#if SIZE_MAX == 0xffffffff + CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vM), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&); +#endif + } + SECTION("do not accept NTFZ markers in ndarray optimized type (with count)") { json _;