Skip to content

4-rwirext/json/字符串值含 NUL 被截断(constructTLV 走 C 字符串) #101

Description

@miaobyte

背景

JSON 字符串值里的 NUL(码点 U+0000,JSON 源文本中写作反斜杠 + u0000)在往返后被截断,其后内容全部丢失。

实测(下文用 <NUL> 表示该码点):

[DIFF] nul-byte  in: {"v":"before<NUL>after"}  out: {"v":"before"}

成因:json.goconstructTLVchar/* kind 走 kvspaceNewChar(kind, const char *s, ...)——参数是 C 字符串,遇 NUL 终止。函数内部把 raw 追加一个终止符再传入,NUL 之后的字节到不了 kvspace。

同组其余 12 例全部无损:CJK、emoji(含 ZWJ 序列 👨‍👩‍👧‍👦)、代理对、RTL、制表/换行/回车/引号/反斜杠转义、U+0001 与 U+001F 等控制字符、10KB 长串、值中出现 ·、值中嵌 JSON 文本。所以问题出在 NUL 这一个码点上,是 ABI 用法问题而非编码问题——U+0001 能过而 U+0000 不能,正说明卡点是 C 字符串终止符而非字符集。

需求描述

字符串值应可承载任意字节序列,包括 NUL。方案文档 §5.4 已明确「字符串值(value)不受 key 字符约束,任意字符皆可」。

预期结果

含 U+0000 的字符串值无损往返;长度与字节内容逐字节相等。

方案简述

不需要 kvspace 改动——dispatch ABI 已导出带显式长度的入口:

// kvspace-durable/src/ffi.rs:497
pub extern "C" fn kvspaceNewCharByte(bytes: *const u8, len: u32,
                                     out: *mut *mut u8, out_len: *mut u32) -> c_int

nm -D /usr/lib/libkvspace.so 确认 kvspaceNewCharByte 在导出符号表中。constructTLVchar/* 分支改调它(传 raw 指针与 len(raw),不再追加终止符)即可。

需确认 NewCharByte 落盘的 kind 与 dims 约定和 NewChar 一致(char/utf8、一维、dims=[字节数]),否则会与既有落盘不兼容;同时确认 kvspace-c(shm)侧同名符号行为一致。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions