ServerCommit no longer enforces required properties on JSON deserialization (regression rc.241 → rc.266)
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
調査の方向性
SIL.Harmony.Core.dll の各バージョンで ServerCommit から始め、clientId が欠落している payload に対する JsonSchemaExporter の出力とデシリアライズ動作を再現します。System.Text.Json で使用されるコンストラクター経路を比較し、rc.266 の新しいパラメーターなしコンストラクターも含めます。完了条件は、省略された必須プロパティがデシリアライズ時に再び JsonException を発生させ、必要なマテリアライズのシナリオを壊さないことです。
索引モデルが issue の本文から書いたものです。
説明
Summary
Between SIL.Harmony.Core 0.2.1-rc.241 and 0.2.1-rc.266, ServerCommit stopped enforcing its required init properties during System.Text.Json deserialization. A JSON payload that omits clientId (and even hybridDateTime) now deserializes successfully, silently defaulting ClientId to Guid.Empty, where it previously threw a JsonException.
ClientId identifies the originating client of a CRDT commit, so accepting Guid.Empty is a data-integrity concern for any endpoint that deserializes commits from clients.
Impact
Downstream, lexbox's CRDT sync endpoint POST /api/crdt/{projectId}/add deserializes ServerCommit[] straight from the request body. With rc.266 a malformed or outdated client can upload commits with a missing/empty clientId and the server will accept them instead of rejecting the request.
Root cause
ClientId is unchanged — still public required Guid ClientId { get; init; } (non-nullable, RequiredMemberAttribute present) in both versions. The only relevant IL difference is that rc.266 adds a parameterless constructor to ServerCommit:
rc.241 ServerCommit ctors: [JsonConstructor] (Guid id, HybridDateTime hybridDateTime); (Guid id)
rc.266 ServerCommit ctors: [JsonConstructor] (Guid id, HybridDateTime hybridDateTime); (Guid id); () <-- new parameterless ctor
With a parameterless constructor available, STJ constructs the object and sets init properties afterward, and it stops reporting/enforcing the required init property ClientId. This shows up both in JsonSchemaExporter output and in actual deserialization.
Reproduction
Run STJ's schema exporter and a deserialization against each package version's SIL.Harmony.Core.dll:
JsonSchemaExporter.GetJsonSchemaAsNode(opts, typeof(ServerCommit))["required"]
- rc.241 →
["Id","HybridDateTime","ClientId"] - rc.266 →
["Id","HybridDateTime"]
Deserializing a payload with clientId omitted:
{"id":"11111111-1111-1111-1111-111111111111","hybridDateTime":{...},"changeEntities":[]}
- rc.241 → throws
JsonException: ... missing required properties including: 'ClientId' - rc.266 → succeeds,
ClientId == Guid.Empty
(Note: rc.266 also no longer enforces HybridDateTime, yet the exported schema still lists it as required — the schema and the enforcement have diverged.)
Expected
Deserializing a ServerCommit that omits a required property (e.g. clientId) should fail, as it did in rc.241. If the parameterless constructor is needed (e.g. for EF/materialization), it shouldn't come at the cost of required-property enforcement during JSON deserialization.
- 主要言語
- C#
- スター
- 14
- フォーク
- 4
- 平均マージ
- 2日 16時間
- マージ済み PR(30日)
- 5
環境構築
このプロジェクトの環境構築ファイルはまだ確認していません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
sillsdev/harmony のほかの issue
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
メンテナーはふだん 1 日以内に返信
-
Data bug
難易度 4/5 3〜5日 初心者へのやさしさ 55/100
sillsdev/harmony#105 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
enhancement
難易度 3/5 1〜2日 初心者へのやさしさ 58/100
メンテナーはふだん 1 日以内に返信
-
enhancement
難易度 3/5 1〜2日 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
sillsdev/harmony の issue をすべて見る
似ている issue
-
area-ai untriaged
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
dotnet/extensions#7790 ·
メンテナーはふだん 1 日以内に返信
-
P2 testing
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
メンテナーはふだん 1 日以内に返信
-
area-Infrastructure-coreclr os-ios os-maccatalyst os-tvos untriaged
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
dotnet/runtime#134766 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
0 - Backlog Bug
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
BrighterCommand/Brighter#4444 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信