[PR #2107] [MERGED] fix(native): preserve literal line breaks in signing identifiers #5032

Closed
opened 2026-10-31 00:59:23 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/2107
Author: @1NormalGuy
Created: 10/12/2026
Status: ✅ Merged
Merged: 10/13/2026
Merged by: @morluto

Base: main ← Head: fix/codesign-literal-line-breaks


📝 Commits (2)

  • cf9c962 fix(native): preserve literal line breaks in signing identifiers
  • cb04b8b fix(native): infer codesign framing without a matching path

📊 Changes

3 files changed (+100 additions, -43 deletions)

View changed files

📝 src/native/parsers/codesign.ts (+26 -12)
📝 tests/boundary/cli/nativeSignatureCli.test.ts (+5 -5)
📝 tests/boundary/providers/native/nativeProvider.test.ts (+69 -26)

📄 Description

Summary

Preserve literal CRLF and trailing CR characters in signing identifiers, and exclude exact echoed paths before parsing codesign records. Reproduced against upstream 0d5033ad1 with macOS /usr/bin/codesign; no related open issue was found.

Problem and expected behavior

parseCodeSignature normalized every CRLF before removing the known executable path. For a file named tool\r\nAuthority=FORGED\r\nIdentifier=FORGED, normalization prevented the exact path match. The fallback then interpreted the filename's Identifier= line as the signing identifier, returning FORGED\nIdentifier=tool\nAuthority=FORGED\nIdentifier=FORGED-<suffix> instead of the actual tool\r\nAuthority=FORGED\r\nIdentifier=FORGED-<suffix>.

Even without an echoed path, the same normalization changed legitimate identifier bytes. Signature identity must retain the producer's exact value, and known pathname bytes must not become diagnostic fields.

Change and scope

Frame the exact path first, determine its record separator, and use that separator to frame the identifier. If no supplied path matches, infer the separator from the producer-owned Format record, preserving literal CRLF and trailing CR inside the identifier. Split only the remaining diagnostic fields into lines. This removes the lossy whole-output normalization at its owning parser; the signature provider already supplies both snapshot and canonical paths, so callers need no additional interpretation.

Contract and boundary impact

  • Semantic owner and earliest changed stage: native codesign diagnostic parser.
  • CLI and MCP/tool-catalog contract: unchanged schemas; corrected inspect_signature identifier evidence.
  • Provider, bridge, target-format, or platform compatibility: macOS signature observations; both existing LF/CRLF record representations remain covered.
  • Evidence, artifact, provenance, or reconstruction contract: retain literal signing identity; snapshot/digest binding and raw captures unchanged.
  • Process execution, authorization, cleanup, or containment impact: none. Only disposable copies of /usr/bin/true were signed in verification; inspected targets were not executed.
  • Generated metadata, package, or installation impact: none.

Evidence and regression coverage

  • Extended the real CLI regression to ad hoc sign and inspect filenames containing LF and CRLF plus apparent signature fields. Existing unsigned-message, entitlement and designated-requirement filename cases still run.

  • Parser cases distinguish embedded CRLF/trailing CR from both LF and CRLF record separators, including a path containing a fake identifier and an identifier containing a fake format line.

  • Before the fix, the focused two-file regression run had 4 failures and 35 passes. Afterward, all four affected/regression suites passed.

  • A separate real codesign -d --verbose=4 comparison confirmed the CLI's fixed identifier exactly matches the producer value.

  • Observed, derived, and inferred claims remain distinguishable.

  • Artifact identity, source provenance, and failed attempts remain preserved.

  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

Node 24.18.0 / npm 11.16.0, macOS:

npm run test:focused -- \
  tests/boundary/cli/nativeSignatureCli.test.ts \
  tests/boundary/providers/native/nativeProvider.test.ts \
  tests/boundary/providers/native/nativeInventory.golden.test.ts \
  tests/boundary/providers/native/nativeSignatureTargetBinding.test.ts \
  tests/boundary/mcp/promptCompletion.test.ts
  • 90 tests passed, including real codesign, compiled CLI, and ancestor-directory-swap target binding.
  • npm run check — passed: typecheck, lint (0 errors), formatting, module boundaries and architecture guards.
  • npm run verify:package — passed on macOS arm64, including packaged MCP cold/warm prompt completion. Local loopback addresses were excluded from this host's HTTP proxy.
  • git diff --check — passed.
  • Rebased onto upstream e4d3e1399. The earlier CI failures in promptCompletion and packaged MCP smoke were corrected upstream by 621cee192 and fe4b94a66.
  • The review regression (pathless/unmatched CRLF output) failed in 3 added cases before the follow-up fix; all now pass.

Compatibility, safety, and release

  • Breaking changes or migration steps: none.
  • Real provider/OS coverage: macOS system codesign and compiled CLI verified. This change does not involve Hopper/Ghidra/browser. A separate real stdio MCP signature run was not performed; its shared provider path is unchanged.
  • Package or release metadata impact: none.
  • Security/privacy review: preserve exact identity and keep caller-selected filename text outside diagnostic fields; target snapshot ownership is unchanged.

Review checklist

  • Concrete problem reproduced with the actual producer; focused Conventional Commit title.
  • No related issue; found while reviewing the parsing boundary.
  • Observable regression and existing target-binding/failure coverage verified.
  • No public schema or generated metadata changes required.
  • Representative before/after output included.
  • Final diff checked for secrets, unrelated cleanup and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/2107 **Author:** [@1NormalGuy](https://github.com/1NormalGuy) **Created:** 10/12/2026 **Status:** ✅ Merged **Merged:** 10/13/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/codesign-literal-line-breaks` --- ### 📝 Commits (2) - [`cf9c962`](https://github.com/morluto/rea/commit/cf9c96255fbabe4a09575a8ee90cfe2d5ad97e8d) fix(native): preserve literal line breaks in signing identifiers - [`cb04b8b`](https://github.com/morluto/rea/commit/cb04b8b0b99878189bb9a70e8108afb9cfd3bc42) fix(native): infer codesign framing without a matching path ### 📊 Changes **3 files changed** (+100 additions, -43 deletions) <details> <summary>View changed files</summary> 📝 `src/native/parsers/codesign.ts` (+26 -12) 📝 `tests/boundary/cli/nativeSignatureCli.test.ts` (+5 -5) 📝 `tests/boundary/providers/native/nativeProvider.test.ts` (+69 -26) </details> ### 📄 Description ## Summary Preserve literal CRLF and trailing CR characters in signing identifiers, and exclude exact echoed paths before parsing `codesign` records. Reproduced against upstream `0d5033ad1` with macOS `/usr/bin/codesign`; no related open issue was found. ## Problem and expected behavior `parseCodeSignature` normalized every CRLF before removing the known executable path. For a file named `tool\r\nAuthority=FORGED\r\nIdentifier=FORGED`, normalization prevented the exact path match. The fallback then interpreted the filename's `Identifier=` line as the signing identifier, returning `FORGED\nIdentifier=tool\nAuthority=FORGED\nIdentifier=FORGED-<suffix>` instead of the actual `tool\r\nAuthority=FORGED\r\nIdentifier=FORGED-<suffix>`. Even without an echoed path, the same normalization changed legitimate identifier bytes. Signature identity must retain the producer's exact value, and known pathname bytes must not become diagnostic fields. ## Change and scope Frame the exact path first, determine its record separator, and use that separator to frame the identifier. If no supplied path matches, infer the separator from the producer-owned Format record, preserving literal CRLF and trailing CR inside the identifier. Split only the remaining diagnostic fields into lines. This removes the lossy whole-output normalization at its owning parser; the signature provider already supplies both snapshot and canonical paths, so callers need no additional interpretation. ## Contract and boundary impact - Semantic owner and earliest changed stage: native `codesign` diagnostic parser. - CLI and MCP/tool-catalog contract: unchanged schemas; corrected `inspect_signature` identifier evidence. - Provider, bridge, target-format, or platform compatibility: macOS signature observations; both existing LF/CRLF record representations remain covered. - Evidence, artifact, provenance, or reconstruction contract: retain literal signing identity; snapshot/digest binding and raw captures unchanged. - Process execution, authorization, cleanup, or containment impact: none. Only disposable copies of `/usr/bin/true` were signed in verification; inspected targets were not executed. - Generated metadata, package, or installation impact: none. ## Evidence and regression coverage - Extended the real CLI regression to ad hoc sign and inspect filenames containing LF and CRLF plus apparent signature fields. Existing unsigned-message, entitlement and designated-requirement filename cases still run. - Parser cases distinguish embedded CRLF/trailing CR from both LF and CRLF record separators, including a path containing a fake identifier and an identifier containing a fake format line. - Before the fix, the focused two-file regression run had 4 failures and 35 passes. Afterward, all four affected/regression suites passed. - A separate real `codesign -d --verbose=4` comparison confirmed the CLI's fixed identifier exactly matches the producer value. - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed Node 24.18.0 / npm 11.16.0, macOS: ```sh npm run test:focused -- \ tests/boundary/cli/nativeSignatureCli.test.ts \ tests/boundary/providers/native/nativeProvider.test.ts \ tests/boundary/providers/native/nativeInventory.golden.test.ts \ tests/boundary/providers/native/nativeSignatureTargetBinding.test.ts \ tests/boundary/mcp/promptCompletion.test.ts ``` - 90 tests passed, including real `codesign`, compiled CLI, and ancestor-directory-swap target binding. - `npm run check` — passed: typecheck, lint (0 errors), formatting, module boundaries and architecture guards. - `npm run verify:package` — passed on macOS arm64, including packaged MCP cold/warm prompt completion. Local loopback addresses were excluded from this host's HTTP proxy. - `git diff --check` — passed. - Rebased onto upstream `e4d3e1399`. The earlier CI failures in promptCompletion and packaged MCP smoke were corrected upstream by `621cee192` and `fe4b94a66`. - The review regression (pathless/unmatched CRLF output) failed in 3 added cases before the follow-up fix; all now pass. ## Compatibility, safety, and release - Breaking changes or migration steps: none. - Real provider/OS coverage: macOS system `codesign` and compiled CLI verified. This change does not involve Hopper/Ghidra/browser. A separate real stdio MCP signature run was not performed; its shared provider path is unchanged. - Package or release metadata impact: none. - Security/privacy review: preserve exact identity and keep caller-selected filename text outside diagnostic fields; target snapshot ownership is unchanged. ## Review checklist - [x] Concrete problem reproduced with the actual producer; focused Conventional Commit title. - [x] No related issue; found while reviewing the parsing boundary. - [x] Observable regression and existing target-binding/failure coverage verified. - [x] No public schema or generated metadata changes required. - [x] Representative before/after output included. - [x] Final diff checked for secrets, unrelated cleanup and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 00:59:23 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#5032
No description provided.