From 2461bec3b69ca33c7747abadbcff3a8f98e5aa40 Mon Sep 17 00:00:00 2001 From: Nixevol Date: Wed, 30 Sep 2026 15:04:43 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=8E=A8=E9=80=81=20meta=20=E7=94=A8=20?= =?UTF-8?q?UseNumber=20=E4=BF=9D=E7=95=99=E8=B6=85=E8=BF=87=202^53=20?= =?UTF-8?q?=E7=9A=84=E6=95=B4=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/DEVIATIONS.md | 9 +++++++ internal/app/message/delivery_test.go | 35 +++++++++++++++++++++++++++ internal/app/message/dispatch.go | 5 ++-- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/docs/DEVIATIONS.md b/docs/DEVIATIONS.md index 193c68f..2ab9575 100644 --- a/docs/DEVIATIONS.md +++ b/docs/DEVIATIONS.md @@ -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 diff --git a/internal/app/message/delivery_test.go b/internal/app/message/delivery_test.go index 0a292f2..537dffb 100644 --- a/internal/app/message/delivery_test.go +++ b/internal/app/message/delivery_test.go @@ -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()) + } +} diff --git a/internal/app/message/dispatch.go b/internal/app/message/dispatch.go index ac4c802..e68f8ee 100644 --- a/internal/app/message/dispatch.go +++ b/internal/app/message/dispatch.go @@ -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