aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QUtil.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2020-04-06 16:00:05 +0200
committerJay Berkenbilt <ejb@ql.org>2020-04-06 16:00:43 +0200
commit52749b85df2e25c5ca35d5e0d07fbe4248b6f99b (patch)
tree3921e6d39c28f8d1df2590b4a05879898402b2af /libqpdf/QUtil.cc
parent619d294e9d2d9bb64c4eac62fde57096d5a84ba4 (diff)
downloadqpdf-52749b85df2e25c5ca35d5e0d07fbe4248b6f99b.tar.zst
Make random data provider code thread-safe
This uses C++-11 thread-safe static initializers now.
Diffstat (limited to 'libqpdf/QUtil.cc')
-rw-r--r--libqpdf/QUtil.cc76
1 files changed, 50 insertions, 26 deletions
diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc
index 177b49e1..fa0cf8ae 100644
--- a/libqpdf/QUtil.cc
+++ b/libqpdf/QUtil.cc
@@ -878,57 +878,81 @@ QUtil::toUTF16(unsigned long uval)
// Random data support
-static RandomDataProvider* random_data_provider = 0;
+class RandomDataProviderProvider
+{
+ public:
+ RandomDataProviderProvider();
+ void setProvider(RandomDataProvider*);
+ RandomDataProvider* getProvider();
+ private:
+ RandomDataProvider* default_provider;
+ RandomDataProvider* current_provider;
+};
+
+RandomDataProviderProvider::RandomDataProviderProvider() :
+ default_provider(0),
+ current_provider(0)
+{
#ifdef USE_INSECURE_RANDOM
-static RandomDataProvider* insecure_random_data_provider =
- InsecureRandomDataProvider::getInstance();
+ static RandomDataProvider* insecure_random_data_provider =
+ InsecureRandomDataProvider::getInstance();
#else
-static RandomDataProvider* insecure_random_data_provider = 0;
+ static RandomDataProvider* insecure_random_data_provider = 0;
#endif
-static RandomDataProvider* secure_random_data_provider =
- SecureRandomDataProvider::getInstance();
+ 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);
-static void
-initialize_random_data_provider()
-{
- if (random_data_provider == 0)
- {
- if (secure_random_data_provider)
- {
- random_data_provider = secure_random_data_provider;
- }
- else if (insecure_random_data_provider)
- {
- random_data_provider = insecure_random_data_provider;
- }
- }
// QUtil.hh has comments indicating that getRandomDataProvider(),
// 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");
}
+ 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
QUtil::setRandomDataProvider(RandomDataProvider* p)
{
- random_data_provider = p;
+ getRandomDataProviderProvider()->setProvider(p);
}
RandomDataProvider*
QUtil::getRandomDataProvider()
{
- initialize_random_data_provider();
- return random_data_provider;
+ return getRandomDataProviderProvider()->getProvider();
}
void
QUtil::initializeWithRandomBytes(unsigned char* data, size_t len)
{
- initialize_random_data_provider();
- random_data_provider->provideRandomData(data, len);
+ getRandomDataProvider()->provideRandomData(data, len);
}
long