[GH-ISSUE #6583] [Bug] NIBArchive decoding replaces signed infinities and NaN with ordinary null values #3971

Closed
opened 2026-10-31 00:45:41 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 23, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6583

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

Source-only finding; runtime reproduction NOT RUN. The NIBArchive reader recognizes float32 and float64 value records but returns null for every non-finite IEEE value. Positive infinity, negative infinity and NaN therefore become indistinguishable from the format's actual nil tag. This happens during decode, before JSON serialization; the UI graph retains the substituted values under attributes.nibValues without a scalar-loss notice.

Reproduction

Actually performed: inspected the NIB value decoder, projection, coverage and public CLI/provider route, then searched supplied open issues/PRs and live GitHub open/closed reports. No parser or public runtime reproduction was executed.

Proposed runtime steps, UNEXECUTED:

  1. Build an inert, format-version-1 NIBArchive with a retained class such as NSView, ordinary valid object/key/class tables, and four scalar fields: tag 6 with little-endian bytes 00 00 80 7f (positive infinity), tag 7 with bytes 00 00 00 00 00 00 f0 ff (negative infinity), tag 7 with bytes 00 00 00 00 00 00 f8 7f (NaN), and tag 9 (nil, no payload). Counts and table offsets must match the encoded records.
  2. Place the archive at Contents/Resources/Numbers.nib in an ordinary admitted .app and run rea decode-interface-builder Fixture.app --json.
  3. Inspect the view node's attributes.nibValues: the source predicts all four fields are null. A proposed finite-number control uses the same tags and valid table structure with finite payloads.

Expected behavior

Preserve the established real kind and infinity sign in JSON-safe typed values, or explicitly retain these fields as unavailable with a scalar-conversion limitation. A valid floating-point record must remain distinguishable from serialized nil. The existing plist projection in the same Apple domain already carries canonical non-finite real labels without claiming original XML spelling.

Impact and scope

Encoded numeric facts are lost from returned UI evidence for supported NIBArchive floating-point records. Consumers cannot distinguish a known non-finite number from nil using the normalized graph. Original source bytes and archive digest remain intact. Runtime prevalence and downstream UI consequences are unknown; this report does not assert NaN payload-bit preservation or application execution behavior.

REA version

rea-agents 6.7.0; source main at 46111dd091f2ae01baab9eb119b53b9bd309a05b (the supplied latest published release is also 6.7.0).

Runtime and platform

Source-only; runtime reproduction NOT RUN; no provider runtime run. Source inspection host: Linux x86_64; Node.js v26.12.1 was queried for environment identification only. No REA command, Apple tool, target process, dependency installation, or test suite was run.

Target and artifact context

Compiled NIBArchive v1 within an Apple .app, containing well-bounded float32/float64 scalar records with non-finite IEEE payloads and a nil control.

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

Source proof, not captured runtime output:

Missing evidence: no generated fixture, decoder execution, CLI/MCP result, Apple-generated nib or real-app incidence measurement.

Typed outcome or recovery expected

Distinct JSON-safe non-finite real values, or explicit unknown/unavailable scalar records with a reason; preserve actual nil as null.

Analysis or suspected cause

Number.isFinite(value) ? value : null destroys an established scalar fact at the NIB format boundary. Later projection receives only null and cannot recover the distinction from the retained field.

Additional context

Live open/closed searches included repo:morluto/rea NIBArchive "non-finite" and repo:morluto/rea nib infinity. Closed #4919 concerned non-finite binary-plist values being replaced inside projectPlistValue; that owner now preserves their labels, whereas NIBArchive uses this separate earlier decoder. Closed #4295 concerned keyed-archive node kinds. Closed PR #899 fixed keyed-plist nibs, not the NIBArchive scalar branch. Open #6437 concerns Python negative zero; #6541 concerns native accessibility values. No matching NIBArchive scalar-loss report was found. No known-good version was established.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: The supported NIBArchive numeric branches deterministically erase three established real kinds into the same nil value before returning normalized evidence. Scope is bounded to non-finite scalar payloads; real-app frequency is unknown.
  • Workaround status: unverified
  • Workaround basis: Reading the original binary record with a separate decoder could retain its value, but no supported REA alternative or practical end-to-end recovery was exercised.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6583 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior Source-only finding; runtime reproduction NOT RUN. The NIBArchive reader recognizes float32 and float64 value records but returns `null` for every non-finite IEEE value. Positive infinity, negative infinity and NaN therefore become indistinguishable from the format's actual nil tag. This happens during decode, before JSON serialization; the UI graph retains the substituted values under `attributes.nibValues` without a scalar-loss notice. ### Reproduction Actually performed: inspected the NIB value decoder, projection, coverage and public CLI/provider route, then searched supplied open issues/PRs and live GitHub open/closed reports. No parser or public runtime reproduction was executed. Proposed runtime steps, UNEXECUTED: 1. Build an inert, format-version-1 NIBArchive with a retained class such as `NSView`, ordinary valid object/key/class tables, and four scalar fields: tag 6 with little-endian bytes `00 00 80 7f` (positive infinity), tag 7 with bytes `00 00 00 00 00 00 f0 ff` (negative infinity), tag 7 with bytes `00 00 00 00 00 00 f8 7f` (NaN), and tag 9 (nil, no payload). Counts and table offsets must match the encoded records. 2. Place the archive at `Contents/Resources/Numbers.nib` in an ordinary admitted `.app` and run `rea decode-interface-builder Fixture.app --json`. 3. Inspect the view node's `attributes.nibValues`: the source predicts all four fields are `null`. A proposed finite-number control uses the same tags and valid table structure with finite payloads. ### Expected behavior Preserve the established real kind and infinity sign in JSON-safe typed values, or explicitly retain these fields as unavailable with a scalar-conversion limitation. A valid floating-point record must remain distinguishable from serialized nil. The existing plist projection in the same Apple domain already carries canonical non-finite real labels without claiming original XML spelling. ### Impact and scope Encoded numeric facts are lost from returned UI evidence for supported NIBArchive floating-point records. Consumers cannot distinguish a known non-finite number from nil using the normalized graph. Original source bytes and archive digest remain intact. Runtime prevalence and downstream UI consequences are unknown; this report does not assert NaN payload-bit preservation or application execution behavior. ### REA version rea-agents 6.7.0; source main at `46111dd091f2ae01baab9eb119b53b9bd309a05b` (the supplied latest published release is also 6.7.0). ### Runtime and platform Source-only; runtime reproduction NOT RUN; no provider runtime run. Source inspection host: Linux x86_64; Node.js v26.12.1 was queried for environment identification only. No REA command, Apple tool, target process, dependency installation, or test suite was run. ### Target and artifact context Compiled NIBArchive v1 within an Apple `.app`, containing well-bounded float32/float64 scalar records with non-finite IEEE payloads and a nil control. ### Interface CLI ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence Source proof, not captured runtime output: - [The reader declares float32, float64 and nil as separate supported encodings](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/artifacts/apple/NibArchive.ts#L341-L357). - [Both float branches replace non-finite values with null](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/artifacts/apple/NibArchive.ts#L399-L411); [the actual nil tag also returns null](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/artifacts/apple/NibArchive.ts#L429-L430). No validity check rejects the IEEE payloads before this substitution. - [Object fields retain the decoder's substituted value](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/artifacts/apple/NibArchive.ts#L126-L147); [UI projection copies it into nibValues](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/artifacts/apple/InterfaceBuilderAnalysis.ts#L568-L588). - [The public CLI](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/cli/artifactCommands.ts#L180-L191) reaches [the analyzer](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/artifacts/ArtifactProvider.ts#L224-L231), which [takes the NIBArchive decoder branch](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/artifacts/apple/InterfaceBuilderAnalysis.ts#L134-L145). - [The Apple plist projection preserves canonical non-finite labels](https://github.com/morluto/rea/blob/46111dd091f2ae01baab9eb119b53b9bd309a05b/src/domain/apple/plistValue.ts#L101-L114), providing an existing JSON-safe distinction. Missing evidence: no generated fixture, decoder execution, CLI/MCP result, Apple-generated nib or real-app incidence measurement. ### Typed outcome or recovery expected Distinct JSON-safe non-finite real values, or explicit unknown/unavailable scalar records with a reason; preserve actual nil as null. ### Analysis or suspected cause `Number.isFinite(value) ? value : null` destroys an established scalar fact at the NIB format boundary. Later projection receives only null and cannot recover the distinction from the retained field. ### Additional context Live open/closed searches included `repo:morluto/rea NIBArchive "non-finite"` and `repo:morluto/rea nib infinity`. Closed #4919 concerned non-finite binary-plist values being replaced inside `projectPlistValue`; that owner now preserves their labels, whereas NIBArchive uses this separate earlier decoder. Closed #4295 concerned keyed-archive node kinds. Closed PR #899 fixed keyed-plist nibs, not the NIBArchive scalar branch. Open #6437 concerns Python negative zero; #6541 concerns native accessibility values. No matching NIBArchive scalar-loss report was found. No known-good version was established. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: The supported NIBArchive numeric branches deterministically erase three established real kinds into the same nil value before returning normalized evidence. Scope is bounded to non-finite scalar payloads; real-app frequency is unknown. - Workaround status: unverified - Workaround basis: Reading the original binary record with a separate decoder could retain its value, but no supported REA alternative or practical end-to-end recovery was exercised.
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#3971
No description provided.