Fixing static initialization order on Windows using construct-on-first-use. (#3206)

Fix discarded out of bounds memory access.
This commit is contained in:
clemahieu 2021-04-18 13:18:09 +02:00 committed by GitHub
commit 6b994b2b71
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 48 deletions

View file

@ -5,16 +5,56 @@
#include <unordered_set>
static nano::keypair keyzero;
static nano::keypair key0;
static nano::keypair key1;
static nano::keypair key2;
static nano::keypair key3;
static auto blockzero = std::make_shared<nano::state_block> (keyzero.pub, 0, keyzero.pub, 0, 0, keyzero.prv, keyzero.pub, 0);
static auto block0 = std::make_shared<nano::state_block> (key0.pub, 0, key0.pub, nano::Gxrb_ratio, 0, key0.prv, key0.pub, 0);
static auto block1 = std::make_shared<nano::state_block> (key1.pub, 0, key1.pub, nano::Mxrb_ratio, 0, key1.prv, key1.pub, 0);
static auto block2 = std::make_shared<nano::state_block> (key2.pub, 0, key2.pub, nano::Gxrb_ratio, 0, key2.prv, key2.pub, 0);
static auto block3 = std::make_shared<nano::state_block> (key3.pub, 0, key3.pub, nano::Mxrb_ratio, 0, key3.prv, key3.pub, 0);
nano::keypair & keyzero ()
{
static nano::keypair result;
return result;
}
nano::keypair & key0 ()
{
static nano::keypair result;
return result;
}
nano::keypair & key1 ()
{
static nano::keypair result;
return result;
}
nano::keypair & key2 ()
{
static nano::keypair result;
return result;
}
nano::keypair & key3 ()
{
static nano::keypair result;
return result;
}
std::shared_ptr<nano::state_block> & blockzero ()
{
static std::shared_ptr<nano::state_block> result = std::make_shared<nano::state_block> (keyzero ().pub, 0, keyzero ().pub, 0, 0, keyzero ().prv, keyzero ().pub, 0);
return result;
}
std::shared_ptr<nano::state_block> & block0 ()
{
static std::shared_ptr<nano::state_block> result = std::make_shared<nano::state_block> (key0 ().pub, 0, key0 ().pub, nano::Gxrb_ratio, 0, key0 ().prv, key0 ().pub, 0);
return result;
}
std::shared_ptr<nano::state_block> & block1 ()
{
static std::shared_ptr<nano::state_block> result = std::make_shared<nano::state_block> (key1 ().pub, 0, key1 ().pub, nano::Mxrb_ratio, 0, key1 ().prv, key1 ().pub, 0);
return result;
}
std::shared_ptr<nano::state_block> & block2 ()
{
static std::shared_ptr<nano::state_block> result = std::make_shared<nano::state_block> (key2 ().pub, 0, key2 ().pub, nano::Gxrb_ratio, 0, key2 ().prv, key2 ().pub, 0);
return result;
}
std::shared_ptr<nano::state_block> & block3 ()
{
static std::shared_ptr<nano::state_block> result = std::make_shared<nano::state_block> (key3 ().pub, 0, key3 ().pub, nano::Mxrb_ratio, 0, key3 ().prv, key3 ().pub, 0);
return result;
}
TEST (prioritization, construction)
{
@ -27,7 +67,7 @@ TEST (prioritization, construction)
TEST (prioritization, insert_zero)
{
nano::prioritization prioritization;
prioritization.push (1000, block0);
prioritization.push (1000, block0 ());
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (1, prioritization.bucket_size (110));
}
@ -35,7 +75,7 @@ TEST (prioritization, insert_zero)
TEST (prioritization, insert_one)
{
nano::prioritization prioritization;
prioritization.push (1000, block1);
prioritization.push (1000, block1 ());
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (1, prioritization.bucket_size (100));
}
@ -43,8 +83,8 @@ TEST (prioritization, insert_one)
TEST (prioritization, insert_same_priority)
{
nano::prioritization prioritization;
prioritization.push (1000, block0);
prioritization.push (1000, block2);
prioritization.push (1000, block0 ());
prioritization.push (1000, block2 ());
ASSERT_EQ (2, prioritization.size ());
ASSERT_EQ (2, prioritization.bucket_size (110));
}
@ -52,8 +92,8 @@ TEST (prioritization, insert_same_priority)
TEST (prioritization, insert_duplicate)
{
nano::prioritization prioritization;
prioritization.push (1000, block0);
prioritization.push (1000, block0);
prioritization.push (1000, block0 ());
prioritization.push (1000, block0 ());
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (1, prioritization.bucket_size (110));
}
@ -61,11 +101,11 @@ TEST (prioritization, insert_duplicate)
TEST (prioritization, insert_older)
{
nano::prioritization prioritization;
prioritization.push (1000, block0);
prioritization.push (1100, block2);
ASSERT_EQ (block0, prioritization.top ());
prioritization.push (1000, block0 ());
prioritization.push (1100, block2 ());
ASSERT_EQ (block0 (), prioritization.top ());
prioritization.pop ();
ASSERT_EQ (block2, prioritization.top ());
ASSERT_EQ (block2 (), prioritization.top ());
prioritization.pop ();
}
@ -73,7 +113,7 @@ TEST (prioritization, pop)
{
nano::prioritization prioritization;
ASSERT_TRUE (prioritization.empty ());
prioritization.push (1000, block0);
prioritization.push (1000, block0 ());
ASSERT_FALSE (prioritization.empty ());
prioritization.pop ();
ASSERT_TRUE (prioritization.empty ());
@ -82,18 +122,18 @@ TEST (prioritization, pop)
TEST (prioritization, top_one)
{
nano::prioritization prioritization;
prioritization.push (1000, block0);
ASSERT_EQ (block0, prioritization.top ());
prioritization.push (1000, block0 ());
ASSERT_EQ (block0 (), prioritization.top ());
}
TEST (prioritization, top_two)
{
nano::prioritization prioritization;
prioritization.push (1000, block0);
prioritization.push (1, block1);
ASSERT_EQ (block0, prioritization.top ());
prioritization.push (1000, block0 ());
prioritization.push (1, block1 ());
ASSERT_EQ (block0 (), prioritization.top ());
prioritization.pop ();
ASSERT_EQ (block1, prioritization.top ());
ASSERT_EQ (block1 (), prioritization.top ());
prioritization.pop ();
ASSERT_TRUE (prioritization.empty ());
}
@ -101,17 +141,17 @@ TEST (prioritization, top_two)
TEST (prioritization, top_round_robin)
{
nano::prioritization prioritization;
prioritization.push (1000, blockzero);
ASSERT_EQ (blockzero, prioritization.top ());
prioritization.push (1000, block0);
prioritization.push (1000, block1);
prioritization.push (1100, block3);
prioritization.push (1000, blockzero ());
ASSERT_EQ (blockzero (), prioritization.top ());
prioritization.push (1000, block0 ());
prioritization.push (1000, block1 ());
prioritization.push (1100, block3 ());
prioritization.pop (); // blockzero
EXPECT_EQ (block1, prioritization.top ());
EXPECT_EQ (block1 (), prioritization.top ());
prioritization.pop ();
EXPECT_EQ (block0, prioritization.top ());
EXPECT_EQ (block0 (), prioritization.top ());
prioritization.pop ();
EXPECT_EQ (block3, prioritization.top ());
EXPECT_EQ (block3 (), prioritization.top ());
prioritization.pop ();
EXPECT_TRUE (prioritization.empty ());
}
@ -119,31 +159,31 @@ TEST (prioritization, top_round_robin)
TEST (prioritization, trim_normal)
{
nano::prioritization prioritization{ 1 };
prioritization.push (1000, block0);
prioritization.push (1100, block2);
prioritization.push (1000, block0 ());
prioritization.push (1100, block2 ());
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (block0, prioritization.top ());
ASSERT_EQ (block0 (), prioritization.top ());
}
TEST (prioritization, trim_reverse)
{
nano::prioritization prioritization{ 1 };
prioritization.push (1100, block2);
prioritization.push (1000, block0);
prioritization.push (1100, block2 ());
prioritization.push (1000, block0 ());
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (block0, prioritization.top ());
ASSERT_EQ (block0 (), prioritization.top ());
}
TEST (prioritization, trim_even)
{
nano::prioritization prioritization{ 2 };
prioritization.push (1000, block0);
prioritization.push (1100, block2);
prioritization.push (1000, block0 ());
prioritization.push (1100, block2 ());
ASSERT_EQ (1, prioritization.size ());
ASSERT_EQ (block0, prioritization.top ());
prioritization.push (1000, block1);
ASSERT_EQ (block0 (), prioritization.top ());
prioritization.push (1000, block1 ());
ASSERT_EQ (2, prioritization.size ());
ASSERT_EQ (block0, prioritization.top ());
ASSERT_EQ (block0 (), prioritization.top ());
prioritization.pop ();
ASSERT_EQ (block1, prioritization.top ());
ASSERT_EQ (block1 (), prioritization.top ());
}

View file

@ -46,7 +46,6 @@ maximum{ maximum }
{
static size_t constexpr bucket_count = 129;
buckets.resize (bucket_count);
(void)minimums[0];
nano::uint128_t minimum{ 1 };
minimums.push_back (0);
for (auto i = 1; i < bucket_count; ++i)