[GH-ISSUE #5732] [Bug] Artifact inspection and extraction reject ZIPs with a valid executable prefix #3479

Closed
opened 2026-10-31 00:40:57 +00:00 by bsakaguchi · 2 comments
Owner

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

Originally assigned to: @kaoru0822-kitauji on GitHub.

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

Both inspect-artifact and extract-artifact reject a readable ZIP with a 17-byte inert shell prefix, returning target_unavailable / unsupported_target before inventory or extraction. The ZIP was written after the prefix, so its stored offsets include the prefix; independent readers accept it without warnings. The equivalent plain ZIP passes both REA commands. The prefix is never executed.

Reproduction

Run from a built source checkout with locked dependencies, its pinned Node runtime, Python 3, Info-ZIP and bsdtar. The following exact reproduction was independently verified and replayed during submission:

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 -I - "$work_dir" <<'PYTHON'
from pathlib import Path
import hashlib
import struct
import sys
import zipfile

root = Path(sys.argv[1])
entries = [('a.txt', b'hello world\n'), ('d/', b''), ('d/b.txt', b'x\n')]
with zipfile.ZipFile(root / 'plain.zip', 'w') as archive:
    for name, data in entries:
        archive.writestr(name, data)
(root / 'prefixed.zip').write_bytes(b'#!/bin/sh\nexit 0\n')
# Append through the ZIP writer so stored offsets include the prefix.
with zipfile.ZipFile(root / 'prefixed.zip', 'a') as archive:
    for name, data in entries:
        archive.writestr(name, data)
for name in ('plain.zip', 'prefixed.zip'):
    data = (root / name).read_bytes()
    end = data.rfind(b'PK\x05\x06')
    central = data.find(b'PK\x01\x02')
    assert struct.unpack_from('<I', data, end + 16)[0] == central
    first_local = struct.unpack_from('<I', data, central + 42)[0]
    assert data[first_local:first_local + 4] == b'PK\x03\x04'
    with zipfile.ZipFile(root / name) as archive:
        assert archive.testzip() is None
        assert [(entry.filename, archive.read(entry)) for entry in archive.infolist()] == entries
        print(name, archive.namelist())
        print([(entry.filename, hashlib.sha256(archive.read(entry)).hexdigest())
               for entry in archive.infolist()])
PYTHON
unzip -l "$work_dir/prefixed.zip"
unzip -t "$work_dir/prefixed.zip"
zipinfo -1 "$work_dir/prefixed.zip"
bsdtar -tf "$work_dir/prefixed.zip"
run_rea() {
  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 "$@"
}
for archive in plain prefixed; do
  for operation in inspect-artifact extract-artifact; do
    run_rea "$operation" "$work_dir/$archive.zip" --json       > "$work_dir/$archive.$operation.json"
    echo "$archive $operation exit=$?"
  done
done
cat "$work_dir/prefixed.inspect-artifact.json"
cat "$work_dir/prefixed.extract-artifact.json"

Both independent listing tools, unzip -t, and Python accept the prefixed archive. Each REA operation exits 0 for the plain control and 1 for the prefixed input.

Expected behavior

Inspect the original prefixed ZIP as a ZIP root with three member occurrences; extract its two regular files with the same bytes and hashes as the plain control. The prefix need not become a member or be executed.

Source-derived contract: src/contracts/artifactToolContracts.ts:82-88 advertises archive inspection and regular-file extraction. docs/tool-design.md requires limits to follow real format, protocol, authority or resource constraints. No public byte-zero ZIP admission requirement or prefixed-ZIP exclusion was found. ZIP_NON_ENTRY_LIMITATION in src/domain/zipPackageFormat.ts describes member coverage and omitted surrounding bytes; that coverage note alone is not an explicit promise to admit every prefixed layout.

Impact and scope

P2: this bounded class of readable ZIPs cannot be inspected or extracted through REA. Independent readers provide a demonstrated way to examine the original archive. Repacking its members into an ordinary ZIP was independently tested and allows both REA commands to succeed, but changes the original container identity. No data loss or security-boundary crossing was observed. Real installers, MZ stubs, longer prefixes and MCP were not tested.

REA version

rea-agents 6.7.0; source baseline 9d8e7803326a382cbbb3ffdb900f5e93e5442d68. Fetched origin/main at d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f: none of the five cited contract/failure-source files changed since the baseline. Main was source-rechecked; runtime observations are from the baseline, not a fresh main build. The latest published release checked was also 6.7.0.

Runtime and platform

Node.js v24.18.0 (repository pin); macOS 27.0.1 arm64. An earlier independent run with Node.js v26.12.0 produced the same refusal. Hopper/Ghidra are not involved.

Target and artifact context

Locally generated 309-byte ZIP beginning with #!/bin/sh and exit 0, followed by ZIP structures. Its first local header is at offset 17; actual and declared central-directory offsets are 135; the first declared local-header offset is 17. Members are a.txt, d/, and d/b.txt. The 292-byte plain control contains identical member bytes. No private target data is needed.

Interface

CLI

Earliest failure stage

Setup or provider admission

Relevant output or evidence

Observed on both prefixed CLI calls (exit 1; operand path omitted):

{
  "error": "Analysis failed",
  "code": "target_unavailable",
  "category": "unsupported_target",
  "message": "Cannot open artifact: unsupported binary format.",
  "retryable": false,
  "remediation": {
    "action": "Review the reported file-format reason and select a supported, well-formed target."
  },
  "details": {
    "reason": "unsupported binary format",
    "constraint": "file_format_rejected"
  }
}

unzip -l, unzip -t, zipinfo -1, bsdtar -tf, and Python zipfile all accept the offset-correct prefixed input with exit 0 and no warning. The plain REA inspection returns the root plus three members, with directory d/ normalized to d; extraction produces a.txt = hello world\n and d/b.txt = x\n. Evidence provenance: observed; local verification: independently reproduced and replayed at submission.

Typed outcome or recovery expected

Return inventory and extraction results for the original prefixed container, preserving its identity and regular-file bytes. Proposed restoration check: rerun both operations on that same input and compare member hashes with the plain control; preserve rejection of inputs without valid ZIP structures. Rewriting the input as an ordinary ZIP is a workaround, not proof that the original container is supported.

Analysis or suspected cause

Source-derived reasoning: src/application/BinaryTargetResolver.ts:186-214,317-333 checks hasZipSignature on a 4 KiB leading window before selecting an archive target. src/domain/zipPackageFormat.ts:20-28 examines only bytes 0-3. This rejects the prefix before the ZIP reader is reached. Root inventory separately uses the same predicate at src/artifacts/inventory/classify.ts:163, initially on an 8 KiB classification prefix; that downstream path was not reached by these failing CLI calls. The admission predicate belongs to REA; no bundled dependency was identified as the cause.

Additional context

Prepared with AI assistance and independent verification. No earlier known-good REA version or successful restoration was established. Simply concatenating a prefix with a finished ZIP also fails, but leaves stored offsets unadjusted and triggers an Info-ZIP warning; this report instead uses the offset-correct construction above.

Distinct from #4124 / #4126 (current-directory prefixes inside member names) and #2330 / #1485 / #2059 (non-entry coverage reporting). #1491 concerns false format claims based only on filename suffixes. This report asks to recognize a valid ZIP structure, not to trust its suffix or inventory the prefix as a member. #4554 concerns a dedicated CRX/XPI manifest inspector, not admission of a ZIP with an inert executable prefix.

Originally created by @coygeek on GitHub (Oct 21, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5732 Originally assigned to: @kaoru0822-kitauji on GitHub. ### 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 Both `inspect-artifact` and `extract-artifact` reject a readable ZIP with a 17-byte inert shell prefix, returning `target_unavailable` / `unsupported_target` before inventory or extraction. The ZIP was written after the prefix, so its stored offsets include the prefix; independent readers accept it without warnings. The equivalent plain ZIP passes both REA commands. The prefix is never executed. ### Reproduction Run from a built source checkout with locked dependencies, its pinned Node runtime, Python 3, Info-ZIP and bsdtar. The following exact reproduction was independently verified and replayed during submission: ```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 -I - "$work_dir" <<'PYTHON' from pathlib import Path import hashlib import struct import sys import zipfile root = Path(sys.argv[1]) entries = [('a.txt', b'hello world\n'), ('d/', b''), ('d/b.txt', b'x\n')] with zipfile.ZipFile(root / 'plain.zip', 'w') as archive: for name, data in entries: archive.writestr(name, data) (root / 'prefixed.zip').write_bytes(b'#!/bin/sh\nexit 0\n') # Append through the ZIP writer so stored offsets include the prefix. with zipfile.ZipFile(root / 'prefixed.zip', 'a') as archive: for name, data in entries: archive.writestr(name, data) for name in ('plain.zip', 'prefixed.zip'): data = (root / name).read_bytes() end = data.rfind(b'PK\x05\x06') central = data.find(b'PK\x01\x02') assert struct.unpack_from('<I', data, end + 16)[0] == central first_local = struct.unpack_from('<I', data, central + 42)[0] assert data[first_local:first_local + 4] == b'PK\x03\x04' with zipfile.ZipFile(root / name) as archive: assert archive.testzip() is None assert [(entry.filename, archive.read(entry)) for entry in archive.infolist()] == entries print(name, archive.namelist()) print([(entry.filename, hashlib.sha256(archive.read(entry)).hexdigest()) for entry in archive.infolist()]) PYTHON unzip -l "$work_dir/prefixed.zip" unzip -t "$work_dir/prefixed.zip" zipinfo -1 "$work_dir/prefixed.zip" bsdtar -tf "$work_dir/prefixed.zip" run_rea() { 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 "$@" } for archive in plain prefixed; do for operation in inspect-artifact extract-artifact; do run_rea "$operation" "$work_dir/$archive.zip" --json > "$work_dir/$archive.$operation.json" echo "$archive $operation exit=$?" done done cat "$work_dir/prefixed.inspect-artifact.json" cat "$work_dir/prefixed.extract-artifact.json" ``` Both independent listing tools, `unzip -t`, and Python accept the prefixed archive. Each REA operation exits 0 for the plain control and 1 for the prefixed input. ### Expected behavior Inspect the original prefixed ZIP as a ZIP root with three member occurrences; extract its two regular files with the same bytes and hashes as the plain control. The prefix need not become a member or be executed. Source-derived contract: `src/contracts/artifactToolContracts.ts:82-88` advertises archive inspection and regular-file extraction. `docs/tool-design.md` requires limits to follow real format, protocol, authority or resource constraints. No public byte-zero ZIP admission requirement or prefixed-ZIP exclusion was found. `ZIP_NON_ENTRY_LIMITATION` in `src/domain/zipPackageFormat.ts` describes member coverage and omitted surrounding bytes; that coverage note alone is not an explicit promise to admit every prefixed layout. ### Impact and scope P2: this bounded class of readable ZIPs cannot be inspected or extracted through REA. Independent readers provide a demonstrated way to examine the original archive. Repacking its members into an ordinary ZIP was independently tested and allows both REA commands to succeed, but changes the original container identity. No data loss or security-boundary crossing was observed. Real installers, MZ stubs, longer prefixes and MCP were not tested. ### REA version `rea-agents` 6.7.0; source baseline `9d8e7803326a382cbbb3ffdb900f5e93e5442d68`. Fetched `origin/main` at `d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f`: none of the five cited contract/failure-source files changed since the baseline. Main was source-rechecked; runtime observations are from the baseline, not a fresh main build. The latest published release checked was also 6.7.0. ### Runtime and platform Node.js v24.18.0 (repository pin); macOS 27.0.1 arm64. An earlier independent run with Node.js v26.12.0 produced the same refusal. Hopper/Ghidra are not involved. ### Target and artifact context Locally generated 309-byte ZIP beginning with `#!/bin/sh` and `exit 0`, followed by ZIP structures. Its first local header is at offset 17; actual and declared central-directory offsets are 135; the first declared local-header offset is 17. Members are `a.txt`, `d/`, and `d/b.txt`. The 292-byte plain control contains identical member bytes. No private target data is needed. ### Interface CLI ### Earliest failure stage Setup or provider admission ### Relevant output or evidence Observed on both prefixed CLI calls (exit 1; operand path omitted): ```json { "error": "Analysis failed", "code": "target_unavailable", "category": "unsupported_target", "message": "Cannot open artifact: unsupported binary format.", "retryable": false, "remediation": { "action": "Review the reported file-format reason and select a supported, well-formed target." }, "details": { "reason": "unsupported binary format", "constraint": "file_format_rejected" } } ``` `unzip -l`, `unzip -t`, `zipinfo -1`, `bsdtar -tf`, and Python zipfile all accept the offset-correct prefixed input with exit 0 and no warning. The plain REA inspection returns the root plus three members, with directory `d/` normalized to `d`; extraction produces `a.txt` = `hello world\n` and `d/b.txt` = `x\n`. Evidence provenance: observed; local verification: independently reproduced and replayed at submission. ### Typed outcome or recovery expected Return inventory and extraction results for the original prefixed container, preserving its identity and regular-file bytes. Proposed restoration check: rerun both operations on that same input and compare member hashes with the plain control; preserve rejection of inputs without valid ZIP structures. Rewriting the input as an ordinary ZIP is a workaround, not proof that the original container is supported. ### Analysis or suspected cause Source-derived reasoning: `src/application/BinaryTargetResolver.ts:186-214,317-333` checks `hasZipSignature` on a 4 KiB leading window before selecting an archive target. `src/domain/zipPackageFormat.ts:20-28` examines only bytes 0-3. This rejects the prefix before the ZIP reader is reached. Root inventory separately uses the same predicate at `src/artifacts/inventory/classify.ts:163`, initially on an 8 KiB classification prefix; that downstream path was not reached by these failing CLI calls. The admission predicate belongs to REA; no bundled dependency was identified as the cause. ### Additional context Prepared with AI assistance and independent verification. No earlier known-good REA version or successful restoration was established. Simply concatenating a prefix with a finished ZIP also fails, but leaves stored offsets unadjusted and triggers an Info-ZIP warning; this report instead uses the offset-correct construction above. Distinct from #4124 / #4126 (current-directory prefixes inside member names) and #2330 / #1485 / #2059 (non-entry coverage reporting). #1491 concerns false format claims based only on filename suffixes. This report asks to recognize a valid ZIP structure, not to trust its suffix or inventory the prefix as a member. #4554 concerns a dedicated CRX/XPI manifest inspector, not admission of a ZIP with an inert executable prefix.
Author
Owner

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

Independently reproduced on built main d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f, macOS arm64, Node 24.18.0. The same Python zipfile-created member list passes both inspect-artifact and extract-artifact without a prefix (exit 0), but adding a 17-byte inert shell prefix through the ZIP writer makes both commands return target_unavailable / unsupported binary format (exit 1). Python zipfile.testzip() and exact member-byte reads accept both originals. A truncated-marker negative control is refused by both commands. All six CLI calls preserve input SHA-256. The prefix was never executed. This confirms the reported root-admission failure on this captured main; installed-package/MCP and a fix have not been tested yet. I am preparing a shared recognition fix; no upstream PR exists from my branch yet.

Local source preparation update (2026-10-21)

The shared root-input fix is now committed and normally pushed to my fork: github.com/xu91102/rea@a23559d861. The final source is based on d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f. It recognizes an EOF ZIP end record only for an otherwise unrecognized root, retains the complete carrier hash, and delegates directory/member validation to the existing ZIP reader. Native-format refusals and established ASAR/plist/map/JavaScript filename routing retain their previous behavior; no prefix is executed.

Final validation: 14 focused files / 197 PASS, plus five fresh README checks (15 distinct files / 202 PASS / 0 skip). Check, docs, discovery (1,880 files once), installed-package verification and explicit pack dry run pass. The same original six compiled CLI controls and two ASAR-preservation controls pass; a fresh tarball's 1,974 installed files match, six installed CLI controls and one real stdio MCP session (four open/inspect/extract/close calls) preserve source hashes and exact member bytes. The package reports 212 tools and six prompts. Independent Standards and Spec review of the final frozen patch both pass. Two review-found routing regressions were first reproduced and then fixed at their shared owners.

This is fork source preparation, not an upstream PR or upstream CI result. I have not created an upstream PR for this fix because the account's three existing open PRs are unchanged and no new legitimate capacity restoration is established. Full agent/model workflows, Windows/Linux runtime, native installer launch, nested prefixed carriers and performance qualification were not run. An earlier excluded harness run's full log was accidentally overwritten and only its original tail recovered; current acceptance has separate complete final logs, with original product/review regression failures retained.

2026-10-21: overlapping upstream implementation; local branch held

I have read the complete production diff of #5803 at 93e55760ef7a6daa23e630afcfc22c36f4f391ed (kaoru0822-kitauji). It addresses the same ZIP root-admission problem in BinaryTargetResolver and inventory classification, using a trailing-directory locator and shared ZIP root roles. That algorithm differs from my footer-admission helper, but the production root overlaps, so I have put my fork branch at a23559d8617ee1e06fae036e12e5be1ab34e5570 on read-only hold and will not submit a duplicate PR or repackage residual cases.

At this check #5803 is open and unmerged. I have not run its head and do not claim it covers every local control, uses my source, or gives me author credit. My previous results remain evidence only for my frozen local branch; no upstream PR or CI was created for that branch. The issue state is unchanged by this update.

2026-10-22: upstream implementation merged; local hold continues

PR #5803 was merged on 2026-10-21 at 12:06:29 UTC as 35d6d5bb0acaf8cd99399c1167dfef309d6add19, and this issue was closed at 12:06:30 UTC. I read the complete actual merge patch, including its four production files, and confirmed that commit is an ancestor of the captured current main 421d527bfefa7c268ccb1e6aca68d59e45ebe643. Its shared root-admission and root-format changes address the same reported problem.

My branch remains read-only at a23559d8617ee1e06fae036e12e5be1ab34e5570; I did not create an upstream PR, close this issue, or execute the foreign or merged ZIP workflow. My earlier local tests and package/MCP results do not qualify the merged implementation. Adoption of my fork source or author credit is not established. I will not repackage residual ZIP/native/ASAR/CLI/MCP/docs cases as a replacement contribution.

<!-- gh-comment-id:6305473882 --> @xu91102 commented on GitHub (Oct 21, 2026): Independently reproduced on built main `d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f`, macOS arm64, Node 24.18.0. The same Python `zipfile`-created member list passes both `inspect-artifact` and `extract-artifact` without a prefix (exit 0), but adding a 17-byte inert shell prefix through the ZIP writer makes both commands return `target_unavailable` / `unsupported binary format` (exit 1). Python `zipfile.testzip()` and exact member-byte reads accept both originals. A truncated-marker negative control is refused by both commands. All six CLI calls preserve input SHA-256. The prefix was never executed. This confirms the reported root-admission failure on this captured main; installed-package/MCP and a fix have not been tested yet. I am preparing a shared recognition fix; no upstream PR exists from my branch yet. ### Local source preparation update (2026-10-21) The shared root-input fix is now committed and normally pushed to my fork: https://github.com/xu91102/rea/commit/a23559d8617ee1e06fae036e12e5be1ab34e5570. The final source is based on `d0067ba34a39ea47dd7e11bb2e6169bc0938cc3f`. It recognizes an EOF ZIP end record only for an otherwise unrecognized root, retains the complete carrier hash, and delegates directory/member validation to the existing ZIP reader. Native-format refusals and established ASAR/plist/map/JavaScript filename routing retain their previous behavior; no prefix is executed. Final validation: 14 focused files / 197 PASS, plus five fresh README checks (15 distinct files / 202 PASS / 0 skip). Check, docs, discovery (1,880 files once), installed-package verification and explicit pack dry run pass. The same original six compiled CLI controls and two ASAR-preservation controls pass; a fresh tarball's 1,974 installed files match, six installed CLI controls and one real stdio MCP session (four open/inspect/extract/close calls) preserve source hashes and exact member bytes. The package reports 212 tools and six prompts. Independent Standards and Spec review of the final frozen patch both pass. Two review-found routing regressions were first reproduced and then fixed at their shared owners. This is fork source preparation, not an upstream PR or upstream CI result. I have not created an upstream PR for this fix because the account's three existing open PRs are unchanged and no new legitimate capacity restoration is established. Full agent/model workflows, Windows/Linux runtime, native installer launch, nested prefixed carriers and performance qualification were not run. An earlier excluded harness run's full log was accidentally overwritten and only its original tail recovered; current acceptance has separate complete final logs, with original product/review regression failures retained. ### 2026-10-21: overlapping upstream implementation; local branch held I have read the complete production diff of #5803 at `93e55760ef7a6daa23e630afcfc22c36f4f391ed` (kaoru0822-kitauji). It addresses the same ZIP root-admission problem in `BinaryTargetResolver` and inventory classification, using a trailing-directory locator and shared ZIP root roles. That algorithm differs from my footer-admission helper, but the production root overlaps, so I have put my fork branch at `a23559d8617ee1e06fae036e12e5be1ab34e5570` on read-only hold and will not submit a duplicate PR or repackage residual cases. At this check #5803 is open and unmerged. I have not run its head and do not claim it covers every local control, uses my source, or gives me author credit. My previous results remain evidence only for my frozen local branch; no upstream PR or CI was created for that branch. The issue state is unchanged by this update. ### 2026-10-22: upstream implementation merged; local hold continues PR #5803 was merged on 2026-10-21 at 12:06:29 UTC as [`35d6d5bb0acaf8cd99399c1167dfef309d6add19`](https://github.com/morluto/rea/commit/35d6d5bb0acaf8cd99399c1167dfef309d6add19), and this issue was closed at 12:06:30 UTC. I read the complete actual merge patch, including its four production files, and confirmed that commit is an ancestor of the captured current main `421d527bfefa7c268ccb1e6aca68d59e45ebe643`. Its shared root-admission and root-format changes address the same reported problem. My branch remains read-only at `a23559d8617ee1e06fae036e12e5be1ab34e5570`; I did not create an upstream PR, close this issue, or execute the foreign or merged ZIP workflow. My earlier local tests and package/MCP results do not qualify the merged implementation. Adoption of my fork source or author credit is not established. I will not repackage residual ZIP/native/ASAR/CLI/MCP/docs cases as a replacement contribution.
Author
Owner

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

Supporting the recognition fix direction. A prefixed ZIP (self-extracting style) is a legitimate, widely-produced format — Info-ZIP and bsdtar read it without warnings, so rejecting on a plain PK magic check will keep tripping real artifacts. The fix should locate the End of Central Directory record from the tail and derive the start offset from its fields, instead of requiring the archive at byte 0. One caution: once prefixed ZIPs are admitted, extraction must keep the zip-slip / path-containment checks and ideally verify the central directory offsets against the actual file length, otherwise a truncated marker plus a forged EOCD could bypass the negative control you mentioned.

<!-- gh-comment-id:6305893935 --> @XinwangTao commented on GitHub (Oct 21, 2026): Supporting the recognition fix direction. A prefixed ZIP (self-extracting style) is a legitimate, widely-produced format — Info-ZIP and bsdtar read it without warnings, so rejecting on a plain PK magic check will keep tripping real artifacts. The fix should locate the End of Central Directory record from the tail and derive the start offset from its fields, instead of requiring the archive at byte 0. One caution: once prefixed ZIPs are admitted, extraction must keep the zip-slip / path-containment checks and ideally verify the central directory offsets against the actual file length, otherwise a truncated marker plus a forged EOCD could bypass the negative control you mentioned.
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#3479
No description provided.