fix: 推送 meta 用 UseNumber 保留超过 2^53 的整数

This commit is contained in:
Nixevol
2026-09-30 16:21:05 +08:00
parent aa24e974af
commit 2461bec3b6
3 changed files with 46 additions and 3 deletions
+9
View File
@@ -509,6 +509,15 @@
- 备选方案:把桶挪到 broker 层(B-09 范围)。
- 影响:开放注册后的非 send 请求也计入配额;直接调 `Submit` 的单测不再覆盖限速。
### 复审修复 C-06
1. **推送 meta 数字用 UseNumber 解码**
- 原条款:PRD F07 / D11 自定义键值送达应与提交一致。
- 实际做法:`decodeMetaJSON` 改用 `protocol.Unmarshal`(`UseNumber`),超过 2^53 的整数以 `json.Number` 保留原文再编码进推送帧。不改 `Msg.Meta` 类型与协议包。
- 原因:标准 `json.Unmarshal` 把数字变成 float64,雪花 ID 会被改掉。
- 备选方案:`Meta` 改为 `json.RawMessage` 原样输出(需改 protocol,牵动 SDK)。
- 影响:仅推送路径;入库仍是提交时的规范 JSON。
## 身份 I
### I1 2026-09-30
+35
View File
@@ -1,6 +1,7 @@
package message
import (
"bytes"
"context"
"database/sql"
"encoding/json"
@@ -742,3 +743,37 @@ func TestPushRevokedOnRecallAfterPush(t *testing.T) {
t.Fatal("expected revoked frame")
}
}
func TestPushPreservesLargeMetaInteger(t *testing.T) {
t.Parallel()
raw := `{"id":12345678901234567890}`
decoded := decodeMetaJSON(raw)
n, ok := decoded["id"].(json.Number)
if !ok || n.String() != "12345678901234567890" {
t.Fatalf("decode meta=%v", decoded)
}
e := openDeliveryEnv(t, nil)
insertEndpoint(t, e.db, "alice", "", 1, 0)
insertEndpoint(t, e.db, "bob", "", 1, 0)
e.online("bob", "c-bob")
ctx := context.Background()
req := baseSend("meta-big", "bob")
req.Meta = map[string]any{"id": json.Number("12345678901234567890")}
if _, err := e.app.Submit(ctx, "alice", port.ConnInfo{}, req); err != nil {
t.Fatal(err)
}
if err := e.app.PushPending(ctx, "bob", "c-bob"); err != nil {
t.Fatal(err)
}
found := false
for _, p := range e.down.Snapshots() {
if bytes.Contains(p.Payload, []byte("12345678901234567890")) {
found = true
break
}
}
if !found {
t.Fatalf("push payloads missing large int: %v", e.down.Snapshots())
}
}
+2 -3
View File
@@ -3,7 +3,6 @@ package message
import (
"database/sql"
"encoding/base64"
"encoding/json"
"git.asio.asia/nixevol/NixMsg/internal/protocol"
)
@@ -94,7 +93,7 @@ func (a *App) dispatchFullTx(tx *sql.Tx, seq int64, senderID, destKind, destID s
SELECT gm.endpoint_id, e.enabled
FROM group_members gm
JOIN endpoints e ON e.id = gm.endpoint_id
WHERE gm.group_id = ? AND gm.endpoint_id != ?`, destID, senderID)
WHERE gm.group_id = ? AND gm.endpoint_id != ? AND gm.joined_at <= ?`, destID, senderID, sendAt)
if qErr != nil {
return "", true, qErr
}
@@ -342,7 +341,7 @@ func decodeMetaJSON(s string) map[string]any {
return nil
}
var m map[string]any
if err := json.Unmarshal([]byte(s), &m); err != nil {
if err := protocol.Unmarshal([]byte(s), &m); err != nil {
return nil
}
return m