getml / reflect-cpp

A C++20 library for fast serialization, deserialization and validation using reflection. Supports JSON, BSON, CBOR, flexbuffers, msgpack, TOML, XML, YAML / msgpack.org[C++20]
https://getml.github.io/reflect-cpp/
MIT License
901 stars 76 forks source link

Out of bound memory access when `std::variant` (or `Rfl::Variant`) types have arrays with same name #138

Closed tim-lyon closed 1 month ago

tim-lyon commented 1 month ago

The following code results in an out of bound memory access when reading the json. Occurs when both Foo and Bar have std::array property of the same name (v) but the arrays are of different lengths, and the shorter ones appears before the longer one in the variant.

I think it should be possible to match the types in this case, as the arrays have fixed length so only one of the types can match.

struct Foo { std::array<int, 2> v; };
struct Bar { std::array<int, 3> v; };
using FooBar = std::variant<Foo, Bar>;  // or rfl::Variant
FooBar foobar = Bar({1, 2, 3});
const auto json = rfl::json::write(foobar);  // {"v":[1,2,3]}
const auto result = rfl::json::read<FooBar>(json); // accesses std::array<int, 2>[2]

Using rfl::TaggedUnion avoids the issue.

liuzicheng1987 commented 1 month ago

Thanks for reporting this. I agree that something like this should never happen.

I will take a look tonight.

liuzicheng1987 commented 1 month ago

Resolved (https://github.com/getml/reflect-cpp/commit/1ff7f762f1f782b4b01d8f1f2a0bd3b112b0ffd4).

Thanks @tim-lyon for bringing this to my attention.