mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-10-24 13:33:01 +03:00
dict: Separate RNG code
This commit is contained in:
135
dict.c
135
dict.c
@@ -122,16 +122,6 @@ struct _xmlDict {
|
||||
*/
|
||||
static xmlMutex xmlDictMutex;
|
||||
|
||||
/*
|
||||
* Internal data for random function, protected by xmlDictMutex
|
||||
*/
|
||||
static unsigned globalRngState[2];
|
||||
|
||||
#ifdef XML_THREAD_LOCAL
|
||||
XML_THREAD_LOCAL static int localRngInitialized = 0;
|
||||
XML_THREAD_LOCAL static unsigned localRngState[2];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* xmlInitializeDict:
|
||||
*
|
||||
@@ -146,64 +136,11 @@ xmlInitializeDict(void) {
|
||||
/**
|
||||
* xmlInitializeDict:
|
||||
*
|
||||
* Initialize mutex and global PRNG seed.
|
||||
* Initialize mutex.
|
||||
*/
|
||||
#ifdef __clang__
|
||||
ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
|
||||
ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
|
||||
#endif
|
||||
void
|
||||
xmlInitDictInternal(void) {
|
||||
int var;
|
||||
|
||||
xmlInitMutex(&xmlDictMutex);
|
||||
|
||||
/* TODO: Get seed values from system PRNG */
|
||||
|
||||
globalRngState[0] = (unsigned) time(NULL) ^
|
||||
HASH_ROL((unsigned) (size_t) &xmlInitializeDict, 8);
|
||||
globalRngState[1] = HASH_ROL((unsigned) (size_t) &xmlDictMutex, 16) ^
|
||||
HASH_ROL((unsigned) (size_t) &var, 24);
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
|
||||
ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
|
||||
#endif
|
||||
static unsigned
|
||||
xoroshiro64ss(unsigned *s) {
|
||||
unsigned s0 = s[0];
|
||||
unsigned s1 = s[1];
|
||||
unsigned result = HASH_ROL(s0 * 0x9E3779BB, 5) * 5;
|
||||
|
||||
s1 ^= s0;
|
||||
s[0] = HASH_ROL(s0, 26) ^ s1 ^ (s1 << 9);
|
||||
s[1] = HASH_ROL(s1, 13);
|
||||
|
||||
return(result & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
unsigned
|
||||
xmlRandom(void) {
|
||||
#ifdef XML_THREAD_LOCAL
|
||||
if (!localRngInitialized) {
|
||||
xmlMutexLock(&xmlDictMutex);
|
||||
localRngState[0] = xoroshiro64ss(globalRngState);
|
||||
localRngState[1] = xoroshiro64ss(globalRngState);
|
||||
localRngInitialized = 1;
|
||||
xmlMutexUnlock(&xmlDictMutex);
|
||||
}
|
||||
|
||||
return(xoroshiro64ss(localRngState));
|
||||
#else
|
||||
unsigned ret;
|
||||
|
||||
xmlMutexLock(&xmlDictMutex);
|
||||
ret = xoroshiro64ss(globalRngState);
|
||||
xmlMutexUnlock(&xmlDictMutex);
|
||||
|
||||
return(ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1288,3 +1225,73 @@ xmlDictGetUsage(xmlDictPtr dict) {
|
||||
return(limit);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pseudo-random generator
|
||||
*/
|
||||
|
||||
static xmlMutex xmlRngMutex;
|
||||
|
||||
static unsigned globalRngState[2];
|
||||
|
||||
#ifdef XML_THREAD_LOCAL
|
||||
XML_THREAD_LOCAL static int localRngInitialized = 0;
|
||||
XML_THREAD_LOCAL static unsigned localRngState[2];
|
||||
#endif
|
||||
|
||||
ATTRIBUTE_NO_SANITIZE_INTEGER
|
||||
void
|
||||
xmlInitRandom(void) {
|
||||
int var;
|
||||
|
||||
xmlInitMutex(&xmlRngMutex);
|
||||
|
||||
/* TODO: Get seed values from system PRNG */
|
||||
|
||||
globalRngState[0] = (unsigned) time(NULL) ^
|
||||
HASH_ROL((unsigned) (size_t) &xmlInitRandom, 8);
|
||||
globalRngState[1] = HASH_ROL((unsigned) (size_t) &xmlRngMutex, 16) ^
|
||||
HASH_ROL((unsigned) (size_t) &var, 24);
|
||||
}
|
||||
|
||||
void
|
||||
xmlCleanupRandom(void) {
|
||||
xmlCleanupMutex(&xmlRngMutex);
|
||||
}
|
||||
|
||||
ATTRIBUTE_NO_SANITIZE_INTEGER
|
||||
static unsigned
|
||||
xoroshiro64ss(unsigned *s) {
|
||||
unsigned s0 = s[0];
|
||||
unsigned s1 = s[1];
|
||||
unsigned result = HASH_ROL(s0 * 0x9E3779BB, 5) * 5;
|
||||
|
||||
s1 ^= s0;
|
||||
s[0] = HASH_ROL(s0, 26) ^ s1 ^ (s1 << 9);
|
||||
s[1] = HASH_ROL(s1, 13);
|
||||
|
||||
return(result & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
unsigned
|
||||
xmlRandom(void) {
|
||||
#ifdef XML_THREAD_LOCAL
|
||||
if (!localRngInitialized) {
|
||||
xmlMutexLock(&xmlRngMutex);
|
||||
localRngState[0] = xoroshiro64ss(globalRngState);
|
||||
localRngState[1] = xoroshiro64ss(globalRngState);
|
||||
localRngInitialized = 1;
|
||||
xmlMutexUnlock(&xmlRngMutex);
|
||||
}
|
||||
|
||||
return(xoroshiro64ss(localRngState));
|
||||
#else
|
||||
unsigned ret;
|
||||
|
||||
xmlMutexLock(&xmlRngMutex);
|
||||
ret = xoroshiro64ss(globalRngState);
|
||||
xmlMutexUnlock(&xmlRngMutex);
|
||||
|
||||
return(ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,11 @@ XML_HIDDEN void
|
||||
xmlInitDictInternal(void);
|
||||
XML_HIDDEN void
|
||||
xmlCleanupDictInternal(void);
|
||||
|
||||
XML_HIDDEN void
|
||||
xmlInitRandom(void);
|
||||
XML_HIDDEN void
|
||||
xmlCleanupRandom(void);
|
||||
XML_HIDDEN unsigned
|
||||
xmlRandom(void);
|
||||
|
||||
|
||||
@@ -586,6 +586,7 @@ xmlInitParser(void) {
|
||||
|
||||
xmlInitMemoryInternal(); /* Should come second */
|
||||
xmlInitGlobalsInternal();
|
||||
xmlInitRandom();
|
||||
xmlInitDictInternal();
|
||||
xmlInitEncodingInternal();
|
||||
#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
|
||||
@@ -650,6 +651,7 @@ xmlCleanupParser(void) {
|
||||
#endif
|
||||
|
||||
xmlCleanupDictInternal();
|
||||
xmlCleanupRandom();
|
||||
xmlCleanupGlobalsInternal();
|
||||
/*
|
||||
* Must come last. On Windows, xmlCleanupGlobalsInternal can call
|
||||
|
||||
Reference in New Issue
Block a user