mirror of
https://github.com/ETLCPP/etl.git
synced 2026-07-30 16:26:17 +08:00
Fix etl::bitset single-element from_string shift on empty string (#1486)
The single-element from_string overloads (char, wchar_t, char16_t, char32_t) computed element_type(1) << (string_length - 1U) before the copy loop. For an empty string, or when active_bits is 0, string_length is 0, so the shift count underflows to SIZE_MAX. Shifting by more than the element width is undefined behaviour, which also breaks constexpr evaluation. Guard the mask with a zero-length check so the shift is only performed when string_length > 0. The multi-element from_string overloads were already safe. Add test_construct_from_empty_string regression test. Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
This commit is contained in:
parent
98cb365d4c
commit
032ec4cc80
@ -311,6 +311,11 @@ namespace etl
|
|||||||
// Build from the string.
|
// Build from the string.
|
||||||
string_length = etl::min(active_bits, string_length);
|
string_length = etl::min(active_bits, string_length);
|
||||||
|
|
||||||
|
if (string_length == 0U)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
element_type mask = element_type(element_type(1) << (string_length - 1U));
|
element_type mask = element_type(element_type(1) << (string_length - 1U));
|
||||||
|
|
||||||
for (size_t i = 0U; i < string_length; ++i)
|
for (size_t i = 0U; i < string_length; ++i)
|
||||||
@ -339,6 +344,11 @@ namespace etl
|
|||||||
// Build from the string.
|
// Build from the string.
|
||||||
string_length = etl::min(active_bits, string_length);
|
string_length = etl::min(active_bits, string_length);
|
||||||
|
|
||||||
|
if (string_length == 0U)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
element_type mask = element_type(element_type(1) << (string_length - 1U));
|
element_type mask = element_type(element_type(1) << (string_length - 1U));
|
||||||
|
|
||||||
for (size_t i = 0U; i < string_length; ++i)
|
for (size_t i = 0U; i < string_length; ++i)
|
||||||
@ -367,6 +377,11 @@ namespace etl
|
|||||||
// Build from the string.
|
// Build from the string.
|
||||||
string_length = etl::min(active_bits, string_length);
|
string_length = etl::min(active_bits, string_length);
|
||||||
|
|
||||||
|
if (string_length == 0U)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
element_type mask = element_type(element_type(1) << (string_length - 1U));
|
element_type mask = element_type(element_type(1) << (string_length - 1U));
|
||||||
|
|
||||||
for (size_t i = 0U; i < string_length; ++i)
|
for (size_t i = 0U; i < string_length; ++i)
|
||||||
@ -395,6 +410,11 @@ namespace etl
|
|||||||
// Build from the string.
|
// Build from the string.
|
||||||
string_length = etl::min(active_bits, string_length);
|
string_length = etl::min(active_bits, string_length);
|
||||||
|
|
||||||
|
if (string_length == 0U)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
element_type mask = element_type(element_type(1) << (string_length - 1U));
|
element_type mask = element_type(element_type(1) << (string_length - 1U));
|
||||||
|
|
||||||
for (size_t i = 0U; i < string_length; ++i)
|
for (size_t i = 0U; i < string_length; ++i)
|
||||||
|
|||||||
@ -398,6 +398,22 @@ namespace
|
|||||||
CHECK_EQUAL(0, data.count());
|
CHECK_EQUAL(0, data.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// Empty strings exercise the string_length == 0 path in from_string,
|
||||||
|
// which must not shift by (0 - 1U).
|
||||||
|
TEST(test_construct_from_empty_string)
|
||||||
|
{
|
||||||
|
etl::bitset<64, uint64_t> data_char("");
|
||||||
|
etl::bitset<64, uint64_t> data_wchar(L"");
|
||||||
|
etl::bitset<64, uint64_t> data_u16(u"");
|
||||||
|
etl::bitset<64, uint64_t> data_u32(U"");
|
||||||
|
|
||||||
|
CHECK_EQUAL(0U, data_char.count());
|
||||||
|
CHECK_EQUAL(0U, data_wchar.count());
|
||||||
|
CHECK_EQUAL(0U, data_u16.count());
|
||||||
|
CHECK_EQUAL(0U, data_u32.count());
|
||||||
|
}
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
TEST(test_construct_from_excess_string)
|
TEST(test_construct_from_excess_string)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user