registry enumeration has a bug with the key name field size and m_name_length getting out of sync.
ChrisGuzak opened this issue · comments
Chris Guzak commented
This shows a bug in the intermediate representations of the iterator. Note that passing by value works, by creating a copy and re-syncing the std::wstring size.
it seems when the size of the value name gets smaller is when this bug occurs.
it seems m_name_length
is for the bstr case and I don't have much sympathy for code that needs the value name in that format. can we simplify this and get rid of m_name_length or not use a std::wstring in this case to avoid the duplication and incoherence it creates?
// failing test. post this issue on github
TEST_METHOD(VerifyRegistryEnumeratorWorksWithByRefParameter)
{
PCWSTR subKey = LR"(BugRepro)";
auto extensionsIds = wil::reg::create_unique_key(HKEY_CURRENT_USER_LOCAL_SETTINGS, subKey, wil::reg::key_access::readwrite);
wil::reg::set_value_string(extensionsIds.get(), L"{00021401-0000-0000-C000-000000000046}", L"");
wil::reg::set_value_string(extensionsIds.get(), L"{66742402-F9B9-11D1-A202-0000F81FEDEE}", L"");
wil::reg::set_value_string(extensionsIds.get(), L"Windows.Foundation.Uri", L"");
wil::reg::set_value_string(extensionsIds.get(), L"Windows.Foundation.PropertyValue", L"");
wil::reg::set_value_string(extensionsIds.get(), L"Wrong", L"{F8F24682-0E3B-4BE3-B6F5-1EC33AFE207D}");
auto begin = wil::reg::value_iterator{ extensionsIds.get() };
auto end = wil::reg::value_iterator{};
std::for_each(begin, end, [&](auto nameAndType) // this works
{
cpp_unit::Logger::WriteMessage(nameAndType.name.c_str());
auto size = wcslen(nameAndType.name.c_str());
cpp_unit::Assert::IsTrue(size == nameAndType.name.size());
});
std::for_each(begin, end, [&](auto&& nameAndType) // this fails with the size assert below
{
cpp_unit::Logger::WriteMessage(nameAndType.name.c_str());
auto size = wcslen(nameAndType.name.c_str());
cpp_unit::Assert::IsTrue(size == nameAndType.name.size()); // failing
});
}