-
Notifications
You must be signed in to change notification settings - Fork 236
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
Add support for different inputs to wil::reg::set_value_binary #399
Comments
Just realized that you can't call the throwing version without passing a |
OK, so I'll add support for this: Spanlikes of PODs - generally, anything that can has a PODs - can have its address taken and has a fixed size. Convertable to a span-like with addressof/sizeof. Can probably get this to also remove the direct dependency on vector's existence. |
OK, got this far so far as a prototype. My template-fu is breaking down, I can't get the detectoid to block #include <vector>
#include <string>
#include <array>
struct MyData {
int a;
int b;
};
void set_value(void const *ptr, size_t size);
template<typename Q> using always_false = std::false_type;
template<typename Q> void set(Q const& q)
{
constexpr bool is_span_like = requires {
{ *q.data() };
{ q.size() };
};
if constexpr (is_span_like)
{
static_assert(std::is_pod_v<std::decay_t<decltype(*q.data())>>);
static_assert(!std::is_pointer_v<decltype(*q.data())>);
set_value(q.data(), q.size() * sizeof(*q.data()));
}
else if constexpr (std::is_array_v<Q>)
{
static_assert(!std::is_pointer_v<std::remove_all_extents_t<Q>>);
set_value(q, sizeof(q));
}
else if constexpr (std::is_pod_v<Q>)
{
set_value(std::addressof(q), sizeof(q));
}
else
{
static_assert(always_false<Q>());
}
}
void should_work()
{
set(std::vector<int>{1, 2, 3});
set(std::vector<float>{0.5f, 2.1f, 0.3f, 10.0f});
set(std::vector<MyData>{{6, 7}});
set(std::array<int, 3>{1,2,3});
set(int(3));
set(float{3});
set(MyData{1, 2});
MyData r[] = {{3, 4}, {5, 6}};
set(r);
}
void does_not_work()
{
// Reasoning: wstring is "complex"
// set(std::vector<std::wstring>{L"kittens", L"puppies"});
// Reasoning: int* is not POD and not safely blittable into binary
// int* p[2]{};
// set(p);
set(std::array<int*, 3>{nullptr, nullptr, nullptr});
set(std::vector<MyData*>{});
}
void should_probably_not_work_2()
{
set(std::wstring(L"puppies"));
} |
Are POD types portably (de)serializable? I'd be very worried about supporting any type other than a pure list of bytes; you'd probably want to use capnproto or protobufs as an intermediate, right? It seems very easy to write something that seems secure but is not. e.g. what about endianness? buffer overruns? eek
Plus: because there's no ordering or structuring to the data type, I can easily imagine folks changing member ordering and blowing up their whole "deserialization" pipeline. This seems like a big footgun. |
I'd like to be able to pass data in formats other than std::vector<uint8_t> as input to binary registry data.
While I can write this
This is not supported
I'd also like to be able to do this.
or some support void*/size_t as the input.
The text was updated successfully, but these errors were encountered: