From bf58ec59f55f057cb234a5a80d28dd0ec3f8dca8 Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Mon, 7 Oct 2024 23:35:24 +0300 Subject: [PATCH] =?UTF-8?q?mdbx:=20=D0=B4=D0=BE=D0=BF=D1=83=D1=89=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=204-=D0=B1=D0=B0=D0=B9=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20=D0=B2=D1=8B=D1=80=D0=B0=D0=B2=D0=BD=D0=B8?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D1=85=20`MDBX=5FMULTIPLE`=20=D0=B4=D0=BB=D1=8F=2032-=D0=B1?= =?UTF-8?q?=D0=B8=D1=82=D0=BD=D1=8B=D1=85=20=D1=81=D0=B1=D0=BE=D1=80=D0=BE?= =?UTF-8?q?=D0=BA.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit На 32-битных платформах элементы массивов 64-битных типов могут быть выравнены на 4-байтовую границу. Из-за этого `mdbx_put(MDBX_MULTIPLE)` могла возвращать ошибку `MDBX_BAD_VALSIZE`, считая что переданные пользователем данные не выровнены. --- src/cursor.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/cursor.c b/src/cursor.c index 2d2e0fa4..0d4e1ec5 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -1569,12 +1569,19 @@ __hot int cursor_put_checklen(MDBX_cursor *mc, const MDBX_val *key, if (mc->tree->flags & MDBX_INTEGERDUP) { if (data->iov_len == 8) { if (unlikely(7 & (uintptr_t)data->iov_base)) { - if (unlikely(flags & MDBX_MULTIPLE)) - return MDBX_BAD_VALSIZE; - /* copy instead of return error to avoid break compatibility */ - aligned_data.iov_base = bcopy_8(&aligned_databytes, data->iov_base); - aligned_data.iov_len = data->iov_len; - data = &aligned_data; + if (unlikely(flags & MDBX_MULTIPLE)) { + /* LY: использование alignof(uint64_t) тут не подходил из-за ошибок + * MSVC и некоторых других компиляторов, когда для элементов + * массивов/векторов обеспечивает выравнивание только на 4-х байтовых + * границу и одновременно alignof(uint64_t) == 8. */ + if (MDBX_WORDBITS > 32 || (3 & (uintptr_t)data->iov_base) != 0) + return MDBX_BAD_VALSIZE; + } else { + /* copy instead of return error to avoid break compatibility */ + aligned_data.iov_base = bcopy_8(&aligned_databytes, data->iov_base); + aligned_data.iov_len = data->iov_len; + data = &aligned_data; + } } } else if (data->iov_len == 4) { if (unlikely(3 & (uintptr_t)data->iov_base)) {