Skip to content

std::atomic<T> Reflector bypasses domain validation present on bare T (#575 followup) #615

@RampantDespair

Description

@RampantDespair

Following up on #575, now that std::atomic<T> support has been implemented, I discovered a validation inconsistency between bare T and std::atomic<T> when going through the Reflector path.

Observed behavior

When deserializing a negative JSON number into a std::uint64_t field directly, reflect-cpp correctly rejects it. When the same field is wrapped in std::atomic<std::uint64_t>, the parse succeeds and the value silently wraps to UINT64_MAX.

Repro

#include <atomic>
#include <cstdint>

#include <gtest/gtest.h>
#include <rfl.hpp>
#include <rfl/json.hpp>

struct TestObject {
    std::uint64_t number{0};
};

struct AtomicTestObject {
    std::atomic<std::uint64_t> number{0};
};

TEST(
    ReflectCppUint,
    NegativeIntoUint64
) {
    auto req = rfl::json::read<TestObject>(R"({"number": -1})");
    EXPECT_FALSE(req.has_value());
}

TEST(
    ReflectCppUint,
    NegativeIntoAtomicUint64
) {
    auto req = rfl::json::read<rfl::Ref<AtomicTestObject>>(R"({"number": -1})");
    EXPECT_FALSE(req.has_value());
}

Test output

[17:18:37.340] [info] [tid 31448] [==========] Running 2 test(s) from 1 test suite(s).
[17:18:37.340] [info] [tid 31448] [----------] Global test environment set-up.
[17:18:37.340] [info] [tid 31448] [----------] 2 test(s) from ReflectCppUint
[17:18:37.340] [info] [tid 31448] [RUN] ReflectCppUint.NegativeIntoUint64
[17:18:37.341] [info] [tid 31448] [OK] ReflectCppUint.NegativeIntoUint64 (0 ms)
[17:18:37.341] [info] [tid 31448] [RUN] ReflectCppUint.NegativeIntoAtomicUint64
[17:18:37.341] [error] [tid 31448] ASSERT FAILED at [REDACTED]: Value of: req.has_value()
  Actual: true
Expected: false

[17:18:37.341] [info] [tid 31448] [FAILED] ReflectCppUint.NegativeIntoAtomicUint64 (0 ms)
[17:18:37.341] [info] [tid 31448] [----------] 2 test(s) from ReflectCppUint (0 ms total)
[17:18:37.341] [info] [tid 31448] [----------] Global test environment tear-down.
[17:18:37.341] [info] [tid 31448] [==========] 77 test(s) from 19 test suite(s) ran. (0 ms total)
[17:18:37.341] [info] [tid 31448] [PASSED] 1 test(s).
[17:18:37.341] [error] [tid 31448] [FAILED] 1 test(s).

Root cause (hypothesis)

The domain validation that reflect-cpp applies to bare uint64_t fields during normal struct parsing does not appear to be applied when the value is parsed through the std::atomic<T> path. The negative number passes through and the unsigned integer silently wraps.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions