mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-05-09 23:43:11 +02: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
|
guint
|
||||||
g_int64_hash (gconstpointer v)
|
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
|
guint
|
||||||
g_double_hash (gconstpointer v)
|
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…
x
Reference in New Issue
Block a user