mirror of
https://github.com/ETLCPP/etl.git
synced 2026-07-30 08:16:19 +08:00
Fix etl::mem_cast cross-size copy constructor and assignment (#1488)
The templated cross-size copy constructor and assignment operator were broken in two ways: - They accessed other.buffer / rhs.buffer, which is private in a different mem_cast instantiation, so the cross-size overloads failed to compile whenever they were actually instantiated. - They copied Size_ (the destination size) bytes from a source buffer that is only Other_Size bytes large, reading past the end of the source when the destination was larger. Use the public data() accessor and copy Other_Size bytes. The existing static_assert(Size >= Other_Size) guarantees the destination is big enough. Add test_mem_cast_copy_and_assign_from_smaller regression test. Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
This commit is contained in:
parent
165674cb23
commit
c52b2ac7b1
@ -115,7 +115,7 @@ namespace etl
|
||||
{
|
||||
ETL_STATIC_ASSERT(Size >= Other_Size, "Other size is too large");
|
||||
|
||||
memcpy(buffer, other.buffer, Size_);
|
||||
memcpy(buffer, other.data(), Other_Size);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
@ -126,7 +126,7 @@ namespace etl
|
||||
{
|
||||
ETL_STATIC_ASSERT(Size >= Other_Size, "RHS size is too large");
|
||||
|
||||
memcpy(buffer, rhs.buffer, Size_);
|
||||
memcpy(buffer, rhs.data(), Other_Size);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -152,6 +152,24 @@ namespace
|
||||
CHECK_EQUAL(3, memCast.ref<Data>().a[2]);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Cross-size copy/assignment must copy only the source's bytes and must
|
||||
// not read past the end of the (smaller) source buffer.
|
||||
TEST(test_mem_cast_copy_and_assign_from_smaller)
|
||||
{
|
||||
etl::mem_cast<sizeof(uint32_t), alignof(uint32_t)> smaller;
|
||||
smaller.assign<uint32_t>(0x12345678UL);
|
||||
|
||||
// Cross-size copy construct (destination larger than source).
|
||||
etl::mem_cast<sizeof(uint32_t) * 2U, alignof(uint32_t)> larger_copy(smaller);
|
||||
CHECK_EQUAL(0x12345678UL, larger_copy.ref<uint32_t>());
|
||||
|
||||
// Cross-size assignment (destination larger than source).
|
||||
etl::mem_cast<sizeof(uint32_t) * 2U, alignof(uint32_t)> larger_assign;
|
||||
larger_assign = smaller;
|
||||
CHECK_EQUAL(0x12345678UL, larger_assign.ref<uint32_t>());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_mem_cast_assign_type_at_dynamic_offset)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user