Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions TESTING_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ Candidate-ordered parallel-index recovery tests must prove that the fatal result
Hotspot candidate-filter alignment is one public database-behavior contract across site, grouped, and file list/count queries. Keep visibility include/exclude filters before ambiguity cardinality, path include/exclude and test suppression after cardinality, authoritative family identity intact, and all six result/count shapes aligned. The structural SQL fixture separately pins the shared candidate plan to its explicit ten-column projection and forbids `SELECT *`.
Unused-candidate query coverage must keep the SQL-aware and non-SQL paths aligned on the shared 17-column projection, provisional bucket ordering, scope filters, and parameter binding. Retain one mixed C#/SQL public-behavior fixture that proves SQL reference resolution, C# projection and null fallbacks, list/count agreement, and detailed bucket counts together. A separate mixed partial-family fixture must force the resolver-aware and non-SQL routes with an SQL scope probe plus a visibility-filtered SQL control, then require result/count/detailed-count parity while the shared pre-page predicate suppresses a private member used from a peer part; keep same-file C# suppression and enum-collision scope in their focused fixtures.
Unused-symbol classification coverage must preserve surface-tag insertion order and contract-domain precedence when one symbol overlaps generated, contract-member, configuration, exception-metadata, public, and test signals. Keep those surface predicates evaluated once into the shared analysis, retain private/non-public early returns, and assert aligned reason tags, domain tags, and aggregate domain counts.
Checkpoint listing and retention fixtures should exceed the relevant directory cap once and exceed the inspected-file cap on only one checkpoint; multiplying both caps together adds filesystem work without increasing boundary coverage. Checkpoint and restore-backup cleanup dry-run tests must assert both exact deleted/retained paths and the continued existence of every candidate directory. Restore dry-run tests should inject destination free space through `DbCommandRunner.AvailableFreeSpaceForTesting`, verify manifest and regular-file path diagnostics independently, and prove that no restore staging or backup directory is created.
Checkpoint listing and retention fixtures should exceed the relevant directory cap once and exceed the inspected-file cap on only one checkpoint; multiplying both caps together adds filesystem work without increasing boundary coverage. Checkpoint and restore-backup cleanup dry-run tests must assert both exact deleted/retained paths and the continued existence of every candidate directory. Restore dry-run tests should inject destination free space through `DbCommandRunner.AvailableFreeSpaceForTesting`, verify manifest and regular-file path diagnostics independently, and prove that no restore staging or backup directory is created. Checkpoint-name coverage must round-trip representative accepted names through create and restore dry-run, reject CR, LF, CRLF, NUL, and another C0 control at create/restore/delete entry points with the shared usage contract, and prove that rejection creates no checkpoint artifacts.
WAL checkpoint contention fixtures must establish a real read transaction before a later writer commit, then lower `busy_timeout` to keep the assertion bounded without fixed sleeps. Permission/error-path coverage may throw from `DbContext.WalCheckpointTruncateExecutedForTesting`; restore the previous `AsyncLocal` value in `finally` so parallel test state cannot leak.
- `ConcurrencyTests.cs`
WAL snapshot and shared-writer stress tests. The concurrent reader/writer
Expand Down Expand Up @@ -1283,7 +1283,7 @@ dotnet test --filter "FullyQualifiedName~GitHelperTests"
hotspot candidate filter の整合性は、site / grouped / file の list / count 全6 query に共通する public database behavior 契約です。visibility include / exclude は ambiguity cardinality より前、path include / exclude と test suppression は cardinality より後に適用し、authoritative family identity と全6形状の結果・件数を一致させてください。structural SQL fixture は別途、共通 candidate plan の明示的な10列 projection と `SELECT *` 禁止を固定します。
unused candidate query の coverage では、SQL-aware / non-SQL 経路で共通の17列 projection、provisional bucket 順、scope filter、parameter binding を一致させてください。mixed C#/SQL の public behavior fixture 1つで SQL reference resolution、C# projection と null fallback、list/count の一致、詳細 bucket count をまとめて固定します。別の mixed partial-family fixture では、SQL scope probe と visibility filter で除外される SQL control によって resolver-aware / non-SQL の両経路を強制し、peer part から使用される private member を共有の page 前 predicate が抑制した状態で、result / count / detailed-count の一致を必須にしてください。same-file C# suppression と enum collision scope は焦点を絞った既存 fixture で維持します。
unused symbol classification の coverage では、1つの symbol が generated、contract member、configuration、exception metadata、public、test の各 signal に重なる場合も、surface tag の追加順と contract domain の優先順位を維持してください。これらの surface predicate は共有 analysis へ1度だけ評価し、private / non-public の early return を保ったまま、reason tag、domain tag、domain 集計件数の一致を assertion します。
checkpoint listing / retention fixture は対象の directory cap を 1 件だけ超え、inspected-file cap は 1 checkpoint だけで超えてください。両方の cap を掛け合わせても boundary coverage は増えず、filesystem work だけが増えます。checkpoint / restore-backup cleanup の dry-run test では、削除予定・保持予定の正確な path と、全候補 directory が引き続き存在することの両方を検証してください。restore dry-run test は `DbCommandRunner.AvailableFreeSpaceForTesting` で destination free space を注入し、manifest と regular-file path の diagnostic を独立に検証し、restore staging directory や backup directory が作られないことを固定します。
checkpoint listing / retention fixture は対象の directory cap を 1 件だけ超え、inspected-file cap は 1 checkpoint だけで超えてください。両方の cap を掛け合わせても boundary coverage は増えず、filesystem work だけが増えます。checkpoint / restore-backup cleanup の dry-run test では、削除予定・保持予定の正確な path と、全候補 directory が引き続き存在することの両方を検証してください。restore dry-run test は `DbCommandRunner.AvailableFreeSpaceForTesting` で destination free space を注入し、manifest と regular-file path の diagnostic を独立に検証し、restore staging directory や backup directory が作られないことを固定します。checkpoint 名の coverage では、代表的な受理名を create から restore dry-run まで round-trip し、CR、LF、CRLF、NUL、その他の C0 制御文字を create / restore / delete の全入口で共通 usage contract により拒否し、拒否時に checkpoint artifact が作られないことを証明してください。
WAL checkpoint contention fixture は後続 writer commit より先に実際の read transaction を確立し、固定 sleep を使わず assertion を bounded にするため `busy_timeout` を短くします。permission / error path の coverage では `DbContext.WalCheckpointTruncateExecutedForTesting` から exception を throw できますが、parallel test state を漏らさないよう、以前の `AsyncLocal` 値を `finally` で復元してください。
- `ConcurrencyTests.cs`
WAL snapshot と shared-writer の stress test。concurrent reader/writer snapshot
Expand Down
4 changes: 2 additions & 2 deletions USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1340,7 +1340,7 @@ Failures from `vacuum`, `backfill-fold`, `optimize` (including `index --optimize

`db schema` keeps the current full schema dump by default for support bundles. Add `--summary-only` to return only object counts, combine `--type <table|index|trigger|view>` and `--name <object>` for an exact projection, and use `--limit`, `--max-sql-chars`, and `--exclude-internal` to keep schema diagnostics bounded.

`db checkpoint --dry-run` separates source DB/WAL/SHM files and bytes from every planned output without creating the checkpoint directory. The plan includes the versioned `manifest.txt`, its SHA-256, estimated final bytes, destination/conflict status and policy, sidecar/compression/metadata policy, and remaining uncertainty. The metadata policy is `owner_only_files_and_directories` on POSIX and `inherited_windows_acls` on Windows. Execution creates a fresh plan from the current sources, verifies source metadata and SHA-256 before and after copying, verifies every output, and refuses to publish if the inputs drift. Non-regular DB/WAL/SHM inputs such as Unix FIFOs are rejected before hashing. A source database named `manifest.txt` (including an equivalent case variant on a case-insensitive filesystem) conflicts with the generated manifest, so the plan reports `ready: false` and execution refuses without creating a checkpoint. Import, checkpoint restore, and managed-backup restore create a verified standalone rollback snapshot before replacing an existing DB. `db restore-backups --list` returns each managed ID and provenance; `--restore <id>` validates its bounded manifest, SHA-256, supported schema stamp, and free space before an atomic replacement that rolls back on failure. Add `--dry-run` to perform the same validations and preview the pre-restore backup without mutation. `--no-backup` is an explicit opt-out from creating rollback material and should be reserved for cases where losing the current DB is acceptable. A checkpoint name must be a non-blank single file name of at most 128 characters: it cannot be `.` or `..`, contain a directory separator, or contain characters that the operating system rejects in file names. Invalid names are input errors (`E010_USAGE_ERROR`), not database or storage failures.
`db checkpoint --dry-run` separates source DB/WAL/SHM files and bytes from every planned output without creating the checkpoint directory. The plan includes the versioned `manifest.txt`, its SHA-256, estimated final bytes, destination/conflict status and policy, sidecar/compression/metadata policy, and remaining uncertainty. The metadata policy is `owner_only_files_and_directories` on POSIX and `inherited_windows_acls` on Windows. Execution creates a fresh plan from the current sources, verifies source metadata and SHA-256 before and after copying, verifies every output, and refuses to publish if the inputs drift. Non-regular DB/WAL/SHM inputs such as Unix FIFOs are rejected before hashing. A source database named `manifest.txt` (including an equivalent case variant on a case-insensitive filesystem) conflicts with the generated manifest, so the plan reports `ready: false` and execution refuses without creating a checkpoint. Import, checkpoint restore, and managed-backup restore create a verified standalone rollback snapshot before replacing an existing DB. `db restore-backups --list` returns each managed ID and provenance; `--restore <id>` validates its bounded manifest, SHA-256, supported schema stamp, and free space before an atomic replacement that rolls back on failure. Add `--dry-run` to perform the same validations and preview the pre-restore backup without mutation. `--no-backup` is an explicit opt-out from creating rollback material and should be reserved for cases where losing the current DB is acceptable. A checkpoint name must be a non-blank single file name of at most 128 characters: it cannot be `.` or `..`, contain a directory separator or C0 control character (including CR, LF, and NUL), or contain characters that the operating system rejects in file names. Invalid names are input errors (`E010_USAGE_ERROR` / `usage`), not database or storage failures, and are rejected before checkpoint artifacts are created.

Here, drift refusal means drift detected through the final pre-publication validation. The `uncertainty` field explicitly notes that a source can still change after that validation; the already-copied outputs remain verified against the immutable plan.

Expand Down Expand Up @@ -4880,7 +4880,7 @@ DB を read-only で開いて SQLite の `PRAGMA integrity_check` を実行し

`db schema` は support bundle 向けに、既定では従来どおり full schema dump を維持します。`--summary-only` を付けると object 件数だけを返し、`--type <table|index|trigger|view>` と `--name <object>` を組み合わせると exact projection を適用できます。schema diagnostics を小さく保つには `--limit`、`--max-sql-chars`、`--exclude-internal` を使います。

`db checkpoint --dry-run` は checkpoint directory を作らずに、source DB/WAL/SHM file と byte 数を、作成予定の全 output から分けて報告します。plan には version 付き `manifest.txt`、その SHA-256、最終 byte 数の見積もり、destination/conflict の状態と policy、sidecar/compression/metadata policy、残る不確実性が含まれます。metadata policy は POSIX では `owner_only_files_and_directories`、Windows では `inherited_windows_acls` です。実行時は現在の source から新しい plan を作成し、copy 前後の source metadata と SHA-256、および全 output を検証して、入力が変化した場合は publish を拒否します。Unix FIFO など regular file ではない DB/WAL/SHM input は hash 読み取り前に拒否します。source database 名が `manifest.txt`(case-insensitive filesystem 上の同等な大小文字違いを含む)の場合は生成 manifest と衝突するため、plan は `ready: false` を報告し、実行は checkpoint を作成せず拒否します。import、checkpoint restore、managed-backup restore は既存 DB の置換前に検証済み standalone rollback snapshot を作成します。`db restore-backups --list` は managed ID と provenance を返し、`--restore <id>` は bounded manifest、SHA-256、対応する schema stamp、free space を検証してから、失敗時に rollback する atomic replacement を実行します。`--dry-run` を付けると、同じ検証と pre-restore backup の予定を DB 無変更で確認できます。`--no-backup` は rollback material 作成の明示的な opt-out であり、現在の DB を失ってもよい場合にだけ使用してください。checkpoint 名は空白だけではない 128 文字以下の単一 file 名でなければならず、`.`、`..`、directory separator、または OS が file 名で拒否する文字は使用できません。不正な名前は database / storage 障害ではなく入力エラー (`E010_USAGE_ERROR`) として扱われます。
`db checkpoint --dry-run` は checkpoint directory を作らずに、source DB/WAL/SHM file と byte 数を、作成予定の全 output から分けて報告します。plan には version 付き `manifest.txt`、その SHA-256、最終 byte 数の見積もり、destination/conflict の状態と policy、sidecar/compression/metadata policy、残る不確実性が含まれます。metadata policy は POSIX では `owner_only_files_and_directories`、Windows では `inherited_windows_acls` です。実行時は現在の source から新しい plan を作成し、copy 前後の source metadata と SHA-256、および全 output を検証して、入力が変化した場合は publish を拒否します。Unix FIFO など regular file ではない DB/WAL/SHM input は hash 読み取り前に拒否します。source database 名が `manifest.txt`(case-insensitive filesystem 上の同等な大小文字違いを含む)の場合は生成 manifest と衝突するため、plan は `ready: false` を報告し、実行は checkpoint を作成せず拒否します。import、checkpoint restore、managed-backup restore は既存 DB の置換前に検証済み standalone rollback snapshot を作成します。`db restore-backups --list` は managed ID と provenance を返し、`--restore <id>` は bounded manifest、SHA-256、対応する schema stamp、free space を検証してから、失敗時に rollback する atomic replacement を実行します。`--dry-run` を付けると、同じ検証と pre-restore backup の予定を DB 無変更で確認できます。`--no-backup` は rollback material 作成の明示的な opt-out であり、現在の DB を失ってもよい場合にだけ使用してください。checkpoint 名は空白だけではない 128 文字以下の単一 file 名でなければならず、`.`、`..`、directory separator、C0 制御文字(CR、LF、NUL を含む)、または OS が file 名で拒否する文字は使用できません。不正な名前は checkpoint artifact の作成前に拒否され、database / storage 障害ではなく入力エラー (`E010_USAGE_ERROR` / `usage`) として扱われます。

ここで drift の拒否とは、publish 前の最終検証までに検出した drift を指します。`uncertainty` field は、その検証後にも source が変化し得ることを明示しますが、copy 済み output は immutable plan に対して検証されたままです。

Expand Down
22 changes: 22 additions & 0 deletions changelog.d/unreleased/5082.security.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
category: security
issues:
- 5082
affected:
- src/CodeIndex/Cli/DbCommandRunner.FileOperations.cs
- src/CodeIndex/Cli/DbCommandRunner.Maintenance.cs
- src/CodeIndex/Cli/DbCommandRunner.Restore.cs
- src/CodeIndex/Cli/ConsoleUi.cs
- tests/CodeIndex.Tests/DbCommandRunnerTests.cs
- tests/CodeIndex.Tests/ConsoleUiTests.cs
- USER_GUIDE.md
- TESTING_GUIDE.md
---

## English

- **Database checkpoint names now reject C0 control characters before writing artifacts (#5082)** — checkpoint creation, restore, and deletion consistently return `E010_USAGE_ERROR` / `usage` for names containing CR, LF, NUL, or any other C0 control, preventing successful creation of manifests that cannot be restored.

## 日本語

- **database checkpoint 名の C0 制御文字を artifact 作成前に拒否するようにしました (#5082)** — CR、LF、NUL、その他の C0 制御文字を含む名前に対し、checkpoint 作成・restore・delete が一貫して `E010_USAGE_ERROR` / `usage` を返し、restore 不能な manifest の作成成功を防ぎます。
1 change: 1 addition & 0 deletions src/CodeIndex/Cli/ConsoleUi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ private static readonly (string Command, string Note)[] CommandUsageNotes =
("recipes-list", "Example: `cdidx recipes list --names --json`."),
("db", "schema defaults to the full sqlite_master dump for support bundles; use --summary-only, --limit, --max-sql-chars, and --exclude-internal for bounded diagnostics."),
("db", "checkpoint --dry-run separates source DB/WAL/SHM bytes from every planned output, including the versioned manifest, its SHA-256, estimated final bytes, destination/conflict policy, and uncertainty."),
("db", "checkpoint names must be non-blank single file names of at most 128 characters and cannot contain C0 control characters, directory separators, or platform-invalid file-name characters."),
("db", "checkpoint creates a filesystem snapshot next to the DB; restore creates a verified managed rollback backup before replacing an existing DB unless --no-backup is explicit."),
("db", "restore --dry-run validates the checkpoint manifest, regular-file paths, rollback-backup policy, and destination free space without replacing the DB."),
("db", "checkpoints --delete and --prune remove snapshots; add --dry-run to report exact deleted/retained paths without mutation."),
Expand Down
Loading
Loading