Description
The BJData ndarray writer validates the kind of each _ArrayData_ element (integer vs float, added in #5301) but not its range. An element that does not fit the declared _ArrayType_ is written with a wrap-around static_cast, silently corrupting the data.
In write_bjdata_ndarray (include/nlohmann/detail/output/binary_writer.hpp), each element is written as e.g. write_number(static_cast<std::uint8_t>(el.get<std::uint64_t>()), true). For _ArrayType_ = "uint8" and an element 256, the cast yields 0, so the value round-trips to a different value with no error.
This is a softer case than #5398/#5399: the documented fallback conditions (bjdata.md) require each element to be "a number of the kind named by _ArrayType_", and 256 is an integer — the docs do not currently mention range. So this is reported as a lower-severity data-integrity issue / possible doc-vs-behavior gap for the maintainer to weigh: either range-check and fall back to a plain object encoding (consistent with the other annotation-validation failures), raise an error, or document that out-of-range elements are truncated.
Reproduction steps
Serialize a uint8 ndarray whose _ArrayData_ contains a value > 255 and round-trip it.
Expected vs. actual results
- Expected: fall back to plain-object encoding (or an
out_of_range error); no silent value change.
- Actual:
256 is written as byte 0x00; the array round-trips to [1,0].
Minimal code example
#include <nlohmann/json.hpp>
#include <cstdio>
using json = nlohmann::json;
int main()
{
json j;
j["_ArrayType_"] = "uint8";
j["_ArraySize_"] = json::array({2});
j["_ArrayData_"] = json::array({1, 256}); // 256 does not fit uint8
auto v = json::to_bjdata(j);
std::printf("back=%s\n", json::from_bjdata(v).dump().c_str()); // back=[1,0]
}
Error messages
Compiler and operating system
g++ 13.3.0 (Ubuntu 24.04, x86-64)
Library version
develop @ 01853ed6bcf9ebe88ec2e248ea757b86417b1487
Validation
Description
The BJData ndarray writer validates the kind of each
_ArrayData_element (integer vs float, added in #5301) but not its range. An element that does not fit the declared_ArrayType_is written with a wrap-aroundstatic_cast, silently corrupting the data.In
write_bjdata_ndarray(include/nlohmann/detail/output/binary_writer.hpp), each element is written as e.g.write_number(static_cast<std::uint8_t>(el.get<std::uint64_t>()), true). For_ArrayType_ = "uint8"and an element256, the cast yields0, so the value round-trips to a different value with no error.This is a softer case than #5398/#5399: the documented fallback conditions (
bjdata.md) require each element to be "a number of the kind named by_ArrayType_", and256is an integer — the docs do not currently mention range. So this is reported as a lower-severity data-integrity issue / possible doc-vs-behavior gap for the maintainer to weigh: either range-check and fall back to a plain object encoding (consistent with the other annotation-validation failures), raise an error, or document that out-of-range elements are truncated.Reproduction steps
Serialize a
uint8ndarray whose_ArrayData_contains a value > 255 and round-trip it.Expected vs. actual results
out_of_rangeerror); no silent value change.256is written as byte0x00; the array round-trips to[1,0].Minimal code example
Error messages
Compiler and operating system
g++ 13.3.0 (Ubuntu 24.04, x86-64)
Library version
develop@01853ed6bcf9ebe88ec2e248ea757b86417b1487Validation
developbranch is used.