[GH-ISSUE #5741] [Bug] inspect-plist aborts a JSON-decodable NUL string when a large integer triggers XML probing #3487

Closed
opened 2026-10-31 00:41:03 +00:00 by bsakaguchi · 5 comments
Owner

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

Before submitting

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

Area

Native analysis or decompilation

Observed behavior

inspect-plist exits 1 with execution_failure and no normalized result for a valid binary plist containing both a string containing U+0061, U+0000, U+0062 and the integer 9007199254740993. Removing the integer or replacing the NUL string with printable text makes inspection succeed. System plutil successfully converts the complete failing input to JSON; its supplemental XML conversion alone fails.

Reproduction

Run from a built source checkout on macOS with Python 3 and jq available. The fixtures are synthetic and REA uses isolated state.

work_dir="$(mktemp -d)"
mkdir -p "$work_dir/home" "$work_dir/cfg" "$work_dir/data" \
  "$work_dir/cache" "$work_dir/state" "$work_dir/tmp"
python3 - "$work_dir" <<'PYTHON'
from pathlib import Path
import plistlib, sys
work = Path(sys.argv[1])
for name, value in [
    ("nul-big", {"note": "a\x00b", "big": 9007199254740993}),
    ("nul-small", {"note": "a\x00b"}),
    ("printable-big", {"note": "ab", "big": 9007199254740993}),
]:
    (work / (name + ".bin")).write_bytes(
        plistlib.dumps(value, fmt=plistlib.FMT_BINARY))
(work / "truncated.bin").write_bytes(
    (work / "nul-big.bin").read_bytes()[:-10])
print(repr(plistlib.loads((work / "nul-big.bin").read_bytes())))
PYTHON
/usr/bin/plutil -lint "$work_dir/nul-big.bin"
/usr/bin/plutil -convert json -o "$work_dir/plutil.json" -- "$work_dir/nul-big.bin"
cat "$work_dir/plutil.json"
/usr/bin/plutil -convert xml1 -o "$work_dir/plutil.xml" -- "$work_dir/nul-big.bin"
printf 'XML conversion exit=%s\n' "$?"
for fixture in nul-big nul-small printable-big truncated; do
  env -i PATH="$PATH" HOME="$work_dir/home" \
    XDG_CONFIG_HOME="$work_dir/cfg" XDG_DATA_HOME="$work_dir/data" \
    XDG_CACHE_HOME="$work_dir/cache" XDG_STATE_HOME="$work_dir/state" \
    TMPDIR="$work_dir/tmp" REA_LOG_LEVEL=silent \
    node scripts/rea.mjs inspect-plist "$work_dir/$fixture.bin" --json \
    > "$work_dir/$fixture.json" 2> "$work_dir/$fixture.err"
  printf '%s exit=%s\n' "$fixture" "$?"
  jq -c 'if .error then {code, message} else {format: .normalized_result.format, value: .normalized_result.value, limitations: .normalized_result.limitations} end' "$work_dir/$fixture.json"
done

The independent verifier executed these fixtures at the baseline below. I replayed this script once against a fresh npm run build:cached build of fetched main: the combined fixture fails, both reduced controls succeed, and the truncated control fails with invalid_request. Python's integer-aware json.loads of plutil's output and plistlib.loads of the binary were also asserted equal to the exact source dictionary.

Expected behavior

Return normalized JSON with format: "binary" and preserve the NUL-bearing string. Retain the large integer exactly when its type can be established; otherwise expose an explicit precision limitation while preserving the available facts. An unavailable supplemental XML representation should not discard successful JSON decoding.

The selected-local-plist contract promises normalized JSON. The JSON parser and its missing-element-types test already support a result with a precision limitation when number-type metadata is unavailable. Malformed selected inputs must still fail with invalid_request.

Impact and scope

P2: this bounded valid-input combination prevents inspection from returning any normalized facts. It reproduces at the verified baseline and current main. System plutil JSON text and Python plistlib provide demonstrated external-inspection workarounds that preserve both values, although they do not produce REA Evidence. Frequency in real artifacts is unknown. MCP, other platforms, and other value combinations were not exercised. No data mutation or security-boundary crossing was observed.

REA version

rea-agents 6.7.0, verified source baseline 9d8e7803326a382cbbb3ffdb900f5e93e5442d68. Rechecked with a successful fresh npm run build:cached and public CLI execution on fetched main d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f (also 6.7.0): still reproduces. The lockfile is unchanged between these revisions.

Runtime and platform

Node.js v26.12.0; macOS 27.0.1; arm64; system plutil and Python 3 plistlib. No Hopper/Ghidra/IDA involvement.

Target and artifact context

Self-authored binary property-list dictionaries with a NUL string and/or a large integer. The malformed control removes the last ten bytes of a genuine binary fixture. No app bundle or live service is required.

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

Current-main CLI and native utility outcomes, reduced to relevant fields:

plutil -lint: OK
plutil JSON conversion: exit 0
big: exact JSON digits 9007199254740993; note: U+0061, U+0000, U+0062
plutil XML conversion: exit 1
Invalid object in plist for property list format

nul-big: exit 1, code execution_failure, no normalized_result
nul-small: exit 0, note: U+0061, U+0000, U+0062; limitations []
printable-big: exit 0, value {"big":{"$plist_type":"integer","decimal":"9007199254740993"},"note":"ab"}
truncated: exit 1, code invalid_request

The failing CLI's diagnostics identify tool: "plutil", reason: "nonzero-exit", and exit_code: 1; captured stderr ends with the XML-conversion diagnostic above. Its message recommends rea doctor and says repeating the unchanged request is not expected to succeed. The printable control includes the expected exact-integer limitation. Python reads the original string as U+0061, U+0000, U+0062 and the integer as exactly 9007199254740993.

Evidence provenance: observed public CLI and independent native utility checks, independently verified at the baseline and replayed on main. Ordinary JavaScript JSON parsing is not evidence of exact unsafe-integer preservation; the exact textual digits and Python decoder establish that here.

Typed outcome or recovery expected

The combined fixture should exit 0 and retain note as U+0061, U+0000, U+0062. big must preserve the exact decimal integer or carry an explicit precision limitation if its integer/real type cannot be established. Dropping the string or number, replacing NUL, or silently rounding does not restore the contract. Preserve both successful controls and the truncated input's invalid_request. These are proposed restoration checks; no fix was implemented or tested.

Analysis or suspected cause

Source-derived reasoning: NativeMacOSProvider.ts captures JSON successfully, detects an unsafe integral literal, and requests XML element-type metadata with acceptNonZero: false. The XML command failure returns before parsePlistJson can use the already decoded JSON and report missing type information. Current main retains this branch. The failure occurs in REA's handling of the supplemental native command, before the bundled XML decoder runs.

Additional context

Related #5701, #5702, #5703, #5705, and #5737 concern XML fallback after JSON conversion fails. Here JSON conversion succeeds and the optional number-type probe fails before parsing. Preserving successful JSON decoding when that metadata is unavailable can restore this case while those sibling defects remain. Open #4047/#4054 concern real CDATA decoding and do not cover this command-failure branch. Merged #846/#860 establish exact-number and number-type handling, but do not handle this XML-refusal trigger.

Prepared with AI assistance and independent verification. NOT_ENOUGH_INFO: no last known good version or regression range was established. No successful restoration is claimed.

Originally created by @coygeek on GitHub (Oct 21, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5741 ### 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 Native analysis or decompilation ### Observed behavior `inspect-plist` exits 1 with `execution_failure` and no normalized result for a valid binary plist containing both a string containing U+0061, U+0000, U+0062 and the integer `9007199254740993`. Removing the integer or replacing the NUL string with printable text makes inspection succeed. System plutil successfully converts the complete failing input to JSON; its supplemental XML conversion alone fails. ### Reproduction Run from a built source checkout on macOS with Python 3 and jq available. The fixtures are synthetic and REA uses isolated state. ```sh work_dir="$(mktemp -d)" mkdir -p "$work_dir/home" "$work_dir/cfg" "$work_dir/data" \ "$work_dir/cache" "$work_dir/state" "$work_dir/tmp" python3 - "$work_dir" <<'PYTHON' from pathlib import Path import plistlib, sys work = Path(sys.argv[1]) for name, value in [ ("nul-big", {"note": "a\x00b", "big": 9007199254740993}), ("nul-small", {"note": "a\x00b"}), ("printable-big", {"note": "ab", "big": 9007199254740993}), ]: (work / (name + ".bin")).write_bytes( plistlib.dumps(value, fmt=plistlib.FMT_BINARY)) (work / "truncated.bin").write_bytes( (work / "nul-big.bin").read_bytes()[:-10]) print(repr(plistlib.loads((work / "nul-big.bin").read_bytes()))) PYTHON /usr/bin/plutil -lint "$work_dir/nul-big.bin" /usr/bin/plutil -convert json -o "$work_dir/plutil.json" -- "$work_dir/nul-big.bin" cat "$work_dir/plutil.json" /usr/bin/plutil -convert xml1 -o "$work_dir/plutil.xml" -- "$work_dir/nul-big.bin" printf 'XML conversion exit=%s\n' "$?" for fixture in nul-big nul-small printable-big truncated; do env -i PATH="$PATH" HOME="$work_dir/home" \ XDG_CONFIG_HOME="$work_dir/cfg" XDG_DATA_HOME="$work_dir/data" \ XDG_CACHE_HOME="$work_dir/cache" XDG_STATE_HOME="$work_dir/state" \ TMPDIR="$work_dir/tmp" REA_LOG_LEVEL=silent \ node scripts/rea.mjs inspect-plist "$work_dir/$fixture.bin" --json \ > "$work_dir/$fixture.json" 2> "$work_dir/$fixture.err" printf '%s exit=%s\n' "$fixture" "$?" jq -c 'if .error then {code, message} else {format: .normalized_result.format, value: .normalized_result.value, limitations: .normalized_result.limitations} end' "$work_dir/$fixture.json" done ``` The independent verifier executed these fixtures at the baseline below. I replayed this script once against a fresh `npm run build:cached` build of fetched main: the combined fixture fails, both reduced controls succeed, and the truncated control fails with `invalid_request`. Python's integer-aware `json.loads` of plutil's output and `plistlib.loads` of the binary were also asserted equal to the exact source dictionary. ### Expected behavior Return normalized JSON with `format: "binary"` and preserve the NUL-bearing string. Retain the large integer exactly when its type can be established; otherwise expose an explicit precision limitation while preserving the available facts. An unavailable supplemental XML representation should not discard successful JSON decoding. The [selected-local-plist contract](https://github.com/morluto/rea/blob/9d8e7803326a382cbbb3ffdb900f5e93e5442d68/src/contracts/native/nativeToolContracts.ts#L111-L117) promises normalized JSON. The [JSON parser](https://github.com/morluto/rea/blob/9d8e7803326a382cbbb3ffdb900f5e93e5442d68/src/native/parsers/plist.ts#L103-L159) and its [missing-element-types test](https://github.com/morluto/rea/blob/9d8e7803326a382cbbb3ffdb900f5e93e5442d68/src/native/parsers/plist.test.ts#L85-L101) already support a result with a precision limitation when number-type metadata is unavailable. Malformed selected inputs must still fail with `invalid_request`. ### Impact and scope P2: this bounded valid-input combination prevents inspection from returning any normalized facts. It reproduces at the verified baseline and current main. System plutil JSON text and Python plistlib provide demonstrated external-inspection workarounds that preserve both values, although they do not produce REA Evidence. Frequency in real artifacts is unknown. MCP, other platforms, and other value combinations were not exercised. No data mutation or security-boundary crossing was observed. ### REA version `rea-agents` 6.7.0, verified source baseline `9d8e7803326a382cbbb3ffdb900f5e93e5442d68`. Rechecked with a successful fresh `npm run build:cached` and public CLI execution on fetched main `d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f` (also 6.7.0): still reproduces. The lockfile is unchanged between these revisions. ### Runtime and platform Node.js v26.12.0; macOS 27.0.1; arm64; system plutil and Python 3 plistlib. No Hopper/Ghidra/IDA involvement. ### Target and artifact context Self-authored binary property-list dictionaries with a NUL string and/or a large integer. The malformed control removes the last ten bytes of a genuine binary fixture. No app bundle or live service is required. ### Interface CLI ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence Current-main CLI and native utility outcomes, reduced to relevant fields: ```text plutil -lint: OK plutil JSON conversion: exit 0 big: exact JSON digits 9007199254740993; note: U+0061, U+0000, U+0062 plutil XML conversion: exit 1 Invalid object in plist for property list format nul-big: exit 1, code execution_failure, no normalized_result nul-small: exit 0, note: U+0061, U+0000, U+0062; limitations [] printable-big: exit 0, value {"big":{"$plist_type":"integer","decimal":"9007199254740993"},"note":"ab"} truncated: exit 1, code invalid_request ``` The failing CLI's diagnostics identify `tool: "plutil"`, `reason: "nonzero-exit"`, and `exit_code: 1`; captured stderr ends with the XML-conversion diagnostic above. Its message recommends `rea doctor` and says repeating the unchanged request is not expected to succeed. The printable control includes the expected exact-integer limitation. Python reads the original string as U+0061, U+0000, U+0062 and the integer as exactly `9007199254740993`. Evidence provenance: observed public CLI and independent native utility checks, independently verified at the baseline and replayed on main. Ordinary JavaScript JSON parsing is not evidence of exact unsafe-integer preservation; the exact textual digits and Python decoder establish that here. ### Typed outcome or recovery expected The combined fixture should exit 0 and retain `note` as U+0061, U+0000, U+0062. `big` must preserve the exact decimal integer or carry an explicit precision limitation if its integer/real type cannot be established. Dropping the string or number, replacing NUL, or silently rounding does not restore the contract. Preserve both successful controls and the truncated input's `invalid_request`. These are proposed restoration checks; no fix was implemented or tested. ### Analysis or suspected cause Source-derived reasoning: [NativeMacOSProvider.ts](https://github.com/morluto/rea/blob/9d8e7803326a382cbbb3ffdb900f5e93e5442d68/src/native/NativeMacOSProvider.ts#L828-L875) captures JSON successfully, detects an unsafe integral literal, and requests XML element-type metadata with `acceptNonZero: false`. The XML command failure returns before `parsePlistJson` can use the already decoded JSON and report missing type information. Current main retains this branch. The failure occurs in REA's handling of the supplemental native command, before the bundled XML decoder runs. ### Additional context Related #5701, #5702, #5703, #5705, and #5737 concern XML fallback after JSON conversion fails. Here JSON conversion succeeds and the optional number-type probe fails before parsing. Preserving successful JSON decoding when that metadata is unavailable can restore this case while those sibling defects remain. Open #4047/#4054 concern real CDATA decoding and do not cover this command-failure branch. Merged #846/#860 establish exact-number and number-type handling, but do not handle this XML-refusal trigger. Prepared with AI assistance and independent verification. NOT_ENOUGH_INFO: no last known good version or regression range was established. No successful restoration is claimed.
Author
Owner

@XinwangTao commented on GitHub (Oct 21, 2026):

Good repro — the combination of a NUL string and a large integer is exactly the case that exposes a probe-order bug: XML 1.0 forbids U+0000, so once the large integer (9007199254740993 > U+0020 printable probing window) pushes the path toward XML conversion, the NUL byte makes serialization abort, and the tool exits 1 instead of falling back to the JSON path that plutil itself handles fine. The error only shows up when both conditions are present, which is why the individual fixtures (nul-small, printable-big) both pass.

Suggestion: when XML probing/serialization fails on an input that the JSON decoder accepts (plutil already proves it), degrade to the JSON path and report a warning instead of execution_failure. A regression fixture combining a\x00b with 9007199254740993 would lock this in.

<!-- gh-comment-id:6305728409 --> @XinwangTao commented on GitHub (Oct 21, 2026): Good repro — the combination of a NUL string and a large integer is exactly the case that exposes a probe-order bug: XML 1.0 forbids U+0000, so once the large integer (9007199254740993 > U+0020 printable probing window) pushes the path toward XML conversion, the NUL byte makes serialization abort, and the tool exits 1 instead of falling back to the JSON path that plutil itself handles fine. The error only shows up when both conditions are present, which is why the individual fixtures (nul-small, printable-big) both pass. Suggestion: when XML probing/serialization fails on an input that the JSON decoder accepts (plutil already proves it), degrade to the JSON path and report a warning instead of execution_failure. A regression fixture combining a\x00b with 9007199254740993 would lock this in.
Author
Owner

@coygeek commented on GitHub (Oct 21, 2026):

Additional independently verified triggers share this issue's root cause: successful JSON conversion is discarded when the supplemental XML number-typing probe is unusable. Here plutil -convert xml1 exits 0, but emits literal control characters/noncharacters that REA's strict XML parser rejects. The independent verifier reproduced all variants below; I separately reran the U+0001 string plus large integer. Tested with rea-agents 6.7.0 at 9d8e7803326a382cbbb3ffdb900f5e93e5442d68 on macOS, Node.js v26.12.0. Fetched main is d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f, with changes in the provider file: verified at baseline; main not re-run for these additional triggers.

  • U+0001, U+000B, U+FFFE, or U+FFFF in a string value alongside integer 9007199254740993.
  • U+0001 in a dictionary key alongside that integer.
  • A U+0001 string alongside the integral real 9007199254740992.0 also triggers the XML type probe and fails.

Minimal reproduction from the built source checkout:

S="$(mktemp -d)"
mkdir -p "$S/home" "$S/cfg" "$S/data" "$S/cache" "$S/state" "$S/tmp"
python3 -I - "$S/ctrl-big.plist" <<'PYTHON'
import plistlib, sys
with open(sys.argv[1], "wb") as f:
    plistlib.dump({"big": 9007199254740993, "s": "a\x01b"},
                 f, fmt=plistlib.FMT_BINARY)
PYTHON
plutil -convert json -o - "$S/ctrl-big.plist"
plutil -convert xml1 -o - "$S/ctrl-big.plist"
env -i PATH="$PATH" HOME="$S/home" \
  XDG_CONFIG_HOME="$S/cfg" XDG_DATA_HOME="$S/data" \
  XDG_CACHE_HOME="$S/cache" XDG_STATE_HOME="$S/state" \
  TMPDIR="$S/tmp" REA_LOG_LEVEL=silent \
  node scripts/rea.mjs inspect-plist "$S/ctrl-big.plist" --json

Observed: both plutil conversions exit 0. Python's integer-aware JSON decoder confirms the exact source dictionary in the JSON output; the XML contains literal U+0001. REA exits 1 with unreadable_output, reason XML is not well-formed: 8:11: disallowed character., and no normalized_result.

Expected restoration: keep the successful JSON result and original string/key, with an explicit precision limitation when number-type metadata cannot be used. The existing parser fallback can retain available facts but does not establish exact unsafe-integer preservation. Recovery must handle unusable XML output even when the conversion command succeeds; tolerating only nonzero XML exits leaves these triggers failing. This is a proposed restoration check, not a tested fix.

<!-- gh-comment-id:6306064626 --> @coygeek commented on GitHub (Oct 21, 2026): Additional independently verified triggers share this issue's root cause: successful JSON conversion is discarded when the supplemental XML number-typing probe is unusable. Here `plutil -convert xml1` exits **0**, but emits literal control characters/noncharacters that REA's strict XML parser rejects. The independent verifier reproduced all variants below; I separately reran the U+0001 string plus large integer. Tested with `rea-agents` 6.7.0 at `9d8e7803326a382cbbb3ffdb900f5e93e5442d68` on macOS, Node.js v26.12.0. Fetched main is `d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f`, with changes in the provider file: **verified at baseline; main not re-run** for these additional triggers. - U+0001, U+000B, U+FFFE, or U+FFFF in a string value alongside integer `9007199254740993`. - U+0001 in a dictionary key alongside that integer. - A U+0001 string alongside the integral real `9007199254740992.0` also triggers the XML type probe and fails. Minimal reproduction from the built source checkout: ```sh S="$(mktemp -d)" mkdir -p "$S/home" "$S/cfg" "$S/data" "$S/cache" "$S/state" "$S/tmp" python3 -I - "$S/ctrl-big.plist" <<'PYTHON' import plistlib, sys with open(sys.argv[1], "wb") as f: plistlib.dump({"big": 9007199254740993, "s": "a\x01b"}, f, fmt=plistlib.FMT_BINARY) PYTHON plutil -convert json -o - "$S/ctrl-big.plist" plutil -convert xml1 -o - "$S/ctrl-big.plist" env -i PATH="$PATH" HOME="$S/home" \ XDG_CONFIG_HOME="$S/cfg" XDG_DATA_HOME="$S/data" \ XDG_CACHE_HOME="$S/cache" XDG_STATE_HOME="$S/state" \ TMPDIR="$S/tmp" REA_LOG_LEVEL=silent \ node scripts/rea.mjs inspect-plist "$S/ctrl-big.plist" --json ``` Observed: both plutil conversions exit 0. Python's integer-aware JSON decoder confirms the exact source dictionary in the JSON output; the XML contains literal U+0001. REA exits 1 with `unreadable_output`, reason `XML is not well-formed: 8:11: disallowed character.`, and no `normalized_result`. Expected restoration: keep the successful JSON result and original string/key, with an explicit precision limitation when number-type metadata cannot be used. The existing parser fallback can retain available facts but does not establish exact unsafe-integer preservation. Recovery must handle unusable XML output even when the conversion command succeeds; tolerating only nonzero XML exits leaves these triggers failing. This is a proposed restoration check, not a tested fix.
Author
Owner

@kaoru0822-kitauji commented on GitHub (Oct 21, 2026):

Rechecked on current main a5f982de8 with a fresh npm run build:cached (macOS arm64, Node 26.5.0, built CLI). This no longer reproduces. d672cc239 (fix(apple): preserve binary plist scalar source facts) decodes binary plists from their own bytes before any plutil conversion, so the XML number-typing probe no longer runs for these inputs.

inspect-plist results with plistlib-generated binary fixtures (all except the truncated control exit 0 with format: "binary"):

Fixture Result
nul-big (issue fixture) note is U+0061 U+0000 U+0062; big is {"$plist_type":"integer","decimal":"9007199254740993"}
nul-small note kept
printable-big big exact
U+0001 string + big integer (coygeek) s kept; big exact
U+FFFF string + big integer (coygeek) s kept; big exact
U+0001 key + big integer (coygeek) key k\u0001 kept; big exact
U+0001 string + real 9007199254740992.0 (coygeek) r is 9007199254740992; s kept
truncated control invalid_request (unchanged)

Not covered: non-binary inputs still go through plutil, but none of the reported triggers are non-binary. Closing is the maintainers' call; I'm unassigning myself since no change is needed.

<!-- gh-comment-id:6310605297 --> @kaoru0822-kitauji commented on GitHub (Oct 21, 2026): Rechecked on current main `a5f982de8` with a fresh `npm run build:cached` (macOS arm64, Node 26.5.0, built CLI). This no longer reproduces. `d672cc239` (`fix(apple): preserve binary plist scalar source facts`) decodes binary plists from their own bytes before any `plutil` conversion, so the XML number-typing probe no longer runs for these inputs. `inspect-plist` results with `plistlib`-generated binary fixtures (all except the truncated control exit 0 with `format: "binary"`): | Fixture | Result | |---|---| | `nul-big` (issue fixture) | `note` is U+0061 U+0000 U+0062; `big` is `{"$plist_type":"integer","decimal":"9007199254740993"}` | | `nul-small` | `note` kept | | `printable-big` | `big` exact | | U+0001 string + big integer (coygeek) | `s` kept; `big` exact | | U+FFFF string + big integer (coygeek) | `s` kept; `big` exact | | U+0001 key + big integer (coygeek) | key `k\u0001` kept; `big` exact | | U+0001 string + real `9007199254740992.0` (coygeek) | `r` is `9007199254740992`; `s` kept | | `truncated` control | `invalid_request` (unchanged) | Not covered: non-binary inputs still go through `plutil`, but none of the reported triggers are non-binary. Closing is the maintainers' call; I'm unassigning myself since no change is needed.
Author
Owner

@XinwangTao commented on GitHub (Oct 21, 2026):

The verification table is reassuring — all binary fixtures (nul-big, the U+0001/U+FFFF variants, the 9007199254740992.0 real) now exit 0 with the NUL string and exact integer preserved, while the truncated control still correctly fails with invalid_request. That keeps malformed-input handling intact.

One small suggestion: since the combined NUL-string + large-integer fixture is what originally exposed this probe-order bug, it would be worth pinning it as a permanent regression test (the reduced controls alone wouldn't have caught it). That would also guard the binary path against future refactors of the XML number-type probe.

<!-- gh-comment-id:6311121036 --> @XinwangTao commented on GitHub (Oct 21, 2026): The verification table is reassuring — all binary fixtures (nul-big, the U+0001/U+FFFF variants, the 9007199254740992.0 real) now exit 0 with the NUL string and exact integer preserved, while the truncated control still correctly fails with invalid_request. That keeps malformed-input handling intact. One small suggestion: since the combined NUL-string + large-integer fixture is what originally exposed this probe-order bug, it would be worth pinning it as a permanent regression test (the reduced controls alone wouldn't have caught it). That would also guard the binary path against future refactors of the XML number-type probe.
Author
Owner

@XinwangTao commented on GitHub (Oct 21, 2026):

Agree with the fix direction — decoding binary plists from their own bytes sidesteps the XML probe entirely for these inputs, and the recheck table covers all reported variants cleanly. One gap worth pinning down: non-binary inputs still route through plutil, so a NUL/control char combined with an unsafe integer could still hit the same "successful JSON discarded by unusable XML probe" abort there. A regression fixture that forces the XML type-probe path on a non-binary input (control char + 9007199254740993) would lock in the fallback behavior — keep the JSON facts and surface a precision limitation instead of execution_failure.

<!-- gh-comment-id:6311124222 --> @XinwangTao commented on GitHub (Oct 21, 2026): Agree with the fix direction — decoding binary plists from their own bytes sidesteps the XML probe entirely for these inputs, and the recheck table covers all reported variants cleanly. One gap worth pinning down: non-binary inputs still route through plutil, so a NUL/control char combined with an unsafe integer could still hit the same "successful JSON discarded by unusable XML probe" abort there. A regression fixture that forces the XML type-probe path on a non-binary input (control char + 9007199254740993) would lock in the fallback behavior — keep the JSON facts and surface a precision limitation instead of execution_failure.
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#3487
No description provided.