Skip to content

Commit

Permalink
fix: msgpack stack blowups on schema gen (#2259)
Browse files Browse the repository at this point in the history
  • Loading branch information
ludamad authored Sep 13, 2023
1 parent 9fc3f3d commit 1afc566
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,19 @@ template <typename T, typename... Args> std::string check_memory_span(T* obj, Ar
return {};
}

template <msgpack_concepts::HasMsgPack T> std::string check_msgpack_method(T& object)
template <msgpack_concepts::HasMsgPack T> std::string check_msgpack_method(const T& object)
{
std::string result;
auto checker = [&](auto&... values) { result = check_memory_span(&object, &values...); };
object.msgpack([&](auto&... keys_and_values) { std::apply(checker, drop_keys(std::tie(keys_and_values...))); });
const_cast<T&>(object).msgpack( // NOLINT
[&](auto&... keys_and_values) { std::apply(checker, drop_keys(std::tie(keys_and_values...))); });
return result;
}
void check_msgpack_usage(auto object)
void check_msgpack_usage(const auto& object)
{
std::string result = check_msgpack_method(object);
if (!result.empty()) {
throw_or_abort(result);
}
}
} // namespace msgpack
} // namespace msgpack
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ struct MsgpackSchemaPacker : msgpack::packer<msgpack::sbuffer> {

// Note: if this fails to compile, check first in list of template Arg's
// it may need a msgpack_schema_pack specialization (particularly if it doesn't define MSGPACK_FIELDS).
(_msgpack_schema_pack(*this, Args{}), ...); /* pack schemas of all template Args */
(_msgpack_schema_pack(*this, *std::make_unique<Args>()), ...); /* pack schemas of all template Args */
}
/**
* @brief Encode a type that defines msgpack based on its key value pairs.
Expand Down Expand Up @@ -108,7 +108,10 @@ concept SchemaPackable = requires(T value, MsgpackSchemaPacker packer) { msgpack

// Helper for packing (key, value, key, value, ...) arguments
template <typename Value, typename... Rest>
inline void _schema_pack_map_content(MsgpackSchemaPacker& packer, std::string key, Value value, Rest... rest)
inline void _schema_pack_map_content(MsgpackSchemaPacker& packer,
std::string key,
const Value& value,
const Rest&... rest)
{
static_assert(
msgpack_concepts::SchemaPackable<Value>,
Expand Down Expand Up @@ -200,7 +203,9 @@ inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, std::array<T, N> co
packer.pack("array");
// That has a size 2 tuple as its 2nd arg
packer.pack_array(2); /* param list format for consistency*/
_msgpack_schema_pack(packer, T{});
// To avoid WASM problems with large stack objects, we use a heap allocation.
// Small note: This works because make_unique goes of scope only when the whole line is done.
_msgpack_schema_pack(packer, *std::make_unique<T>());
packer.pack(N);
}

Expand Down

0 comments on commit 1afc566

Please sign in to comment.