diff options
author | Yann Collet <cyan@fb.com> | 2022-09-17 00:45:51 (GMT) |
---|---|---|
committer | Yann Collet <cyan@fb.com> | 2022-09-17 00:45:51 (GMT) |
commit | dc944197e683fc566cdc3b05b9064635bc2d8edd (patch) | |
tree | eb8528dee8a30e726fbfc992a33bc1f11b283648 | |
parent | 27c9530b757afe7915d0e0d1622f4d1089b66b3c (diff) | |
download | lz4-dc944197e683fc566cdc3b05b9064635bc2d8edd.zip lz4-dc944197e683fc566cdc3b05b9064635bc2d8edd.tar.gz lz4-dc944197e683fc566cdc3b05b9064635bc2d8edd.tar.bz2 |
fix rare ub
apparently, accessing the short member of a union
still requires enough space for its largest member.
-rw-r--r-- | lib/lz4.c | 14 |
1 files changed, 8 insertions, 6 deletions
@@ -379,14 +379,16 @@ static void LZ4_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ /* currently only defined for gcc and icc */ -typedef union { U16 u16; U32 u32; reg_t uArch; } __attribute__((packed)) LZ4_unalign; +typedef struct { U16 u16; } __attribute__((packed)) LZ4_unalign16; +typedef struct { U32 u32; } __attribute__((packed)) LZ4_unalign32; +typedef struct { reg_t uArch; } __attribute__((packed)) LZ4_unalignST; -static U16 LZ4_read16(const void* ptr) { return ((const LZ4_unalign*)ptr)->u16; } -static U32 LZ4_read32(const void* ptr) { return ((const LZ4_unalign*)ptr)->u32; } -static reg_t LZ4_read_ARCH(const void* ptr) { return ((const LZ4_unalign*)ptr)->uArch; } +static U16 LZ4_read16(const void* ptr) { return ((const LZ4_unalign16*)ptr)->u16; } +static U32 LZ4_read32(const void* ptr) { return ((const LZ4_unalign32*)ptr)->u32; } +static reg_t LZ4_read_ARCH(const void* ptr) { return ((const LZ4_unalignST*)ptr)->uArch; } -static void LZ4_write16(void* memPtr, U16 value) { ((LZ4_unalign*)memPtr)->u16 = value; } -static void LZ4_write32(void* memPtr, U32 value) { ((LZ4_unalign*)memPtr)->u32 = value; } +static void LZ4_write16(void* memPtr, U16 value) { ((LZ4_unalign16*)memPtr)->u16 = value; } +static void LZ4_write32(void* memPtr, U32 value) { ((LZ4_unalign32*)memPtr)->u32 = value; } #else /* safe and portable access using memcpy() */ |