Commit 52749b85df2e25c5ca35d5e0d07fbe4248b6f99b
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 | 878 | |
| 879 | 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 | 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 | 900 | #else |
| 887 | -static RandomDataProvider* insecure_random_data_provider = 0; | |
| 901 | + static RandomDataProvider* insecure_random_data_provider = 0; | |
| 888 | 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 | 911 | // QUtil.hh has comments indicating that getRandomDataProvider(), |
| 907 | 912 | // which calls this method, never returns null. |
| 908 | - if (random_data_provider == 0) | |
| 913 | + if (this->default_provider == 0) | |
| 909 | 914 | { |
| 910 | 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 | 940 | void |
| 915 | 941 | QUtil::setRandomDataProvider(RandomDataProvider* p) |
| 916 | 942 | { |
| 917 | - random_data_provider = p; | |
| 943 | + getRandomDataProviderProvider()->setProvider(p); | |
| 918 | 944 | } |
| 919 | 945 | |
| 920 | 946 | RandomDataProvider* |
| 921 | 947 | QUtil::getRandomDataProvider() |
| 922 | 948 | { |
| 923 | - initialize_random_data_provider(); | |
| 924 | - return random_data_provider; | |
| 949 | + return getRandomDataProviderProvider()->getProvider(); | |
| 925 | 950 | } |
| 926 | 951 | |
| 927 | 952 | void |
| 928 | 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 | 958 | long | ... | ... |