fix: 处理撤回消息解密时的500错误
撤回消息会清空content但保留key_version,新增判断跳过此类消息解密,避免整个查询窗口被毒化
This commit is contained in:
@@ -196,7 +196,9 @@ func encryptMessageContent(msg *types.Message) (*types.Message, error) {
|
||||
}
|
||||
|
||||
func decryptMessageContent(msg *types.Message) error {
|
||||
if msg == nil || msg.KeyVersion <= 0 {
|
||||
// 撤回消息的内容已被清空(recall 会把 head/content 置 NULL,但 content_nonce/key_version 残留),
|
||||
// 此类行没有密文可解,直接放行让上层按已撤回形态下发,否则整个 get data 窗口会被单条撤回消息毒化成 500。
|
||||
if msg == nil || msg.KeyVersion <= 0 || msg.Content == nil {
|
||||
return nil
|
||||
}
|
||||
entry, err := getMessageKey(msg.TenantID, msg.KeyVersion)
|
||||
|
||||
@@ -82,6 +82,27 @@ func TestMessageCryptoRejectsTampering(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 撤回消息 content 已被清 NULL,但 recall UPDATE 保留了 content_nonce/key_version;
|
||||
// 读路径解密必须跳过此类行,否则单条撤回消息会把整个 get data 窗口毒化成 500(2026-10-08 测试环境实案)。
|
||||
func TestMessageCryptoSkipsRecalledContent(t *testing.T) {
|
||||
tenantID := types.TenantID(9004)
|
||||
key := bytes.Repeat([]byte{5}, 32)
|
||||
expires := time.Now().Add(time.Minute)
|
||||
messageKeyCache.Lock()
|
||||
messageKeyCache.items[messageKeyCacheID(tenantID, 0)] = cachedMessageKey{enabled: true, version: 2, key: key, expires: expires}
|
||||
messageKeyCache.items[messageKeyCacheID(tenantID, 2)] = cachedMessageKey{enabled: true, version: 2, key: key, expires: expires}
|
||||
messageKeyCache.Unlock()
|
||||
defer InvalidateMessageEncryptionKeys(tenantID)
|
||||
|
||||
recalled := &types.Message{TenantID: tenantID, Topic: "p2p-recalled", SeqId: 64, KeyVersion: 2, ContentNonce: bytes.Repeat([]byte{1}, 12), Content: nil}
|
||||
if err := decryptMessageContent(recalled); err != nil {
|
||||
t.Fatalf("expected recalled message with nil content to be skipped, got: %v", err)
|
||||
}
|
||||
if recalled.Content != nil {
|
||||
t.Fatalf("nil content should stay nil: %#v", recalled.Content)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessageCryptoSearchMatchesDecryptedContent(t *testing.T) {
|
||||
content := map[string]any{"txt": "项目 验收通过", "nested": map[string]any{"title": "日报"}}
|
||||
if !messageContentMatchesSearch(content, "验收") {
|
||||
|
||||
Reference in New Issue
Block a user