From a13d518fdd079aeb0bd07a0457393cca8def7f90 Mon Sep 17 00:00:00 2001 From: Akira TAGOH Date: Tue, 28 Feb 2012 12:52:25 +0900 Subject: [PATCH] Bug 41694 - FcCache functions have random-number-generator side effects Use the own random number generator state if possible. --- configure.in | 2 +- src/fccache.c | 69 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/configure.in b/configure.in index 9f671ab..06851a5 100644 --- a/configure.in +++ b/configure.in @@ -119,7 +119,7 @@ AC_TYPE_PID_T # Checks for library functions. AC_FUNC_VPRINTF AC_FUNC_MMAP -AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr strtol getopt getopt_long sysconf ftruncate chsize rand random lrand48]) +AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr strtol getopt getopt_long sysconf ftruncate chsize rand random lrand48 random_r rand_r]) # # Checks for iconv diff --git a/src/fccache.c b/src/fccache.c index c38a705..d8102d7 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -20,14 +20,18 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ - +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "fcint.h" #include "fcarch.h" #include +#include #include #include #include #include +#include #include #if defined(HAVE_MMAP) || defined(__CYGWIN__) # include @@ -307,17 +311,62 @@ struct _FcCacheSkip { static FcCacheSkip *fcCacheChains[FC_CACHE_MAX_LEVEL]; static int fcCacheMaxLevel; -#if HAVE_RANDOM -# define FcRandom() random() + +static int32_t +FcRandom(void) +{ + int32_t result; + +#if HAVE_RANDOM_R + static struct random_data fcrandbuf; + static char statebuf[256]; + static FcBool initialized = FcFalse; + + if (initialized != FcTrue) + { + initstate_r(time(NULL), statebuf, 256, &fcrandbuf); + initialized = FcTrue; + } + + random_r(&fcrandbuf, &result); +#elif HAVE_RANDOM + static char statebuf[256]; + char *state; + static FcBool initialized = FcFalse; + + if (initialized != FcTrue) + { + state = initstate(time(NULL), statebuf, 256); + initialized = FcTrue; + } + else + state = setstate(statebuf); + + result = random(); + + setstate(state); +#elif HAVE_LRAND48 + result = lrand48(); +#elif HAVE_RAND_R + static unsigned int seed = time(NULL); + + result = rand_r(&seed); +#elif HAVE_RAND + static FcBool initialized = FcFalse; + + if (initialized != FcTrue) + { + srand(time(NULL)); + initialized = FcTrue; + } + result = rand(); #else -# if HAVE_LRAND48 -# define FcRandom() lrand48() -# else -# if HAVE_RAND -# define FcRandom() rand() -# endif -# endif +# error no random number generator function available. #endif + + return result; +} + /* * Generate a random level number, distributed * so that each level is 1/4 as likely as the one before