Commit 52749b85df2e25c5ca35d5e0d07fbe4248b6f99b

Authored by Jay Berkenbilt
1 parent 619d294e

Make random data provider code thread-safe

This uses C++-11 thread-safe static initializers now.
Showing 1 changed file with 50 additions and 26 deletions
libqpdf/QUtil.cc
@@ -878,57 +878,81 @@ QUtil::toUTF16(unsigned long uval) @@ -878,57 +878,81 @@ QUtil::toUTF16(unsigned long uval)
878 878
879 // Random data support 879 // Random data support
880 880
881 -static RandomDataProvider* random_data_provider = 0; 881 +class RandomDataProviderProvider
  882 +{
  883 + public:
  884 + RandomDataProviderProvider();
  885 + void setProvider(RandomDataProvider*);
  886 + RandomDataProvider* getProvider();
882 887
  888 + private:
  889 + RandomDataProvider* default_provider;
  890 + RandomDataProvider* current_provider;
  891 +};
  892 +
  893 +RandomDataProviderProvider::RandomDataProviderProvider() :
  894 + default_provider(0),
  895 + current_provider(0)
  896 +{
883 #ifdef USE_INSECURE_RANDOM 897 #ifdef USE_INSECURE_RANDOM
884 -static RandomDataProvider* insecure_random_data_provider =  
885 - InsecureRandomDataProvider::getInstance(); 898 + static RandomDataProvider* insecure_random_data_provider =
  899 + InsecureRandomDataProvider::getInstance();
886 #else 900 #else
887 -static RandomDataProvider* insecure_random_data_provider = 0; 901 + static RandomDataProvider* insecure_random_data_provider = 0;
888 #endif 902 #endif
889 -static RandomDataProvider* secure_random_data_provider =  
890 - SecureRandomDataProvider::getInstance(); 903 + static RandomDataProvider* secure_random_data_provider =
  904 + SecureRandomDataProvider::getInstance();
  905 +
  906 + this->default_provider = (
  907 + secure_random_data_provider ? secure_random_data_provider
  908 + : insecure_random_data_provider ? insecure_random_data_provider
  909 + : 0);
891 910
892 -static void  
893 -initialize_random_data_provider()  
894 -{  
895 - if (random_data_provider == 0)  
896 - {  
897 - if (secure_random_data_provider)  
898 - {  
899 - random_data_provider = secure_random_data_provider;  
900 - }  
901 - else if (insecure_random_data_provider)  
902 - {  
903 - random_data_provider = insecure_random_data_provider;  
904 - }  
905 - }  
906 // QUtil.hh has comments indicating that getRandomDataProvider(), 911 // QUtil.hh has comments indicating that getRandomDataProvider(),
907 // which calls this method, never returns null. 912 // which calls this method, never returns null.
908 - if (random_data_provider == 0) 913 + if (this->default_provider == 0)
909 { 914 {
910 throw std::logic_error("QPDF has no random data provider"); 915 throw std::logic_error("QPDF has no random data provider");
911 } 916 }
  917 + this->current_provider = default_provider;
  918 +}
  919 +
  920 +RandomDataProvider*
  921 +RandomDataProviderProvider::getProvider()
  922 +{
  923 + return this->current_provider;
  924 +}
  925 +
  926 +void
  927 +RandomDataProviderProvider::setProvider(RandomDataProvider* p)
  928 +{
  929 + this->current_provider = p ? p : this->default_provider;
  930 +}
  931 +
  932 +static RandomDataProviderProvider*
  933 +getRandomDataProviderProvider()
  934 +{
  935 + // Thread-safe static initializer
  936 + static RandomDataProviderProvider rdpp;
  937 + return &rdpp;
912 } 938 }
913 939
914 void 940 void
915 QUtil::setRandomDataProvider(RandomDataProvider* p) 941 QUtil::setRandomDataProvider(RandomDataProvider* p)
916 { 942 {
917 - random_data_provider = p; 943 + getRandomDataProviderProvider()->setProvider(p);
918 } 944 }
919 945
920 RandomDataProvider* 946 RandomDataProvider*
921 QUtil::getRandomDataProvider() 947 QUtil::getRandomDataProvider()
922 { 948 {
923 - initialize_random_data_provider();  
924 - return random_data_provider; 949 + return getRandomDataProviderProvider()->getProvider();
925 } 950 }
926 951
927 void 952 void
928 QUtil::initializeWithRandomBytes(unsigned char* data, size_t len) 953 QUtil::initializeWithRandomBytes(unsigned char* data, size_t len)
929 { 954 {
930 - initialize_random_data_provider();  
931 - random_data_provider->provideRandomData(data, len); 955 + getRandomDataProvider()->provideRandomData(data, len);
932 } 956 }
933 957
934 long 958 long