Skip to content

Nested FromConfable schemas in a Map schema leads to segfault #186

Closed
@cassava

Description

@cassava

Minimum test:

template <typename T>
struct Nested : public fable::Confable {
  T value{}; // NOLINT

 public:
  CONFABLE_SCHEMA(Nested<T>) {
    return fable::Schema{
      { "v", fable::Schema(&value, "nested value") },
    };
  }
};

template <typename T>
struct MapOfSomething : public fable::Confable {
  std::map<std::string, T> values; // NOLINT

 public:
  CONFABLE_SCHEMA(MapOfSomething<T>) {
    return fable::Schema{
        {"values", fable::Schema(&values, "")},
    };
  }
};

TEST(fable_schema_map, validate_map_of_nested_3x) {
  MapOfSomething<Nested<Nested<Nested<double>>>> wrapper;

  fable::assert_validate(wrapper, R"({
    "values": {
      "a": {
        "v": { "v": { "v": 1.0 } }
      }
    }
  })");
}

Leads to output:

The following tests FAILED:
	 33 - fable_schema_map.validate_map_of_nested_3x (SEGFAULT)

With valgrind execution giving the following information:

[ RUN      ] fable_schema_map.validate_map_of_nested_3x
==354081== Use of uninitialised value of size 8
==354081==    at 0x1E69F5: fable::schema::FromConfable<(anonymous namespace)::Nested<double>, 0>::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (confable.hpp:68)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x2F740B: fable::schema::Struct::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (struct.cpp:125)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x1E92B9: fable::schema::FromConfable<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> >, 0>::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (confable.hpp:66)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x2F740B: fable::schema::Struct::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (struct.cpp:125)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x1EAB9B: fable::schema::FromConfable<(anonymous namespace)::Nested<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> > >, 0>::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (confable.hpp:66)
==354081==    by 0x1EA0CC: fable::schema::Map<(anonymous namespace)::Nested<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> > >, fable::schema::FromConfable<(anonymous namespace)::Nested<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> > >, 0> >::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (map.hpp:141)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x2F740B: fable::schema::Struct::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (struct.cpp:125)
==354081==  Uninitialised value was created by a stack allocation
==354081==    at 0x1E9C20: fable::schema::Map<(anonymous namespace)::Nested<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> > >, fable::schema::FromConfable<(anonymous namespace)::Nested<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> > >, 0> >::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (map.hpp:111)
==354081==
==354081== Invalid read of size 8
==354081==    at 0x1E69F5: fable::schema::FromConfable<(anonymous namespace)::Nested<double>, 0>::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (confable.hpp:68)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x2F740B: fable::schema::Struct::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (struct.cpp:125)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x1E92B9: fable::schema::FromConfable<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> >, 0>::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (confable.hpp:66)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x2F740B: fable::schema::Struct::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (struct.cpp:125)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x1EAB9B: fable::schema::FromConfable<(anonymous namespace)::Nested<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> > >, 0>::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (confable.hpp:66)
==354081==    by 0x1EA0CC: fable::schema::Map<(anonymous namespace)::Nested<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> > >, fable::schema::FromConfable<(anonymous namespace)::Nested<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> > >, 0> >::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (map.hpp:141)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x2F740B: fable::schema::Struct::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (struct.cpp:125)
==354081==  Address 0x1ffeff0050 is not stack'd, malloc'd or (recently) free'd
==354081==
==354081==
==354081== Process terminating with default action of signal 11 (SIGSEGV)
==354081==  Access not within mapped region at address 0x1FFEFF0050
==354081==    at 0x1E69F5: fable::schema::FromConfable<(anonymous namespace)::Nested<double>, 0>::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (confable.hpp:68)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x2F740B: fable::schema::Struct::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (struct.cpp:125)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x1E92B9: fable::schema::FromConfable<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> >, 0>::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (confable.hpp:66)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x2F740B: fable::schema::Struct::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (struct.cpp:125)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x1EAB9B: fable::schema::FromConfable<(anonymous namespace)::Nested<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> > >, 0>::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (confable.hpp:66)
==354081==    by 0x1EA0CC: fable::schema::Map<(anonymous namespace)::Nested<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> > >, fable::schema::FromConfable<(anonymous namespace)::Nested<(anonymous namespace)::Nested<(anonymous namespace)::Nested<double> > >, 0> >::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (map.hpp:141)
==354081==    by 0x1875BE: fable::schema::Box::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (interface.hpp:377)
==354081==    by 0x2F740B: fable::schema::Struct::validate(fable::Conf const&, std::optional<fable::SchemaError>&) const (struct.cpp:125)

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingc-fableDomain is the fable library

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions