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.
This commit is contained in:
Alan Wu 2024-06-13 17:39:17 -04:00
Родитель 2699e230e4
Коммит a8730adb60
1 изменённых файлов: 2 добавлений и 2 удалений

Просмотреть файл

@ -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;