[GH-ISSUE #6605] [Bug] classify negative marshal string lengths as malformed input #3990

Closed
opened 2026-10-31 00:45:50 +00:00 by bsakaguchi · 2 comments
Owner

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

Before submitting

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

Area

CLI

Observed behavior

The public inspect-python-pyc CLI reports resource_constraint, category resource_constraint, and resource memory for a 105-byte CPython 3.11 pyc whose bytes constant has signed marshal length −1. Its message claims Marshal string of 4294967295 bytes exceeds max_string_bytes 1048576. The maximum accepted string budget produces the same classification. Matching CPython rejects the body as malformed: ValueError: bad marshal data (bytes object size out of range).

The controls distinguish format rejection from a real budget refusal. A truncated positive-length constant receives invalid_request with invalid_format; a fully present 2 MiB constant receives resource_constraint at the default string budget and complete success when that budget is raised to 2 MiB. A three-byte constant also succeeds. Every measured CLI refusal exits 1 with empty stderr; successful controls exit 0.

Reproduction

Use the source revision below with locked dependencies and its compiled runtime prepared. The verification used an already prepared checkout and did not rebuild or install dependencies. From the checkout root, run this block with Node.js and an existing CPython 3.11 interpreter on PATH. It creates synthetic files and isolated REA home/config/cache/data/state/temp directories, loads code objects only as data, and removes its temporary directory. No target bytecode runs.

python3.11 -I -B - "$PWD" "$(command -v node)" <<'PYTHON'
import json, marshal, os, pathlib, struct, subprocess, sys, tempfile, types
assert sys.implementation.name == 'cpython' and sys.version_info[:2] == (3, 11)
repo, node = pathlib.Path(sys.argv[1]).resolve(), str(pathlib.Path(sys.argv[2]).resolve())
def word(n): return struct.pack('<i', n)
def blob(b): return b's' + word(len(b)) + b
def text(b): return b'z' + bytes([len(b)]) + b
def fixture(obj):
    prefix = b'c' + struct.pack('<5i', 0, 0, 0, 1, 0)
    prefix += blob(b'\x53\x00') + b')\x01'
    suffix = b')\x00' + b')\x00' + blob(b'')
    suffix += text(b'sample.py') + text(b'<module>') + text(b'<module>')
    suffix += word(1) + blob(b'') + blob(b'')
    header = struct.pack('<H', 3495) + b'\r\n' + bytes(12)
    return header + prefix + obj + suffix
fixtures = {
    'valid': fixture(blob(b'abc')),
    'negative': fixture(b's' + word(-1)),
    'large': fixture(blob(b'x' * (2 * 1024 * 1024))),
}
# Stop inside the bytes constant after two of its five declared bytes.
fixtures['truncated'] = fixtures['valid'][:46] + b's' + word(5) + b'ab'
with tempfile.TemporaryDirectory(prefix='pyc-sizes-') as directory:
    root = pathlib.Path(directory).resolve()
    env = {'PATH': str(pathlib.Path(node).parent) + ':/usr/bin:/bin',
           'REA_LOG_LEVEL': 'silent', 'NO_COLOR': '1'}
    for key in ('HOME', 'TMPDIR', 'XDG_CONFIG_HOME', 'XDG_CACHE_HOME',
                'XDG_DATA_HOME', 'XDG_STATE_HOME', 'DSH_HOME', 'DSH_AGENTS_HOME'):
        location = root / key.lower(); location.mkdir(); env[key] = str(location)
    for name, data in fixtures.items():
        (root / (name + '.pyc')).write_bytes(data)
        try:
            obj = marshal.loads(data[16:])
            assert isinstance(obj, types.CodeType)
            oracle = 'accepted code object'
        except (ValueError, EOFError) as error:
            oracle = type(error).__name__ + ': ' + str(error)
        print(json.dumps({'oracle': name, 'bytes': len(data), 'result': oracle}))
    for name, options in [
        ('valid', []), ('negative', []),
        ('negative', ['--max-string-bytes', '8388608']),
        ('truncated', []), ('large', []),
        ('large', ['--max-string-bytes', '2097152']),
    ]:
        command = [node, str(repo / 'scripts/rea.mjs'), 'inspect-python-pyc',
                   str(root / (name + '.pyc')), *options, '--json']
        run = subprocess.run(command, cwd=root, env=env, capture_output=True,
                             text=True, timeout=30)
        assert run.stderr == '', run.stderr
        out = json.loads(run.stdout)
        result = out.get('normalized_result')
        issues = out.get('details', {}).get('issues', [])
        print(json.dumps({'case': name, 'options': options, 'exit': run.returncode,
                          'code': out.get('code'), 'category': out.get('category'),
                          'resource': out.get('details', {}).get('resource'),
                          'format_reason': issues[0]['reason'] if issues else None,
                          'message': out.get('message'),
                          'coverage': result['coverage']['status'] if result else None}))
PYTHON

The six CLI cases and all four matching-interpreter checks were executed through an independent probe, a replay of this program, and the exact inline shell block above. The negative-length failure reproduced on all three runs at both tested string budgets; every run produced the stated control results.

Expected behavior

Once the recognized marshal string length is read, a signed-negative encoding should receive the existing malformed-input result: invalid_request, category invalid_input, with an invalid_format issue for path. It should not be interpreted as a large positive string requesting more memory. This expectation concerns typed rejection; the malformed artifact should remain refused without a successful report.

Preserve real resource boundaries. The fully present positive 2 MiB constant should remain a resource refusal at the default budget and succeed at the accepted higher budget. This report does not require parsing past an earlier exhausted object/depth budget to discover a later malformed value.

Impact and scope

P2: callers receive a different machine-readable failure category and recovery direction for malformed data than for other invalid formats. The returned memory remediation recommends host/worker-memory review or a smaller artifact, neither of which corrects a signed-negative string length. This is a bounded diagnostic behavior defect affecting corrupt or handcrafted artifacts; both the current and expected paths refuse the file, and no valid artifact was observed failing because of this defect.

Real-world frequency is unknown. No input mutation, incorrect successful Evidence, lost sibling inventory, process crash, resource exhaustion, severe incident, or security-boundary crossing was observed. No caller retry loop was exercised. MCP and other platforms were not run.

REA version

Unreleased source revision bcd1f95e68, using its prepared compiled runtime. The CLI reports 6.7.0, but the latest published rea-agents-6.7.0 tag lacks the standalone inspector/parser; this is a source-build finding, not a claim that the published release contains the defect.

Runtime and platform

Node.js v24.22.1; CPython 3.11.17 for inert fixture construction and independent marshal decoding; macOS 27.0.1 arm64. No native analysis engine was involved. Each REA subprocess received an explicit clean environment and isolated state directories.

Target and artifact context

Timestamp-header CPython 3.11 pycs with magic 3495, zero header flags, one root code object, and one bytes constant. The code has zero argument counts/flags, stack size 1, two bytecode bytes, and empty name/local/line/exception tables. Negative, small valid, truncated, and large fixtures contain 105, 108, 53, and 2097257 bytes respectively. The negative constant starts with 73 ff ff ff ff; no corresponding positive-length payload exists.

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

  • Expected source: src/python/PythonPyc.errors.ts:1-18 distinguishes corrupt recognized pycs from resource-boundary failures; src/python/PythonPycProvider.ts:53-76 maps those cases to distinct public outcomes; docs/python-pyc.md, Limits and failures, describes bounded inspection and typed format failures. CPython v3.11.17 marshal reader reads the bytes length as a signed value and rejects negative sizes before allocation; the matching runtime confirms applicability to the exact fixture.
  • Failure source: the executed public CLI results below; src/python/PythonPycParser.ts:359-360,1347-1355,1379-1386 reads the bytes length with u32() and checks the resulting unsigned value against the string budget before the file-overrun check. The prepared compiled parser contains the same read and comparison.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Observed result summary from the inline program:

CPython valid (108 bytes): accepted code object
CPython negative (105 bytes): ValueError: bad marshal data (bytes object size out of range)
CPython large (2097257 bytes): accepted code object
CPython truncated (53 bytes): EOFError: marshal data too short
CLI valid: exit 0, coverage complete
CLI negative, default: exit 1, resource_constraint / resource_constraint / memory
CLI negative, max-string-bytes 8388608: exit 1, resource_constraint / resource_constraint / memory
CLI truncated: exit 1, invalid_request / invalid_input / invalid_format
CLI large, default: exit 1, resource_constraint / resource_constraint / memory
CLI large, max-string-bytes 2097152: exit 0, coverage complete

The negative default result reports max_string_bytes: 1048576, retryable: false, and the message quoted above. At the maximum tested budget, only the reported limit/message changes to 8388608. Both return the same remediation action: Review the reported worker memory limits and available host memory. Retry with sufficient memory or a smaller artifact; REA retains tighter inherited limits. The additional fields and remediation were inspected in the independently retained full CLI responses.

Typed outcome or recovery expected

For the negative string fixture at both tested string budgets, return invalid_request / invalid_input with an issue at ["path"] whose reason is invalid_format. Identify malformed marshal structure rather than a memory shortage. Preserve refusal and avoid successful normalized Evidence; partial or opaque standalone recovery is not requested.

Analysis or suspected cause

Source-derived explanation: the bytes tag uses an unsigned four-byte length reader, so the signed −1 encoding becomes 4294967295 before the resource comparison. The provider then faithfully projects the resulting resource-failure type. The observed mismatch concerns the producing format interpretation; correcting generic resource-remediation wording alone would leave the wrong category. No repair was applied or tested.

Additional context

Issue #6438 concerns valid artifacts refused by intentional caller-selected budgets. Its expected restoration retains resource_constraint and fixes the control-specific recovery advice; this negative-length fixture instead requires the malformed-input classification.

Issue #6120 concerns a separate PYZ parser and loss of healthy sibling inventory. Its closed/completed state and closure commit were checked live. The closure changes the PyInstaller parser and its tests, with no standalone-parser change. Independent public inspect-artifact calls at the tested baseline confirmed its separate restoration signal: negative string/list/tuple sizes abort inventory, whereas truncated and unsupported PYZ tables preserve a healthy data.txt sibling and an opaque PYZ. Standalone pyc has no such sibling or opaque fallback. The closure commit was inspected as source, not executed. Other canonical pyc reports cover code flags, hashability, singleton reference slots, negative line metadata, historical headers, Unicode previews, signed zero, and equality rules; no matching standalone negative-string-length report was found in the bounded open/closed searches.

Restoration check

Rerun the exact inline program after a repair. Both negative-length calls must change from resource_constraint to invalid_request / invalid_input with invalid_format, while still exiting 1. Preserve the truncated input's format refusal, the small valid fixture's complete success, and the large positive fixture's default resource refusal followed by complete success at 2 MiB. Converting every over-budget string into a format error would fail the positive control. This is a proposed check; no repaired runtime was tested.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: The public CLI exposes the wrong machine-readable category and memory-recovery direction for a recognized malformed string length, independently of the valid positive resource-control cases. The defect is bounded to malformed inputs and no severe downstream incident was observed; this changes caller-facing diagnostic behavior rather than only wording.
  • Workaround status: unverified
  • Workaround basis: No existing REA option was verified to restore the malformed-input category. Matching CPython identifies this self-authored fixture as corrupt, but that does not establish a safe general validator or replacement workflow for arbitrary untrusted marshal streams.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6605 ## 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 CLI ## Observed behavior The public `inspect-python-pyc` CLI reports `resource_constraint`, category `resource_constraint`, and resource `memory` for a 105-byte CPython 3.11 pyc whose bytes constant has signed marshal length −1. Its message claims `Marshal string of 4294967295 bytes exceeds max_string_bytes 1048576.` The maximum accepted string budget produces the same classification. Matching CPython rejects the body as malformed: `ValueError: bad marshal data (bytes object size out of range)`. The controls distinguish format rejection from a real budget refusal. A truncated positive-length constant receives `invalid_request` with `invalid_format`; a fully present 2 MiB constant receives `resource_constraint` at the default string budget and complete success when that budget is raised to 2 MiB. A three-byte constant also succeeds. Every measured CLI refusal exits 1 with empty stderr; successful controls exit 0. ## Reproduction Use the source revision below with locked dependencies and its compiled runtime prepared. The verification used an already prepared checkout and did not rebuild or install dependencies. From the checkout root, run this block with Node.js and an existing CPython 3.11 interpreter on PATH. It creates synthetic files and isolated REA home/config/cache/data/state/temp directories, loads code objects only as data, and removes its temporary directory. No target bytecode runs. ```sh python3.11 -I -B - "$PWD" "$(command -v node)" <<'PYTHON' import json, marshal, os, pathlib, struct, subprocess, sys, tempfile, types assert sys.implementation.name == 'cpython' and sys.version_info[:2] == (3, 11) repo, node = pathlib.Path(sys.argv[1]).resolve(), str(pathlib.Path(sys.argv[2]).resolve()) def word(n): return struct.pack('<i', n) def blob(b): return b's' + word(len(b)) + b def text(b): return b'z' + bytes([len(b)]) + b def fixture(obj): prefix = b'c' + struct.pack('<5i', 0, 0, 0, 1, 0) prefix += blob(b'\x53\x00') + b')\x01' suffix = b')\x00' + b')\x00' + blob(b'') suffix += text(b'sample.py') + text(b'<module>') + text(b'<module>') suffix += word(1) + blob(b'') + blob(b'') header = struct.pack('<H', 3495) + b'\r\n' + bytes(12) return header + prefix + obj + suffix fixtures = { 'valid': fixture(blob(b'abc')), 'negative': fixture(b's' + word(-1)), 'large': fixture(blob(b'x' * (2 * 1024 * 1024))), } # Stop inside the bytes constant after two of its five declared bytes. fixtures['truncated'] = fixtures['valid'][:46] + b's' + word(5) + b'ab' with tempfile.TemporaryDirectory(prefix='pyc-sizes-') as directory: root = pathlib.Path(directory).resolve() env = {'PATH': str(pathlib.Path(node).parent) + ':/usr/bin:/bin', 'REA_LOG_LEVEL': 'silent', 'NO_COLOR': '1'} for key in ('HOME', 'TMPDIR', 'XDG_CONFIG_HOME', 'XDG_CACHE_HOME', 'XDG_DATA_HOME', 'XDG_STATE_HOME', 'DSH_HOME', 'DSH_AGENTS_HOME'): location = root / key.lower(); location.mkdir(); env[key] = str(location) for name, data in fixtures.items(): (root / (name + '.pyc')).write_bytes(data) try: obj = marshal.loads(data[16:]) assert isinstance(obj, types.CodeType) oracle = 'accepted code object' except (ValueError, EOFError) as error: oracle = type(error).__name__ + ': ' + str(error) print(json.dumps({'oracle': name, 'bytes': len(data), 'result': oracle})) for name, options in [ ('valid', []), ('negative', []), ('negative', ['--max-string-bytes', '8388608']), ('truncated', []), ('large', []), ('large', ['--max-string-bytes', '2097152']), ]: command = [node, str(repo / 'scripts/rea.mjs'), 'inspect-python-pyc', str(root / (name + '.pyc')), *options, '--json'] run = subprocess.run(command, cwd=root, env=env, capture_output=True, text=True, timeout=30) assert run.stderr == '', run.stderr out = json.loads(run.stdout) result = out.get('normalized_result') issues = out.get('details', {}).get('issues', []) print(json.dumps({'case': name, 'options': options, 'exit': run.returncode, 'code': out.get('code'), 'category': out.get('category'), 'resource': out.get('details', {}).get('resource'), 'format_reason': issues[0]['reason'] if issues else None, 'message': out.get('message'), 'coverage': result['coverage']['status'] if result else None})) PYTHON ``` The six CLI cases and all four matching-interpreter checks were executed through an independent probe, a replay of this program, and the exact inline shell block above. The negative-length failure reproduced on all three runs at both tested string budgets; every run produced the stated control results. ## Expected behavior Once the recognized marshal string length is read, a signed-negative encoding should receive the existing malformed-input result: `invalid_request`, category `invalid_input`, with an `invalid_format` issue for `path`. It should not be interpreted as a large positive string requesting more memory. This expectation concerns typed rejection; the malformed artifact should remain refused without a successful report. Preserve real resource boundaries. The fully present positive 2 MiB constant should remain a resource refusal at the default budget and succeed at the accepted higher budget. This report does not require parsing past an earlier exhausted object/depth budget to discover a later malformed value. ## Impact and scope P2: callers receive a different machine-readable failure category and recovery direction for malformed data than for other invalid formats. The returned memory remediation recommends host/worker-memory review or a smaller artifact, neither of which corrects a signed-negative string length. This is a bounded diagnostic behavior defect affecting corrupt or handcrafted artifacts; both the current and expected paths refuse the file, and no valid artifact was observed failing because of this defect. Real-world frequency is unknown. No input mutation, incorrect successful Evidence, lost sibling inventory, process crash, resource exhaustion, severe incident, or security-boundary crossing was observed. No caller retry loop was exercised. MCP and other platforms were not run. ## REA version Unreleased source revision bcd1f95e688a2ac020a9d13f9c85e0ce321cb6b6, using its prepared compiled runtime. The CLI reports 6.7.0, but the latest published `rea-agents-6.7.0` tag lacks the standalone inspector/parser; this is a source-build finding, not a claim that the published release contains the defect. ## Runtime and platform Node.js v24.22.1; CPython 3.11.17 for inert fixture construction and independent marshal decoding; macOS 27.0.1 arm64. No native analysis engine was involved. Each REA subprocess received an explicit clean environment and isolated state directories. ## Target and artifact context Timestamp-header CPython 3.11 pycs with magic 3495, zero header flags, one root code object, and one bytes constant. The code has zero argument counts/flags, stack size 1, two bytecode bytes, and empty name/local/line/exception tables. Negative, small valid, truncated, and large fixtures contain 105, 108, 53, and 2097257 bytes respectively. The negative constant starts with `73 ff ff ff ff`; no corresponding positive-length payload exists. ## Interface CLI ## Earliest failure stage Native analysis or reconstruction ## Relevant output or evidence - Expected source: `src/python/PythonPyc.errors.ts:1-18` distinguishes corrupt recognized pycs from resource-boundary failures; `src/python/PythonPycProvider.ts:53-76` maps those cases to distinct public outcomes; `docs/python-pyc.md`, Limits and failures, describes bounded inspection and typed format failures. [CPython v3.11.17 marshal reader](https://github.com/python/cpython/blob/v3.11.17/Python/marshal.c#L1110-L1132) reads the bytes length as a signed value and rejects negative sizes before allocation; the matching runtime confirms applicability to the exact fixture. - Failure source: the executed public CLI results below; `src/python/PythonPycParser.ts:359-360,1347-1355,1379-1386` reads the bytes length with `u32()` and checks the resulting unsigned value against the string budget before the file-overrun check. The prepared compiled parser contains the same read and comparison. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete Observed result summary from the inline program: ```text CPython valid (108 bytes): accepted code object CPython negative (105 bytes): ValueError: bad marshal data (bytes object size out of range) CPython large (2097257 bytes): accepted code object CPython truncated (53 bytes): EOFError: marshal data too short CLI valid: exit 0, coverage complete CLI negative, default: exit 1, resource_constraint / resource_constraint / memory CLI negative, max-string-bytes 8388608: exit 1, resource_constraint / resource_constraint / memory CLI truncated: exit 1, invalid_request / invalid_input / invalid_format CLI large, default: exit 1, resource_constraint / resource_constraint / memory CLI large, max-string-bytes 2097152: exit 0, coverage complete ``` The negative default result reports `max_string_bytes: 1048576`, `retryable: false`, and the message quoted above. At the maximum tested budget, only the reported limit/message changes to 8388608. Both return the same remediation action: `Review the reported worker memory limits and available host memory. Retry with sufficient memory or a smaller artifact; REA retains tighter inherited limits.` The additional fields and remediation were inspected in the independently retained full CLI responses. ## Typed outcome or recovery expected For the negative string fixture at both tested string budgets, return `invalid_request` / `invalid_input` with an issue at `["path"]` whose reason is `invalid_format`. Identify malformed marshal structure rather than a memory shortage. Preserve refusal and avoid successful normalized Evidence; partial or opaque standalone recovery is not requested. ## Analysis or suspected cause Source-derived explanation: the bytes tag uses an unsigned four-byte length reader, so the signed −1 encoding becomes 4294967295 before the resource comparison. The provider then faithfully projects the resulting resource-failure type. The observed mismatch concerns the producing format interpretation; correcting generic resource-remediation wording alone would leave the wrong category. No repair was applied or tested. ## Additional context [Issue #6438](https://github.com/morluto/rea/issues/6438) concerns valid artifacts refused by intentional caller-selected budgets. Its expected restoration retains `resource_constraint` and fixes the control-specific recovery advice; this negative-length fixture instead requires the malformed-input classification. [Issue #6120](https://github.com/morluto/rea/issues/6120) concerns a separate PYZ parser and loss of healthy sibling inventory. Its closed/completed state and closure commit were checked live. The closure changes the PyInstaller parser and its tests, with no standalone-parser change. Independent public `inspect-artifact` calls at the tested baseline confirmed its separate restoration signal: negative string/list/tuple sizes abort inventory, whereas truncated and unsupported PYZ tables preserve a healthy `data.txt` sibling and an opaque PYZ. Standalone pyc has no such sibling or opaque fallback. The closure commit was inspected as source, not executed. Other canonical pyc reports cover code flags, hashability, singleton reference slots, negative line metadata, historical headers, Unicode previews, signed zero, and equality rules; no matching standalone negative-string-length report was found in the bounded open/closed searches. ## Restoration check Rerun the exact inline program after a repair. Both negative-length calls must change from `resource_constraint` to `invalid_request` / `invalid_input` with `invalid_format`, while still exiting 1. Preserve the truncated input's format refusal, the small valid fixture's complete success, and the large positive fixture's default resource refusal followed by complete success at 2 MiB. Converting every over-budget string into a format error would fail the positive control. This is a proposed check; no repaired runtime was tested. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: The public CLI exposes the wrong machine-readable category and memory-recovery direction for a recognized malformed string length, independently of the valid positive resource-control cases. The defect is bounded to malformed inputs and no severe downstream incident was observed; this changes caller-facing diagnostic behavior rather than only wording. - Workaround status: unverified - Workaround basis: No existing REA option was verified to restore the malformed-input category. Matching CPython identifies this self-authored fixture as corrupt, but that does not establish a safe general validator or replacement workflow for arbitrary untrusted marshal streams.
Author
Owner

@ezrabrilliant commented on GitHub (Oct 23, 2026):

I'd like to take this one. I've traced it to the bytes-object length being read as an unsigned value (this.blob(this.u32()) in src/python/PythonPycParser.ts), so a signed marshal length of -1 wraps to 4294967295 and gets classified as a resource_constraint/memory budget refusal instead of malformed input.

Planned fix: read the length as a signed count that rejects negative values as malformed (invalid_format), mirroring CPython's bad marshal data (bytes object size out of range) and matching the existing signedCount boundary rule already in that parser. Will add regression coverage for the negative-length case alongside the existing truncated/oversized controls and open a PR shortly.

<!-- gh-comment-id:6362842833 --> @ezrabrilliant commented on GitHub (Oct 23, 2026): I'd like to take this one. I've traced it to the bytes-object length being read as an unsigned value (`this.blob(this.u32())` in `src/python/PythonPycParser.ts`), so a signed marshal length of -1 wraps to 4294967295 and gets classified as a `resource_constraint`/memory budget refusal instead of malformed input. Planned fix: read the length as a signed count that rejects negative values as malformed (`invalid_format`), mirroring CPython's `bad marshal data (bytes object size out of range)` and matching the existing `signedCount` boundary rule already in that parser. Will add regression coverage for the negative-length case alongside the existing truncated/oversized controls and open a PR shortly.
Author
Owner

@morluto commented on GitHub (Oct 23, 2026):

Resolved on main in 06032237c. All signed counted marshal types use nonNegativeInt32 before allocation/resource checks. The executed nine-tag negative-count controls throw PythonPycFormatFailure; ordinary parser controls remain green. Validation: src/python/PythonPycParser.test.ts — classifies a negative signed marshal count (tag %i) before applying limits; recorded execution at e1d9ebd3c. Parser suite52 passed; no new CLI/MCP or CPython oracle run. Provider translation of PythonPycFormatFailure to invalid input remains the existing owner.

<!-- gh-comment-id:6376125569 --> @morluto commented on GitHub (Oct 23, 2026): Resolved on main in [06032237c](https://github.com/morluto/rea/commit/06032237c6755e3dd5f9a8db732c89958b238cc7). All signed counted marshal types use nonNegativeInt32 before allocation/resource checks. The executed nine-tag negative-count controls throw PythonPycFormatFailure; ordinary parser controls remain green. Validation: `src/python/PythonPycParser.test.ts` — classifies a negative signed marshal count (tag %i) before applying limits; recorded execution at `e1d9ebd3c`. Parser suite52 passed; no new CLI/MCP or CPython oracle run. Provider translation of PythonPycFormatFailure to invalid input remains the existing owner.
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#3990
No description provided.