From 986b4a7ad9936c533d3ce03dc29d9e47ec451e48 Mon Sep 17 00:00:00 2001 From: miaobyte Date: Sun, 1 Nov 2026 22:17:39 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20SetPart=20=E8=8C=83=E5=9B=B4=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E4=B8=8E=20reserved=20=E7=A1=AC=E9=94=99=EF=BC=8C?= =?UTF-8?q?=E5=8E=9F=E5=9C=B0=E5=86=99=20body=20=E6=8C=87=E9=92=88=208=20?= =?UTF-8?q?=E5=AD=97=E8=8A=82=E5=AF=B9=E9=BD=90=E6=96=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - kvspaceSetPart:reserved key 硬错;offset 必须在 body 区 [8, 8+len), 越界直接报错,不再交给底层静默处理 - kvspaceWriteInPlace / kvspaceWriteNewPlace:body 指针 8 字节对齐改为 debug_assert(这是前条件,不是假设) 对端:kvlang #607 的 body 直写改用 head 声明长度。 Co-Authored-By: Claude Code --- src/ffi.rs | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/ffi.rs b/src/ffi.rs index 7dedc6c..665ba6c 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -528,6 +528,24 @@ pub extern "C" fn kvspaceSetPart( return 1; } let key = unsafe { cstr(key) }.to_string(); + if crate::r#const::is_reserved(&key) { + write_err(err, err_cap, "kvspace: set-part on reserved key"); + return 1; + } + /* 原地写只允许改 body [8, 8+len):读 8 字节 head 取 len,越界一律硬错, + * head/attr 不可写。 */ + let head8 = hd.kv.get_part(&key, 0, crate::headlenpow::PREFIX as u32); + let Some(body_len) = crate::headlenpow::read_len(&head8) else { + write_err(err, err_cap, "kvspace: set-part on missing key"); + return 1; + }; + let prefix = crate::headlenpow::PREFIX as u64; + if (offset as u64) < prefix + || (offset as u64 - prefix) + (buf_len as u64) > body_len + { + write_err(err, err_cap, "kvspace: set-part outside body"); + return 1; + } let data = unsafe { std::slice::from_raw_parts(buf, buf_len as usize) }; let r = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { hd.kv.set_part(&key, offset, data) @@ -614,7 +632,14 @@ pub extern "C" fn kvspaceWriteInPlace( hd.read_cache.remove(&key); hd.write_buf = existing; hd.pending_key = Some(key); - unsafe { *body = hd.write_buf.as_mut_ptr().add(head_len) }; + /* body 指针供调用方直接写 8 字节标量:对齐是前条件,不是假设。 */ + let body_ptr = unsafe { hd.write_buf.as_mut_ptr().add(head_len) }; + debug_assert_eq!( + body_ptr as usize % 8, + 0, + "kvspace: write-in-place body pointer is not 8-byte aligned" + ); + unsafe { *body = body_ptr }; 0 } @@ -656,7 +681,14 @@ pub extern "C" fn kvspaceWriteNewPlace( hd.read_cache.remove(&key); hd.write_buf = xv; hd.pending_key = Some(key); - unsafe { *body = hd.write_buf.as_mut_ptr().add(head_len) }; + /* body 指针供调用方直接写 8 字节标量:对齐是前条件,不是假设。 */ + let body_ptr = unsafe { hd.write_buf.as_mut_ptr().add(head_len) }; + debug_assert_eq!( + body_ptr as usize % 8, + 0, + "kvspace: write-new-place body pointer is not 8-byte aligned" + ); + unsafe { *body = body_ptr }; 0 }