1
0
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:
Nick Wellnhofer
2023-09-16 19:08:10 +02:00
parent 42a0bc6d96
commit 1425d8f67b
3 changed files with 78 additions and 64 deletions

135
dict.c
View File

@@ -122,16 +122,6 @@ struct _xmlDict {
*/ */
static xmlMutex xmlDictMutex; 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: * xmlInitializeDict:
* *
@@ -146,64 +136,11 @@ xmlInitializeDict(void) {
/** /**
* xmlInitializeDict: * 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 void
xmlInitDictInternal(void) { xmlInitDictInternal(void) {
int var;
xmlInitMutex(&xmlDictMutex); 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); 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
}

View File

@@ -47,6 +47,11 @@ XML_HIDDEN void
xmlInitDictInternal(void); xmlInitDictInternal(void);
XML_HIDDEN void XML_HIDDEN void
xmlCleanupDictInternal(void); xmlCleanupDictInternal(void);
XML_HIDDEN void
xmlInitRandom(void);
XML_HIDDEN void
xmlCleanupRandom(void);
XML_HIDDEN unsigned XML_HIDDEN unsigned
xmlRandom(void); xmlRandom(void);

View File

@@ -586,6 +586,7 @@ xmlInitParser(void) {
xmlInitMemoryInternal(); /* Should come second */ xmlInitMemoryInternal(); /* Should come second */
xmlInitGlobalsInternal(); xmlInitGlobalsInternal();
xmlInitRandom();
xmlInitDictInternal(); xmlInitDictInternal();
xmlInitEncodingInternal(); xmlInitEncodingInternal();
#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) #if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
@@ -650,6 +651,7 @@ xmlCleanupParser(void) {
#endif #endif
xmlCleanupDictInternal(); xmlCleanupDictInternal();
xmlCleanupRandom();
xmlCleanupGlobalsInternal(); xmlCleanupGlobalsInternal();
/* /*
* Must come last. On Windows, xmlCleanupGlobalsInternal can call * Must come last. On Windows, xmlCleanupGlobalsInternal can call