Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[struct_pack][bugfix] fix broken container size cause program crash #509

Merged
merged 3 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 8 additions & 18 deletions include/ylt/struct_pack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,26 +309,16 @@ template <uint64_t conf = sp_config::DEFAULT, typename T, typename... Args,
auto old_pos = reader.tellg();
auto ret = in.deserialize_with_len(consume_len, t, args...);
std::size_t delta = reader.tellg() - old_pos;
if SP_LIKELY (ret == errc{}) {
if SP_LIKELY (consume_len > 0) {
if SP_UNLIKELY (delta > consume_len) {
ret = struct_pack::errc::invalid_buffer;
if constexpr (struct_pack::seek_reader_t<Reader>)
if SP_UNLIKELY (!reader.seekg(old_pos)) {
return struct_pack::errc::seek_failed;
}
}
else {
reader.ignore(consume_len - delta);
}
if SP_LIKELY (consume_len > 0) {
if SP_UNLIKELY (delta > consume_len) {
// TODO test this branch
ret = struct_pack::errc::invalid_buffer;
}
else {
reader.ignore(consume_len - delta);
}
}
else {
if constexpr (struct_pack::seek_reader_t<Reader>)
if SP_UNLIKELY (!reader.seekg(old_pos)) {
return struct_pack::errc::seek_failed;
}
}

return ret;
}
#if __cpp_concepts >= 201907L
Expand Down
3 changes: 1 addition & 2 deletions include/ylt/struct_pack/error_code.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ enum class errc {
no_buffer_space,
invalid_buffer,
hash_conflict,
seek_failed,
too_width_size
invalid_width_of_container_length,
};

namespace detail {
Expand Down
55 changes: 46 additions & 9 deletions include/ylt/struct_pack/reflection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,6 @@ concept view_reader_t = reader_t<T> && requires(T t) {
{ t.read_view(std::size_t{}) } -> std::convertible_to<const char *>;
};

template <typename T>
concept seek_reader_t = reader_t<T> && requires(T t) {
t.seekg(std::size_t{});
};

#else

template <typename T, typename = void>
Expand Down Expand Up @@ -147,17 +142,59 @@ struct view_reader_t_impl<

template <typename T>
constexpr bool view_reader_t = reader_t<T> &&view_reader_t_impl<T>::value;
#endif

#if __cpp_concepts >= 201907L

template <typename T>
concept check_reader_t = reader_t<T> && requires(T t) {
t.check(std::size_t{});
};

template <typename T>
concept can_reserve = requires(T t) {
t.reserve(std::size_t{});
};

template <typename T>
concept can_shrink_to_fit = requires(T t) {
t.shrink_to_fit();
};

#else

template <typename T, typename = void>
struct check_reader_t_impl : std::false_type {};

template <typename T>
struct check_reader_t_impl<
T, std::void_t<decltype(std::declval<T>().check(std::size_t{}))>>
: std::true_type {};

template <typename T>
constexpr bool check_reader_t = reader_t<T> &&check_reader_t_impl<T>::value;

template <typename T, typename = void>
struct can_reserve_impl : std::false_type {};

template <typename T>
struct can_reserve_impl<
T, std::void_t<decltype(std::declval<T>().reserve(std::size_t{}))>>
: std::true_type {};

template <typename T>
constexpr bool can_reserve = can_reserve_impl<T>::value;

template <typename T, typename = void>
struct seek_reader_t_impl : std::false_type {};
struct can_shrink_to_fit_impl : std::false_type {};

template <typename T>
struct seek_reader_t_impl<
T, std::void_t<decltype(std::declval<T>().seekg(std::size_t{}))>>
struct can_shrink_to_fit_impl<
T, std::void_t<decltype(std::declval<T>().shrink_to_fit())>>
: std::true_type {};

template <typename T>
constexpr bool seek_reader_t = reader_t<T> &&seek_reader_t_impl<T>::value;
constexpr bool can_shrink_to_fit = can_shrink_to_fit_impl<T>::value;

#endif

Expand Down
Loading
Loading