@@ -24,10 +24,14 @@ #include #ifdef OF_APPLE_RUNTIME # include #endif + +#ifdef HAVE_GETRANDOM +# include +#endif #import "OFObject.h" #import "OFArray.h" #import "OFLocale.h" #import "OFMethodSignature.h" @@ -113,10 +117,85 @@ of_hash_seed_ref(void) { return &of_hash_seed; } #endif + +#if !defined(HAVE_ARC4RANDOM) && !defined(HAVE_GETRANDOM) +static void +initRandom(void) +{ + struct timeval tv; + +# ifdef HAVE_RANDOM + gettimeofday(&tv, NULL); + srandom((unsigned)(tv.tv_sec ^ tv.tv_usec)); +# else + gettimeofday(&tv, NULL); + srand((unsigned)(tv.tv_sec ^ tv.tv_usec)); +# endif +} +#endif + +uint16_t +of_random16(void) +{ +#if defined(HAVE_ARC4RANDOM) + return arc4random(); +#elif defined(HAVE_GETRANDOM) + uint16_t buffer; + + OF_ENSURE(getrandom(&buffer, sizeof(buffer), 0) == sizeof(buffer)); + + return buffer; +#else + static of_once_t onceControl = OF_ONCE_INIT; + + of_once(&onceControl, initRandom); +# ifdef HAVE_RANDOM + return random() & 0xFFFF; +# else + return rand() & 0xFFFF; +# endif +#endif +} + +uint32_t +of_random32(void) +{ +#if defined(HAVE_ARC4RANDOM) + return arc4random(); +#elif defined(HAVE_GETRANDOM) + uint32_t buffer; + + OF_ENSURE(getrandom(&buffer, sizeof(buffer), 0) == sizeof(buffer)); + + return buffer; +#else + return ((uint32_t)of_random16() << 16) | of_random16(); +#endif +} + +uint64_t +of_random64(void) +{ +#if defined(HAVE_ARC4RANDOM_BUF) + uint64_t buffer; + + arc4random_buf(&buffer, sizeof(buffer)); + + return buffer; +#elif defined(HAVE_GETRANDOM) + uint64_t buffer; + + OF_ENSURE(getrandom(&buffer, sizeof(buffer), 0) == sizeof(buffer)); + + return buffer; +#else + return ((uint64_t)of_random32() << 32) | of_random32(); +#endif +} static const char * typeEncodingForSelector(Class class, SEL selector) { Method method; @@ -262,12 +341,17 @@ #endif objc_setEnumerationMutationHandler(enumerationMutationHandler); do { - of_hash_seed = of_random(); + of_hash_seed = of_random32(); } while (of_hash_seed == 0); + +#ifdef OF_OBJFW_RUNTIME + objc_setTaggedPointerSecret(sizeof(uintptr_t) == 4 + ? (uintptr_t)of_random32() : (uintptr_t)of_random64()); +#endif } + (void)unload { }