Better exception safety during Read/Write

dependabot/npm_and_yarn/Src/WebController/UI/websocket-extensions-0.1.4
Pawel Kurowski 2020-03-13 18:26:25 +01:00
parent 16c7753e7c
commit 4a7870d0e3
3 changed files with 33 additions and 14 deletions

View File

@ -35,6 +35,9 @@ namespace FSecure
/// @return arithmetic type.
static T From(ByteView& bv)
{
if (sizeof(T) > bv.size())
throw std::out_of_range{ OBF(": Cannot read size from ByteView ") };
T ret;
memcpy(&ret, bv.data(), sizeof(T));
bv.remove_prefix(sizeof(T));

View File

@ -167,12 +167,20 @@ namespace FSecure
ByteVector& Concat(T const& arg, Ts const& ...args)
{
auto oldSize = size();
resize(oldSize + arg.size());
memcpy(data() + oldSize, arg.data(), arg.size());
if constexpr (sizeof...(Ts) != 0)
Concat(args...);
try
{
resize(oldSize + arg.size());
memcpy(data() + oldSize, arg.data(), arg.size());
if constexpr (sizeof...(Ts) != 0)
Concat(args...);
return *this;
return *this;
}
catch (...)
{
resize(oldSize);
throw;
}
}
/// Create new ByteVector with Variadic list of parameters.
@ -211,7 +219,6 @@ namespace FSecure
template<typename T, typename ...Ts, typename std::enable_if_t<std::is_same_v<decltype(FSecure::ByteConverter<T>::To(std::declval<T>())), FSecure::ByteVector >, int> = 0>
ByteVector & Store(T const& arg, Ts const& ...args)
{
Concat(FSecure::ByteConverter<T>::To(arg));
if constexpr (sizeof...(Ts) != 0)
Store(args...);

View File

@ -167,13 +167,22 @@ namespace FSecure
template<typename T, typename ...Ts, typename = decltype(FSecure::ByteConverter<Utils::RemoveCVR<T>>::From(std::declval<ByteView&>()))>
auto Read()
{
auto current = ByteConverter<Utils::RemoveCVR<T>>::From(*this);
if constexpr (sizeof...(Ts) == 0)
return current;
else if constexpr (sizeof...(Ts) == 1)
return std::make_tuple(std::move(current), Read<Ts...>());
else
return std::tuple_cat(std::make_tuple(std::move(current)), Read<Ts...>());
auto copy = *this;
try
{
auto current = ByteConverter<Utils::RemoveCVR<T>>::From(*this);
if constexpr (sizeof...(Ts) == 0)
return current;
else if constexpr (sizeof...(Ts) == 1)
return std::make_tuple(std::move(current), Read<Ts...>());
else
return std::tuple_cat(std::make_tuple(std::move(current)), Read<Ts...>());
}
catch (...)
{
*this = copy;
throw;
}
}
};
@ -233,7 +242,7 @@ namespace FSecure
/// @tparam Ts, rest of pointers to members.
/// @note T is not the same as first template parameter of Create(void).
template <typename T, typename ...Ts>
auto Create(T, Ts...) -> decltype(typename SplitMemberPointer<T>::declaringType{std::declval<typename SplitMemberPointer<T>::type>(), std::declval<typename SplitMemberPointer<Ts>::type>()... })
auto Create(T, Ts...) -> decltype(typename SplitMemberPointer<T>::declaringType{ std::declval<typename SplitMemberPointer<T>::type>(), std::declval<typename SplitMemberPointer<Ts>::type>()... })
{
return TupleToConstructor<typename SplitMemberPointer<T>::declaringType>(m_byteView.Read<typename SplitMemberPointer<T>::type, typename SplitMemberPointer<Ts>::type...>(), std::make_index_sequence<1 + sizeof...(Ts)>{});
}