mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-13 07:56:17 +01:00
ghash: Correctly retrieve low 32 bits of 64-bit values
Dereferencing a pointer to a 64-bit object as though it was a 32-bit object is the same as taking the least significant 32 bits on a little-endian machine, but on a big-endian machine it is the same as taking the *most* significant 32 bits, which would result in these hash functions always hashing to zero. The /hash/int64/collisions and /hash/double/collisions test-cases in glib/tests/hash.c detect this and fail. Instead, fetch the whole 64-bit quantity and do the bit-manipulation to xor the more significant half with the less significant half in an architecture-neutral way. Fixes:dd1f4f70
"Optimize g_double_hash implementation" Fixes:c1af4b2b
"Optional optimization for `g_int64_hash`" Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/2787 Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
parent
662661a8d0
commit
de7abf54c7
@ -2496,7 +2496,9 @@ g_int64_equal (gconstpointer v1,
|
||||
guint
|
||||
g_int64_hash (gconstpointer v)
|
||||
{
|
||||
return (guint) ((const guint) (*(guint64 *) v >> 32)) ^ (*(const guint *) v);
|
||||
const guint64 *bits = v;
|
||||
|
||||
return (guint) ((*bits >> 32) ^ (*bits & 0xffffffffU));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2537,5 +2539,8 @@ g_double_equal (gconstpointer v1,
|
||||
guint
|
||||
g_double_hash (gconstpointer v)
|
||||
{
|
||||
return (guint) ((const guint) (*(guint64 *) v >> 32)) ^ (*(const guint *) v);
|
||||
/* Same as g_int64_hash() */
|
||||
const guint64 *bits = v;
|
||||
|
||||
return (guint) ((*bits >> 32) ^ (*bits & 0xffffffffU));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user