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,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 |