diff options
| author | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2026-01-16 14:26:48 +0900 |
|---|---|---|
| committer | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2026-01-16 14:26:48 +0900 |
| commit | d8c21d0780e0fc061a396e66d25b7b87de3108a4 (patch) | |
| tree | 3d1039aecc46da54464e9aeaf842c4197506d79e /string.c | |
| parent | 10876c271b4ced81d852f532231ff87bd14defc9 (diff) | |
merge revision(s) d209e6f1c0a93ad3ce1cc64dd165a6b67672614d: [Backport #21715]ruby_3_3
search_nonascii(): Replace UB pointer cast with memcpy
Casting a pointer to create an unaligned one is undefined behavior in C
standards. Use memcpy to express the unaligned load instead to play by
the rules.
Practically, this yields the same binary output in many situations
while fixing the crash in [Bug #21715].
Diffstat (limited to 'string.c')
| -rw-r--r-- | string.c | 16 |
1 files changed, 9 insertions, 7 deletions
@@ -545,7 +545,7 @@ VALUE rb_fs; static inline const char * search_nonascii(const char *p, const char *e) { - const uintptr_t *s, *t; + const char *s, *t; #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # if SIZEOF_UINTPTR_T == 8 @@ -589,17 +589,19 @@ search_nonascii(const char *p, const char *e) #define aligned_ptr(value) \ __builtin_assume_aligned((value), sizeof(uintptr_t)) #else -#define aligned_ptr(value) (uintptr_t *)(value) +#define aligned_ptr(value) (value) #endif s = aligned_ptr(p); - t = (uintptr_t *)(e - (SIZEOF_VOIDP-1)); + t = (e - (SIZEOF_VOIDP-1)); #undef aligned_ptr - for (;s < t; s++) { - if (*s & NONASCII_MASK) { + for (;s < t; s += sizeof(uintptr_t)) { + uintptr_t word; + memcpy(&word, s, sizeof(word)); + if (word & NONASCII_MASK) { #ifdef WORDS_BIGENDIAN - return (const char *)s + (nlz_intptr(*s&NONASCII_MASK)>>3); + return (const char *)s + (nlz_intptr(word&NONASCII_MASK)>>3); #else - return (const char *)s + (ntz_intptr(*s&NONASCII_MASK)>>3); + return (const char *)s + (ntz_intptr(word&NONASCII_MASK)>>3); #endif } } |
