Skip to content

fix: harden input parsing and special-path handling - #1

Merged
simota merged 19 commits into
mainfrom
fix/robust-input-parsing
Sep 28, 2026
Merged

simota merged 19 commits into
mainfrom
fix/robust-input-parsing

Conversation

@simota

@simota simota commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

Summary

Hardens input/parsing boundaries found during a repository-wide defect audit:

  • reject replay duration integer overflow instead of panicking/wrapping
  • validate replay RFC3339 calendar/time/offset fields, trailing data, and nanosecond range
  • share the validated replay timestamp parser between prune and prune preview
  • reject impossible or malformed YYYY-MM-DD values in CLI pack and web tree filters
  • preserve references on lines containing unrelated invalid UTF-8 bytes
  • use Git's machine-readable NUL-delimited formats for both working-tree status and pack --diff, preserving spaces, tabs/newlines, backslashes, literal -> text, and rename/copy paths
  • make SPA hash decoding resilient to malformed percent escapes, avoid double-decoding right, and preserve encoded commas in open

Regression coverage

Added focused tests for:

  • replay duration overflow
  • invalid RFC3339 dates/times/offsets/suffixes
  • invalid absolute calendar dates
  • invalid UTF-8 reference extraction
  • NUL-delimited status path handling and rename targets
  • NUL-delimited diff name/status handling including newline paths and copy/rename pairs

Verification

Verified on GitHub Actions against the PR merge ref:

  • changed Rust files: rustfmt --check
  • cargo test --manifest-path crates/ctx-replay/Cargo.toml
  • cargo test --manifest-path crates/ctx-contract/Cargo.toml
  • cargo test --manifest-path crates/ctx-web/Cargo.toml --lib
  • cargo test --manifest-path crates/ctx-cli/Cargo.toml --bin ctx
  • cargo clippy for the affected crates
  • pnpm install --frozen-lockfile
  • pnpm check
  • pnpm build

The repository has pre-existing Clippy warnings in unrelated code, so the verification run reports them without promoting all warnings to errors. All commands above completed successfully.

A temporary PR-only verification workflow was used to run this matrix and removed from the final diff.

@simota
simota marked this pull request as ready for review September 28, 2026 07:42
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-28T07:45:56.110247Z ade40de Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@simota
simota merged commit 8d29740 into main Sep 28, 2026
@simota
simota deleted the fix/robust-input-parsing branch September 28, 2026 07:45

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ade40decc1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +96 to +99
n = n
.checked_mul(10)
.and_then(|value| value.checked_add(digit))
.ok_or_else(|| format!("replay: number {s:?} out of range"))?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the minimum signed duration

For the valid input -9223372036854775808ns, the magnitude is one greater than i64::MAX, so this positive-only accumulator now returns an out-of-range error before the sign can be applied. The documented Go-duration behavior accepts this value as i64::MIN; parse the magnitude in an unsigned/wider representation or otherwise special-case the negative boundary, and add boundary coverage alongside the overflow tests.

AGENTS.md reference: AGENTS.md:L41-L42

Useful? React with 👍 / 👎.

use super::*;

#[test]
#[test]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Register the porcelain status parser test

The second #[test] is attached to the preceding name-status test, causing that test to be registered twice, while porcelain_z_parser_preserves_special_paths_and_rename_target has no test attribute and never runs. Move this attribute to the following function so the changed-path parser actually receives the intended regression coverage.

AGENTS.md reference: AGENTS.md:L41-L42

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant