Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

ServerCommit no longer enforces required properties on JSON deserialization (regression rc.241 → rc.266)

オープン
#104 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
55/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
静か
技術スタック
csharp
領域
api, backend

調査の方向性

SIL.Harmony.Core.dll の各バージョンで ServerCommit から始め、clientId が欠落している payload に対する JsonSchemaExporter の出力とデシリアライズ動作を再現します。System.Text.Json で使用されるコンストラクター経路を比較し、rc.266 の新しいパラメーターなしコンストラクターも含めます。完了条件は、省略された必須プロパティがデシリアライズ時に再び JsonException を発生させ、必要なマテリアライズのシナリオを壊さないことです。

索引モデルが issue の本文から書いたものです。

説明

bug

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 を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

sillsdev/harmony のほかの issue

sillsdev/harmony の issue をすべて見る

似ている issue

C# の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。