2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-06-15 16:42:19 +00:00

Make random data provider code thread-safe

This uses C++-11 thread-safe static initializers now.
This commit is contained in:
Jay Berkenbilt 2020-04-06 10:00:05 -04:00
parent 619d294e9d
commit 52749b85df

View File

@ -878,57 +878,81 @@ QUtil::toUTF16(unsigned long uval)
// Random data support // Random data support
static RandomDataProvider* random_data_provider = 0; class RandomDataProviderProvider
#ifdef USE_INSECURE_RANDOM
static RandomDataProvider* insecure_random_data_provider =
InsecureRandomDataProvider::getInstance();
#else
static RandomDataProvider* insecure_random_data_provider = 0;
#endif
static RandomDataProvider* secure_random_data_provider =
SecureRandomDataProvider::getInstance();
static void
initialize_random_data_provider()
{ {
if (random_data_provider == 0) public:
{ RandomDataProviderProvider();
if (secure_random_data_provider) void setProvider(RandomDataProvider*);
{ RandomDataProvider* getProvider();
random_data_provider = secure_random_data_provider;
} private:
else if (insecure_random_data_provider) RandomDataProvider* default_provider;
{ RandomDataProvider* current_provider;
random_data_provider = insecure_random_data_provider; };
}
} RandomDataProviderProvider::RandomDataProviderProvider() :
default_provider(0),
current_provider(0)
{
#ifdef USE_INSECURE_RANDOM
static RandomDataProvider* insecure_random_data_provider =
InsecureRandomDataProvider::getInstance();
#else
static RandomDataProvider* insecure_random_data_provider = 0;
#endif
static RandomDataProvider* secure_random_data_provider =
SecureRandomDataProvider::getInstance();
this->default_provider = (
secure_random_data_provider ? secure_random_data_provider
: insecure_random_data_provider ? insecure_random_data_provider
: 0);
// QUtil.hh has comments indicating that getRandomDataProvider(), // QUtil.hh has comments indicating that getRandomDataProvider(),
// which calls this method, never returns null. // which calls this method, never returns null.
if (random_data_provider == 0) if (this->default_provider == 0)
{ {
throw std::logic_error("QPDF has no random data provider"); throw std::logic_error("QPDF has no random data provider");
} }
this->current_provider = default_provider;
}
RandomDataProvider*
RandomDataProviderProvider::getProvider()
{
return this->current_provider;
}
void
RandomDataProviderProvider::setProvider(RandomDataProvider* p)
{
this->current_provider = p ? p : this->default_provider;
}
static RandomDataProviderProvider*
getRandomDataProviderProvider()
{
// Thread-safe static initializer
static RandomDataProviderProvider rdpp;
return &rdpp;
} }
void void
QUtil::setRandomDataProvider(RandomDataProvider* p) QUtil::setRandomDataProvider(RandomDataProvider* p)
{ {
random_data_provider = p; getRandomDataProviderProvider()->setProvider(p);
} }
RandomDataProvider* RandomDataProvider*
QUtil::getRandomDataProvider() QUtil::getRandomDataProvider()
{ {
initialize_random_data_provider(); return getRandomDataProviderProvider()->getProvider();
return random_data_provider;
} }
void void
QUtil::initializeWithRandomBytes(unsigned char* data, size_t len) QUtil::initializeWithRandomBytes(unsigned char* data, size_t len)
{ {
initialize_random_data_provider(); getRandomDataProvider()->provideRandomData(data, len);
random_data_provider->provideRandomData(data, len);
} }
long long