diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 07a024a8f..da5ede96c 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -114,7 +114,7 @@ jobs: run: cd build ; ctest -j 10 -C Debug --exclude-regex "test-unicode" --output-on-failure ci_module_cpp20: - runs-on: windows-latest + runs-on: windows-2022 steps: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - name: Run CMake (Debug) diff --git a/docs/mkdocs/docs/api/basic_json/get.md b/docs/mkdocs/docs/api/basic_json/get.md index 96fc221da..68a4fa7a0 100644 --- a/docs/mkdocs/docs/api/basic_json/get.md +++ b/docs/mkdocs/docs/api/basic_json/get.md @@ -90,10 +90,25 @@ Depends on what `json_serializer` `from_json()` method throws ## Notes -!!! danger "Undefined behavior" +!!! danger "Undefined behavior for pointers" Writing data to the pointee (overload 3) of the result yields an undefined state. +!!! danger "Undefined behavior for numeric conversions" + + Conversions between numeric types are performed by the corresponding + `from_json()` implementation using the target C++ type. When converting + between numeric types, the library does not check whether the source + value is representable by the target type. + + If the source value is outside the range of the target type, the behavior + is the same as the corresponding C++ conversion. In particular, converting + a floating-point value to an integer type that cannot represent the value + results in undefined behavior. + + See [Number conversion](../../features/types/number_handling.md#number-conversion) + for more information. + ## Examples ??? example diff --git a/docs/mkdocs/docs/api/basic_json/sax_parse.md b/docs/mkdocs/docs/api/basic_json/sax_parse.md index 530c6f85f..94e9d5495 100644 --- a/docs/mkdocs/docs/api/basic_json/sax_parse.md +++ b/docs/mkdocs/docs/api/basic_json/sax_parse.md @@ -92,7 +92,6 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va - Throws [`parse_error.102`](../../home/exceptions.md#jsonexceptionparse_error102) if `to_unicode` fails or surrogate error. - Throws [`parse_error.103`](../../home/exceptions.md#jsonexceptionparse_error103) if `to_unicode` fails. -- Throws [`other_error.502`](../../home/exceptions.md#jsonexceptionother_error502) if `sax` is a null pointer. ## Complexity @@ -125,7 +124,6 @@ A UTF-8 byte order mark is silently ignored. - Added in version 3.2.0. - Ignoring comments via `ignore_comments` added in version 3.9.0. - Added `ignore_trailing_commas` in version 3.12.1. -- Added `json.exception.other_error.502` exception in version 3.12.1. !!! warning "Deprecation" diff --git a/docs/mkdocs/docs/features/types/number_handling.md b/docs/mkdocs/docs/features/types/number_handling.md index 9102376bb..a02c1d3a9 100644 --- a/docs/mkdocs/docs/features/types/number_handling.md +++ b/docs/mkdocs/docs/features/types/number_handling.md @@ -243,6 +243,19 @@ integers, and between integers and floating-point values to integers. This behav Note the last line with throw a [`json.exception.type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) exception if `jd` is not a numerical type, for instance a string. + Numeric conversions are performed according to the corresponding C++ conversion rules. The library does not perform + range checks when converting between numeric types. + + In particular, conversions from floating-point values to integer types, or conversions to integer types with a + smaller range than the stored value, may produce implementation-defined or undefined behavior if the source value + cannot be represented by the target type. + + Applications requiring checked conversions should inspect the stored number type with + [`is_number_float()`](../../api/basic_json/is_number_float.md), + [`is_number_integer()`](../../api/basic_json/is_number_integer.md), + [`is_number_unsigned()`](../../api/basic_json/is_number_unsigned.md), or + [`type()`](../../api/basic_json/type.md), and perform explicit range checks before converting to a narrower type. + The rationale is twofold: 1. JSON does not define a number type or precision (see above). diff --git a/docs/mkdocs/mkdocs.yml b/docs/mkdocs/mkdocs.yml index c374926d2..8168bd4ff 100644 --- a/docs/mkdocs/mkdocs.yml +++ b/docs/mkdocs/mkdocs.yml @@ -270,6 +270,7 @@ nav: - macros: - 'Overview': api/macros/index.md - 'JSON_ASSERT': api/macros/json_assert.md + - 'JSON_BRACE_INIT_COPY_SEMANTICS': api/macros/json_brace_init_copy_semantics.md - 'JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER': api/macros/json_throw_user.md - 'JSON_DIAGNOSTICS': api/macros/json_diagnostics.md - 'JSON_DIAGNOSTIC_POSITIONS': api/macros/json_diagnostic_positions.md diff --git a/tests/src/unit-serialization.cpp b/tests/src/unit-serialization.cpp index c0f2a8e04..f55ed8470 100644 --- a/tests/src/unit-serialization.cpp +++ b/tests/src/unit-serialization.cpp @@ -311,14 +311,16 @@ TEST_CASE("dump for basic_json with long double number_float_t") SECTION("round-trip dump/parse") { constexpr std::array values = - {{ - 0.0L, -0.0L, 1.0L, -1.0L, - 0.5L, -0.5L, 1.5L, -2.25L, - 1.23e45L, 1.23e-45L, - (std::numeric_limits::min)(), - std::numeric_limits::lowest(), - (std::numeric_limits::max)() - }}; + { + { + 0.0L, -0.0L, 1.0L, -1.0L, + 0.5L, -0.5L, 1.5L, -2.25L, + 1.23e45L, 1.23e-45L, + (std::numeric_limits::min)(), + std::numeric_limits::lowest(), + (std::numeric_limits::max)() + } + }; for (long double v : values) {