You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Enum can be deserialized from raw integers that don't map to enum values #714
Any integer value is accepted to deserialize enums which is imo a risky default behavior since it means enum values absolutely need to be checked after deserialization by reflect-cpp.
Reproduction of the behavior:
// Minimal repro: reflect-cpp accepts an out-of-range enum value when it is// supplied as a numeric string during the default (name-based) deserialization.//// Root cause: rfl::string_to_enum (include/rfl/enums.hpp) falls back to// static_cast<EnumType>(std::stoi(name))// whenever the string is not a known enumerator name but IS parseable as an// integer, with no check that the result is a defined enumerator.
#include<iostream>
#include<rfl.hpp>
#include<rfl/json.hpp>enumclassColor { red, green, blue }; // valid underlying values: 0, 1, 2structConfig {
Color color;
};
staticvoidtry_read(constchar* json) {
constauto res = rfl::json::read<Config>(json);
if (res) {
std::cout << "" << json << " -> ACCEPTED, color = "
<< static_cast<int>(res->color)
<< (static_cast<int>(res->color) > 2 ? " <-- OUT OF RANGE, no error!" : "")
<< "\n";
} else {
std::cout << "" << json << " -> rejected: " << res.error().what() << "\n";
}
}
intmain() {
try_read(R"({"color":"green"})"); // valid name -> accepted (1)try_read(R"({"color":"purple"})"); // invalid name -> rejected (correct)try_read(R"({"color":"5"})"); // numeric string, OOR -> WRONGLY accepted (5)try_read(R"({"color":"-1"})"); // numeric string, OOR -> WRONGLY accepted (-1)return0;
}
Outputs:
{"color":"green"} -> ACCEPTED, color = 1
{"color":"purple"} -> rejected: Failed to parse field 'color': stoi
{"color":"5"} -> ACCEPTED, color = 5 <-- OUT OF RANGE, no error!
{"color":"-1"} -> ACCEPTED, color = -1
I think ideally, the default behavior should change to not allow number or at least not out of range numbers.
If this can't be done because it would be a breaking change, a preprocessor would be a nice addition.
I don't agree that the default behaviour should be not to accept out-of-range enums, but I think we could add a processor that disallows out-of-range enums.
Activity
liuzicheng1987 commentedon Aug 22, 2026
@cacharle , yes, this is on purpose and documented behaviour:
https://rfl.getml.com/enums/#what-happens-if-an-enum-cannot-be-matched
I don't agree that the default behaviour should be not to accept out-of-range enums, but I think we could add a processor that disallows out-of-range enums.
liuzicheng1987 commentedon Aug 25, 2026
@cacharle #718
cacharle commentedon Aug 27, 2026
@liuzicheng1987 I think this is exactly what I need, thanks a lot :)
Add the EnumNamesOnly processor; resolves #714 (#718)