[PR #2771] fix(ghidra): keep unreported Java bitness unknown #5380

Open
opened 2026-10-31 01:06:10 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/2771
Author: @yasshmittal
Created: 10/13/2026
Status: 🔄 Open

Base: main ← Head: fix/ghidra-unknown-java-bitness


📝 Commits (10+)

  • 85f960c fix(ghidra): keep unreported Java bitness unknown
  • 2cfb259 fix(ghidra): retain malformed Java data-model text
  • 4443398 fix(ghidra): keep empty Java settings on their own line
  • e8315ea fix(ghidra): keep lossy Java data-model digits unparsed
  • 6e47205 fix(ghidra): reconcile unknown Java bitness with bounded probing
  • 93d5f95 fix(ghidra): keep Java setting values verbatim after the delimiter
  • ad06284 fix(ghidra): retain incomplete Java probe observations
  • a30bb98 test(ghidra): keep incomplete-observation cases in their own suite
  • 38c6cde fix(ghidra): retain mismatch facts in incomplete probes
  • c21fae9 fix(ghidra): classify incomplete Java mismatches

📊 Changes

3 files changed (+321 additions, -34 deletions)

View changed files

📝 src/ghidra/GhidraInstallation.test.ts (+131 -0)
📝 src/ghidra/GhidraInstallation.ts (+115 -34)
📝 tests/boundary/filesystem/ghidraJavaProbe.test.ts (+75 -0)

📄 Description

Summary

Fixes #2532.

When the Java settings probe reported version, home and VM name but omitted sun.arch.data.model, Ghidra inspection and doctor described the runtime as 0-bit and returned unsupported_version. The probe never established a bitness, so the result stated a measurement that did not exist.

Problem and expected behavior

The probe parser in src/ghidra/GhidraInstallation.ts substituted "0" for the absent property, and the Java check formatted that as a determined 0-bit runtime. AGENTS.md requires unresolved identity to stay unknown. Admission must still be refused until a 64-bit JDK is established, but without claiming a measured incompatible bitness.

Change and scope

  • GhidraJavaObservation.bits is now number | null. The parser returns null when the property is absent or is not a decimal value.
  • A reported value that is not an exactly representable decimal (non-digits, or digits beyond the safe-integer range) is retained as unparsedBits, so absent and malformed reports stay distinguishable (review feedback).
  • javaProperty matches horizontal whitespace only, so an explicitly empty setting returns "" instead of absorbing the next line (review feedback). An empty java.version or java.home still cannot identify the runtime.
  • The Java check describes these as bitness unknown or bitness unknown (sun.arch.data.model = "64-bit") and still fails.
  • When unknown bitness is the only unestablished requirement, the check code is version_unresolved. Known mismatches (32-bit, JRE, wrong major version) keep unsupported_version.

Judgment call for review: the issue does not name a code for unknown bitness. I chose the existing version_unresolved because the runtime's required identity is unresolved rather than known to be incompatible. If you prefer to keep unsupported_version, that is a one-line change and the bitness unknown wording fix stands on its own.

Contribution scope: an ordinary fix within existing boundaries; no maintainer scope decision applies.

Contract and boundary impact

  • Semantic owner and earliest changed stage: Java settings parsing in the system Ghidra installation host (probeJava).

  • Contribution scope fit and linked maintainer decision: not applicable (bug fix).

  • CLI and MCP/tool-catalog contract: the doctor/provider Java check detail changes from 0-bit to bitness unknown, and its code becomes version_unresolved in that case. No schema change.

  • Provider, bridge, target-format, or platform compatibility: JDKs that report bitness behave exactly as before.

  • Evidence, artifact, provenance, or reconstruction contract: unchanged.

  • Target selection, authority, upstream behavior, and cleanup details: Ghidra is not launched; admission still requires an established 64-bit JDK.

  • Generated metadata, package, or installation impact: none.

  • Read existing files or captured data.

  • Launch or attach to a process. (Existing behavior: the java -XshowSettings:properties -version probe, unchanged.)

Evidence and regression coverage

  • Tests added or updated:

    • tests/boundary/filesystem/ghidraJavaProbe.test.ts: the real parser on probe output without sun.arch.data.model gives a failed check, version_unresolved, and detail 21.0.11; bitness unknown; JDK;. An empty sun.arch.data.model = line keeps "" instead of reading the next line. A lossy 9007199254740993 keeps its text instead of reporting 9007199254740992-bit. A malformed 64junk gives version_unresolved and retains the reported text; on the base revision parseInt read it as 64 and the check passed. A 32 control gives 32-bit and unsupported_version.
    • src/ghidra/GhidraInstallation.test.ts: two rows in the existing check-code table (32-bit and unreported bitness).
  • Base reproduction or other evidence: run against the base GhidraInstallation.ts, the new boundary test fails with detail 21.0.11; 0-bit; JDK; …; with this change it passes.

  • User-visible CLI/MCP output: Java check detail 21.0.11; bitness unknown; JDK; <home>; accepted a 64-bit full JDK 21 or newer.

  • Remaining proof gaps: no real JDK that omits the property is known; this was exercised with controlled probe output, as in the issue.

  • 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

Host: Windows 11, Node.js 24.21.0.

  • npx vitest run --project boundary tests/boundary/filesystem/ghidraJavaProbe.test.ts: 8 passed (fails on the base revision as described above).
  • npm run test:local -- src/ghidra/GhidraInstallation.test.ts: 53 passed.
  • npm run check: passed.
  • npm run verify:test-discovery: passed.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. Behavior changes only when the probe omits bitness.
  • Real Hopper/Ghidra, browser, or OS coverage: Windows only; no real Ghidra lane run (Ghidra is not launched by this path).
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: no new processes or I/O; admission stays fail-closed.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🤖 Generated with Claude Code


🔄 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/2771 **Author:** [@yasshmittal](https://github.com/yasshmittal) **Created:** 10/13/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/ghidra-unknown-java-bitness` --- ### 📝 Commits (10+) - [`85f960c`](https://github.com/morluto/rea/commit/85f960ccc10ab8c3822aa3976643a0b55b2a12e4) fix(ghidra): keep unreported Java bitness unknown - [`2cfb259`](https://github.com/morluto/rea/commit/2cfb259d57fe38afd78f17d1d6ddc8a0ef7f7c72) fix(ghidra): retain malformed Java data-model text - [`4443398`](https://github.com/morluto/rea/commit/44433989a04d0165184a6538d8d95a0ee91929a9) fix(ghidra): keep empty Java settings on their own line - [`e8315ea`](https://github.com/morluto/rea/commit/e8315ea304f557733c826d49c97ad6a5ac1369cb) fix(ghidra): keep lossy Java data-model digits unparsed - [`6e47205`](https://github.com/morluto/rea/commit/6e47205540a3c0e8591f2080b50c9d08776b50b2) fix(ghidra): reconcile unknown Java bitness with bounded probing - [`93d5f95`](https://github.com/morluto/rea/commit/93d5f956109d77413ffde253f915167ba338551f) fix(ghidra): keep Java setting values verbatim after the delimiter - [`ad06284`](https://github.com/morluto/rea/commit/ad062848f63b11d5df9c4f0bd91752a7b2d2d3ab) fix(ghidra): retain incomplete Java probe observations - [`a30bb98`](https://github.com/morluto/rea/commit/a30bb988f34a6c5a30098484da3a3c7b5b3ccad6) test(ghidra): keep incomplete-observation cases in their own suite - [`38c6cde`](https://github.com/morluto/rea/commit/38c6cde298795ae04f67ab9c8de1b185a4830af1) fix(ghidra): retain mismatch facts in incomplete probes - [`c21fae9`](https://github.com/morluto/rea/commit/c21fae98ae18ff8f8d3c99193ed1ab01d30d18ca) fix(ghidra): classify incomplete Java mismatches ### 📊 Changes **3 files changed** (+321 additions, -34 deletions) <details> <summary>View changed files</summary> 📝 `src/ghidra/GhidraInstallation.test.ts` (+131 -0) 📝 `src/ghidra/GhidraInstallation.ts` (+115 -34) 📝 `tests/boundary/filesystem/ghidraJavaProbe.test.ts` (+75 -0) </details> ### 📄 Description ## Summary Fixes #2532. When the Java settings probe reported version, home and VM name but omitted `sun.arch.data.model`, Ghidra inspection and doctor described the runtime as `0-bit` and returned `unsupported_version`. The probe never established a bitness, so the result stated a measurement that did not exist. ## Problem and expected behavior The probe parser in `src/ghidra/GhidraInstallation.ts` substituted `"0"` for the absent property, and the Java check formatted that as a determined `0-bit` runtime. AGENTS.md requires unresolved identity to stay unknown. Admission must still be refused until a 64-bit JDK is established, but without claiming a measured incompatible bitness. ## Change and scope - `GhidraJavaObservation.bits` is now `number | null`. The parser returns `null` when the property is absent or is not a decimal value. - A reported value that is not an exactly representable decimal (non-digits, or digits beyond the safe-integer range) is retained as `unparsedBits`, so absent and malformed reports stay distinguishable (review feedback). - `javaProperty` matches horizontal whitespace only, so an explicitly empty setting returns `""` instead of absorbing the next line (review feedback). An empty `java.version` or `java.home` still cannot identify the runtime. - The Java check describes these as `bitness unknown` or `bitness unknown (sun.arch.data.model = "64-bit")` and still fails. - When unknown bitness is the only unestablished requirement, the check code is `version_unresolved`. Known mismatches (32-bit, JRE, wrong major version) keep `unsupported_version`. Judgment call for review: the issue does not name a code for unknown bitness. I chose the existing `version_unresolved` because the runtime's required identity is unresolved rather than known to be incompatible. If you prefer to keep `unsupported_version`, that is a one-line change and the `bitness unknown` wording fix stands on its own. Contribution scope: an ordinary fix within existing boundaries; no maintainer scope decision applies. ## Contract and boundary impact - Semantic owner and earliest changed stage: Java settings parsing in the system Ghidra installation host (`probeJava`). - Contribution scope fit and linked maintainer decision: not applicable (bug fix). - CLI and MCP/tool-catalog contract: the doctor/provider Java check detail changes from `0-bit` to `bitness unknown`, and its code becomes `version_unresolved` in that case. No schema change. - Provider, bridge, target-format, or platform compatibility: JDKs that report bitness behave exactly as before. - Evidence, artifact, provenance, or reconstruction contract: unchanged. - Target selection, authority, upstream behavior, and cleanup details: Ghidra is not launched; admission still requires an established 64-bit JDK. - Generated metadata, package, or installation impact: none. - [x] Read existing files or captured data. - [x] Launch or attach to a process. (Existing behavior: the `java -XshowSettings:properties -version` probe, unchanged.) ## Evidence and regression coverage - Tests added or updated: - `tests/boundary/filesystem/ghidraJavaProbe.test.ts`: the real parser on probe output without `sun.arch.data.model` gives a failed check, `version_unresolved`, and detail `21.0.11; bitness unknown; JDK;`. An empty `sun.arch.data.model =` line keeps `""` instead of reading the next line. A lossy `9007199254740993` keeps its text instead of reporting `9007199254740992-bit`. A malformed `64junk` gives `version_unresolved` and retains the reported text; on the base revision `parseInt` read it as 64 and the check passed. A `32` control gives `32-bit` and `unsupported_version`. - `src/ghidra/GhidraInstallation.test.ts`: two rows in the existing check-code table (32-bit and unreported bitness). - Base reproduction or other evidence: run against the base `GhidraInstallation.ts`, the new boundary test fails with detail `21.0.11; 0-bit; JDK; …`; with this change it passes. - User-visible CLI/MCP output: Java check detail `21.0.11; bitness unknown; JDK; <home>; accepted a 64-bit full JDK 21 or newer`. - Remaining proof gaps: no real JDK that omits the property is known; this was exercised with controlled probe output, as in the issue. - [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 Host: Windows 11, Node.js 24.21.0. - `npx vitest run --project boundary tests/boundary/filesystem/ghidraJavaProbe.test.ts`: 8 passed (fails on the base revision as described above). - `npm run test:local -- src/ghidra/GhidraInstallation.test.ts`: 53 passed. - `npm run check`: passed. - `npm run verify:test-discovery`: passed. ## Compatibility, safety, and release - Breaking changes or migration steps: none. Behavior changes only when the probe omits bitness. - Real Hopper/Ghidra, browser, or OS coverage: Windows only; no real Ghidra lane run (Ghidra is not launched by this path). - Package or release metadata impact: none. - Security, privacy, process, or containment review: no new processes or I/O; admission stays fail-closed. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
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#5380
No description provided.