From e8bb729ac26ef97efc02d4c4e9309453149aedb8 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Thu, 13 Jun 2024 17:39:17 -0400 Subject: [PATCH] rb_str_hash(): Avoid UB with making misaligned pointer Previously, on common platforms, this code made a pointer to a union of 8 byte alignment out of a char pointer that is not guaranteed to satisfy the alignment requirement. That is undefined behavior according to [C99 6.3.2.3p7](https://port70.net/~nsz/c/c99/n1256.html#6.3.2.3p7). Use memcpy() to do the unaligned read instead. --- string.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/string.c b/string.c index de3e1c01614ac2..ab260372626f33 100644 --- a/string.c +++ b/string.c @@ -3735,8 +3735,8 @@ st_index_t rb_str_hash(VALUE str) { if (FL_TEST_RAW(str, STR_PRECOMPUTED_HASH)) { - typedef struct {char bytes[sizeof(st_index_t)];} unaligned_index; - st_index_t precomputed_hash = ((union {st_index_t i; unaligned_index b;} *)(RSTRING_END(str) + TERM_LEN(str)))->i; + st_index_t precomputed_hash; + memcpy(&precomputed_hash, RSTRING_END(str) + TERM_LEN(str), sizeof(precomputed_hash)); RUBY_ASSERT(precomputed_hash == str_do_hash(str)); return precomputed_hash;