mirror of
https://github.com/nginx/nginx.git
synced 2026-10-24 14:47:45 -05:00
HTTP/3: avoid unaligned stores in Huffman encoding
The encoder wrote accumulated bits by casting the destination to uint64_t *, or uint32_t * on 32-bit platforms, and assigning through it, which requires the destination to be suitably aligned. In HTTP/2 the destination is a temporary buffer from ngx_palloc() and is always aligned. In HTTP/3 it points past a variable number of prefix integer bytes, so its alignment is arbitrary and the store is undefined behaviour. Byte order conversion is now separated from the store, which is done with ngx_memcpy().
This commit is contained in:
1 parent
4953fc6f02
commit
b38c9d8068
1 file changed
+10
-22
@@ -158,32 +158,19 @@ static ngx_http_huff_encode_code_t ngx_http_huff_encode_table_lc[256] =
|
||||
|
||||
#if (NGX_PTR_SIZE == 8)
|
||||
|
||||
#if (NGX_HAVE_LITTLE_ENDIAN)
|
||||
|
||||
#if (NGX_HAVE_GCC_BSWAP64)
|
||||
#define ngx_http_huff_encode_buf(dst, buf) \
|
||||
(*(uint64_t *) (dst) = __builtin_bswap64(buf))
|
||||
#if !(NGX_HAVE_LITTLE_ENDIAN)
|
||||
#define ngx_http_huff_encode_hton(buf) (buf)
|
||||
#elif (NGX_HAVE_GCC_BSWAP64)
|
||||
#define ngx_http_huff_encode_hton(buf) __builtin_bswap64(buf)
|
||||
#else
|
||||
#define ngx_http_huff_encode_buf(dst, buf) \
|
||||
((dst)[0] = (u_char) ((buf) >> 56), \
|
||||
(dst)[1] = (u_char) ((buf) >> 48), \
|
||||
(dst)[2] = (u_char) ((buf) >> 40), \
|
||||
(dst)[3] = (u_char) ((buf) >> 32), \
|
||||
(dst)[4] = (u_char) ((buf) >> 24), \
|
||||
(dst)[5] = (u_char) ((buf) >> 16), \
|
||||
(dst)[6] = (u_char) ((buf) >> 8), \
|
||||
(dst)[7] = (u_char) (buf))
|
||||
#endif
|
||||
|
||||
#else /* !NGX_HAVE_LITTLE_ENDIAN */
|
||||
#define ngx_http_huff_encode_buf(dst, buf) \
|
||||
(*(uint64_t *) (dst) = (buf))
|
||||
#define ngx_http_huff_encode_hton(buf) \
|
||||
((uint64_t) htonl((uint32_t) (buf)) << 32 \
|
||||
| htonl((uint32_t) ((buf) >> 32)))
|
||||
#endif
|
||||
|
||||
#else /* NGX_PTR_SIZE == 4 */
|
||||
|
||||
#define ngx_http_huff_encode_buf(dst, buf) \
|
||||
(*(uint32_t *) (dst) = htonl(buf))
|
||||
#define ngx_http_huff_encode_hton(buf) htonl(buf)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -224,7 +211,8 @@ ngx_http_huff_encode(u_char *src, size_t len, u_char *dst, ngx_uint_t lower)
|
||||
|
||||
buf |= code >> pending;
|
||||
|
||||
ngx_http_huff_encode_buf(&dst[hlen], buf);
|
||||
buf = ngx_http_huff_encode_hton(buf);
|
||||
ngx_memcpy(&dst[hlen], &buf, sizeof(buf));
|
||||
|
||||
hlen += sizeof(buf);
|
||||
|
||||
|
||||
Reference in new issue
Block a user