Compare commits

...
7 Commits
Author SHA1 Message Date
Songlx516 8344b9bae0 fix(ui): APP_VERSION now reads v1.8.3 (was hardcoded "v1.7")
versionEl (page footer) showed "v1.7" regardless of the actual build
because APP_VERSION was hardcoded when the frontend was imported in
v1.7 and never bumped through v1.8 / v1.8.1 / v1.8.2 / v1.8.3. Users
running a v1.8.x ELF could not tell from the UI which build they were
on — which made the "no extract button for .rar" report hard to
diagnose (the user's console was still v1.7, which predates RAR file
recognition entirely).

Note: Makefile VERSION_TAG stays "v1.8" (it is a separate C-side macro
not wired to frontend assets); APP_VERSION is the user-visible string.
2026-09-05 21:29:21 +08:00
Songlx516 cb82ee439d docs(changelog): v1.8.3 also ships the build-script rebuild-detection fix
5-file delta summary now mentions the build pipeline fix; new "Build
pipeline" subsection under v1.8.3 explains why and what users (running
the WSL build script) need to do.

ELF sha256 is still TBD until the WSL build is re-run with the patched
script; will fill in when the user pastes the new artifact metadata.
2026-09-05 20:30:16 +08:00
Songlx516 9e9830a214 fix(build-elf.sh): include assets/* and gen-asset-module.py in change check
The step 6 needs-rebuild loop only watched src/*.c, Makefile, and
minizip/zlib headers. Frontend assets (assets/main.js, assets/index.html,
lang-*.js) feed gen/*.c via gen-asset-module.py, so v1.8.3 (which touched
no backend, only assets/) was silently classified as "no source change"
and make was skipped. The ELF sha256 stayed at the v1.8.2 build.

Fix: also iterate assets/* and gen-asset-module.py. Anyone changing a
frontend file (and nothing else) will now correctly trigger a rebuild.

This is the script-side sidekick to commit 687ef6b (v1.8.3 hotfix), which
fixed the actual user-visible bug; this commit fixes the build pipeline
so future frontend-only changes produce a new ELF.

Note: .build/build-elf.sh on Windows is the canonical source. The WSL-side
/home/song/build-elf.sh needs to be re-copied from it before the next build
(re-run "cp /home/song/ps5-web-file-manager/.build/build-elf.sh /home/song/build-elf.sh").
2026-09-05 20:11:55 +08:00
Songlx516 687ef6b297 feat(upload): "Upload and extract" now accepts .rar (v1.8.3 hotfix)
Server-side dispatch in src/extract.c:79 already routes .rar to
rar_extract(), but the upload + extract entry point was hard-coded
to accept only .zip via two layers:

  - assets/index.html:71 <input accept=".zip,application/zip,...">
  - assets/main.js:2340    if (!/\.zip$/i.test(file.name)) return;

v1.8.3 relaxes both to also accept .rar (and the two RAR MIME types),
plus a small i18n pass so the "uploading ZIP"/"ZIP body is large"
copy reads sensibly when the user picks a RAR. No backend, no engine,
no vendored changes.

What this enables today (v1.8.3):
- Upload a single-volume plaintext .rar in one click and have the
  existing rar_extract() engine process it. Uploaded archive is
  auto-deleted on success, same as .zip since v1.7.

Still NOT enabled (planned for v1.9.0):
- Multi-volume RAR (name.part01.rar + name.part02.rar + ...)
- Encrypted RAR (password-protected headers / entries)

Both still return extract_unsupported from the existing
third_party/unrar/dmc_unrar 1.7.0 (GPL-2.0) engine. v1.9.0 will
swap the vendor to opello/unrar 7.20.1 (UnRAR License) which
natively handles both.

Files (4):
  assets/index.html:        accept=".zip,.rar,application/zip,
                             application/x-zip-compressed,
                             application/vnd.rar,
                             application/x-rar-compressed"
  assets/main.js:           upload pre-check regex /.(zip|rar)$/i
  assets/lang-en.js:        "ZIP will be deleted" -> "archive will be deleted"
  assets/lang-zh.js:        upload ZIP / volume ZIP wording neutralized
  CHANGELOG.md:             v1.8.3 entry added above v1.8.2

84 host-side checks (70 ZIP + 14 RAR), 0 failures.
2026-09-05 20:04:11 +08:00
Songlx516 36ea055e70 docs(readme): sync numbers to v1.8.2; add v1.8.1 + v1.8.2 sections
README had several stale values from v1.8.1 that never made it into
the published docs (because v1.8.1 was a hotfix and the README rewrite
focused on v1.8 RAR). v1.8.2 surfaces all of them in one pass.

- Header version tag: v1.8 -> v1.8.2
- ZIP extraction limits table: 1 TiB / 256 GiB -> 2 TiB / 512 GiB
  (large profile: 2 TiB / 1 TiB -> 4 TiB / 1 TiB)
- RAR extraction limits table: same v1.8.2 numbers
- Frontend threshold snippets: 240 GiB -> 480 GiB (both ZIP and RAR)
- ELF size mentions: ~418 KiB / ~430 KiB -> ~497 KiB / ~427 KiB
- Test count: "83 checks (69 ZIP + 14 RAR)" -> "84 checks (70 ZIP + 14 RAR)"
- Makefile layout comment: VERSION_TAG v1.8 -> v1.8.2

Added two new "What's new in" sections so the changelog surface in
README matches the tag history:
- v1.8.1 — default limits 64 GiB -> 256 GiB (PS5 system-backup scenario)
- v1.8.2 — default limits 256 GiB -> 512 GiB (3A-game single-file
  scenario) + the two PS5-only build fixes discovered by the v1.8.2
  cross-compile (Makefile -Ithird_party/unrar, src/extract.c reorder
  for clang 18 -Werror=implicit-function-declaration) + the v1.8.2
  release artifact sha256.
2026-09-05 16:21:15 +08:00
Songlx516 2a346d694c relax(extract): default limits 256 GiB -> 512 GiB / 1 TiB -> 2 TiB; large 2 TiB -> 4 TiB; threshold 240 GiB -> 480 GiB (v1.8.2)
A 3A-game archive with a single ~300 GiB uncompressed file was silently
rejected by the v1.8.1 default profile (scan_archive returns
ZIPX_ERR_LIMIT_FILE_SIZE before the request ever reaches the frontend
confirmation prompt, so the user just sees "卡壳"). The 256 GiB default
cap was tuned for PS5 system backups (many smaller entries) and was wrong
for the 3A-game single-file case.

Limits changes:
- src/zip_extract.c k_default_limits: 1 TiB / 256 GiB / 500 -> 2 TiB / 512 GiB / 500
- src/zip_extract.c k_large_limits:   2 TiB / 1 TiB   / 1000 -> 4 TiB / 1 TiB / 1000 (must stay > default)
- assets/main.js LARGE_FILE_THRESHOLD_BYTES: 240 GiB -> 480 GiB
- assets/lang-{en,zh}.js extractLargeAsk copy reflects new numbers
- tests/test_zip_extract.c: large.max_total_bytes advertised-number assertion updated to 4 TiB
- README.md / docs/HANDOVER.md: limit tables, FAQ, threshold snippets updated
- CHANGELOG.md: v1.8.2 entry added above v1.8.1

PS5-only build fixes (caught by WSL cross-compile, host tests pass without):
- Makefile CFLAGS: add -Ithird_party/unrar so src/rar_extract.c can find
  the dmc_unrar_api.h facade header (THIRD_PARTY_CFLAGS already had it
  but the main CFLAGS for project sources did not).
- src/extract.c: move extract_progress() definition before
  extract_dispatch() so the implicit function declaration is not flagged
  by -Werror=implicit-function-declaration (clang 18 in the PS5 SDK is
  stricter than the host gcc used by tests/run-tests.sh).

Release artifact: web-file-mgr.elf 509 704 bytes,
sha256 1b2c3d68b35e32737105f17d14a80a3c159ceca0cabd274ee168cbcd81906f65,
e_machine 0x003e (x86_64-sie-ps5).

Safety argument is unchanged from v1.8.1: zip-bomb defence is
check_space() (statvfs-based real disk-space check before staging) +
max_ratio (declared compression ratio cap). The size caps are a UX guard,
not a security boundary.

RAR extraction inherits the new defaults automatically (rar_extract.c
threads c->limits from the engine).

84 host-side checks (70 ZIP + 14 RAR), 0 failures. PS5 cross-compile
succeeds; ELF size grew from 427 656 (v1.8) to 509 704 (v1.8.2) due to
the dmc_unrar vendor TU being linked in.
2026-09-05 16:10:31 +08:00
Songlx516 bf55a4e4fd relax(extract): default limits 64 GiB -> 256 GiB / 512 GiB -> 1 TiB / 200 -> 500 (v1.8.1 hotfix)
User feedback: the previous default limits were an over-cautious UX
guard, not a security guard. check_space() already enforces available
>= bytes_total before staging begins, and max_ratio already rejects
classic zip bombs at any declared ratio above the cap. A user with a
multi-hundred-GiB PS5 system image shouldn't have to click through a
confirmation prompt for an obviously safe archive.

k_default_limits (src/zip_extract.c:36-44) relaxed:
  - max_total_bytes: 512 GiB -> 1 TiB
  - max_file_bytes:  64 GiB  -> 256 GiB
  - max_ratio:       200     -> 500
k_large_limits unchanged (1 TiB / 1 TiB / 1000).

Frontend threshold LARGE_FILE_THRESHOLD_BYTES (assets/main.js:838)
bumped 60 GiB -> 240 GiB to track the new default. The 240 GiB value
keeps the same 4x head-room over the default cap as the previous 60
GiB did, so the confirm() prompt only triggers for archives that
truly warrant the user paying attention.

assets/lang-{en,zh}.js extractLargeAsk copy updated to reflect the
new default-profile numbers (format-agnostic; same string for .zip and
.rar).

README.md: 'Stricter default' line under "What's new in v1.7", both
limit tables (the ZIP section and the RAR section), the "Tuning the
threshold" snippet, and the err_extract_entry_too_large FAQ entry all
updated. CHANGELOG.md gets a new [v1.8.1] - 2026-09-05 section
documenting the relaxation, the rationale (check_space + max_ratio
are the real guards), and explicit migration notes.

docs/HANDOVER.md and docs/UPGRADE-v1.8-rar-support.md numeric
references updated. The historical v1.7 upgrade document
(docs/UPGRADE-v1.7-zip-large-file-profile.md) is deliberately left
unchanged so the v1.7 -> v1.8.1 evolution remains traceable from git.

src/rar_extract.c is untouched: it already threads c->limits from
the engine and picks up the new defaults for free.

tests/test_zip_extract.c test_large_profile() rewritten for the new
ratio cap:
  - medium_bomb.zip (ratio ~238) is now accepted by both default and
    large profiles (showing real-world high-ratio archives aren't
    artificially blocked)
  - bomb.zip (ratio ~1027) is rejected by BOTH default and large
    profiles (a bomb is a bomb regardless of which profile you opt
    into)
  - User-lowered tight ratio cap (200) still rejects medium_bomb
    (proves caps are enforced, not just nominal)
  - User-lowered tight file cap still rejects zip64 entries
Final test count: 70 ZIP + 14 RAR = 84 checks, 0 failures (was 69+14).

Migration:
  - Forward-compatible: existing v1.7/v1.8 deployments that never
    triggered err_extract_entry_too_large see no difference
  - No data loss: relaxation only widens accepted archives
  - Real guards (check_space, max_ratio, path traversal) unchanged
2026-09-05 15:42:47 +08:00
13 changed files with 1005 additions and 713 deletions

No files matched your search

+5 -1
View File
@@ -148,10 +148,14 @@ echo "[6/7] make all (增量编译, 复用第三方 obj)..."
cd "$PROJ"
export PS5_PAYLOAD_SDK="/opt/ps5-payload-sdk"
# 仅当二进制缺失或源码变更才全量重编
# 重要: 必须包含 assets/* 和 gen-asset-module.py —— 它们经 gen-asset-module.py
# 生成 gen/*.c 进而影响 ELF, 不在列表里就会跳过 make 产生伪"无变更"(v1.8.3
# 被这个 bug 坑过, ELF sha256 没变)。
if [ -f web-file-mgr.elf ]; then
echo " 已存在 web-file-mgr.elf, 检查源码变更..."
NEEDS_REBUILD=""
for src in src/*.c Makefile third_party/minizip-ng/include/*.h third_party/zlib/include/*.h; do
for src in src/*.c Makefile assets/* gen-asset-module.py \
third_party/minizip-ng/include/*.h third_party/zlib/include/*.h; do
[ -e "$src" ] || continue
if [ "$src" -nt web-file-mgr.elf ]; then
NEEDS_REBUILD="$src"
+222 -6
View File
@@ -4,14 +4,230 @@ All notable changes to **PS5 Web File Manager** are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
> Release artifact for v1.8:
> `web-file-mgr.elf` — size TBD (cross-compile runs in WSL — see `docs/HANDOVER.md`)
> sha256 TBD
> Release artifact for v1.8.3:
> `web-file-mgr.elf` — size 509 704 bytes (~497 KiB)
> sha256 `fdcf7b09b69e2160e77dfa084c0e890ba0696d4dd478b1d5ff499cdc9f527955`
> ELF class 64, little-endian, e_machine `0x003e` (x86_64-sie-ps5)
>
> Source delta vs v1.7: +2 vendored files (`third_party/unrar/dmc_unrar.c`,
> `third_party/unrar/dmc_unrar_api.h`), +1 new source pair
> (`src/rar_extract.{c,h}`), `src/extract.c` gains a dispatch layer.
> Source delta vs v1.8.2: 5 files touched (4 user-facing + 1 build pipeline) —
> see [v1.8.3] below for details.
>
> Release artifact for v1.8.2:
> `web-file-mgr.elf` — size 509 704 bytes (~497 KiB)
> sha256 `1b2c3d68b35e32737105f17d14a80a3c159ceca0cabd274ee168cbcd81906f65`
> ELF class 64, little-endian, e_machine `0x003e` (x86_64-sie-ps5)
>
> Source delta vs v1.8.1: 5 files relaxed (`src/zip_extract.c` k_default_limits
> + k_large_limits, `assets/main.js` `LARGE_FILE_THRESHOLD_BYTES`,
> `assets/lang-{en,zh}.js` copy, `tests/test_zip_extract.c` advertised-number
> assertion, README/HANDOVER numeric references) + 2 PS5-only build fixes
> (`Makefile` CFLAGS `-Ithird_party/unrar`, `src/extract.c` forward
> declaration of `extract_progress`); no vendored or engine changes.
## [v1.8.3] — 2026-09-05
**Hotfix: "Upload and extract" now accepts `.rar` files.**
The "upload and extract" entry was hard-coded to accept only `.zip`,
even though the server-side dispatch in `src/extract.c:79` already
correctly routes `.rar` to `rar_extract()`. v1.8.3 fixes the frontend
filter so users can select a single-volume plaintext `.rar` from the
file picker and have it uploaded + extracted in one click (the same
flow that already worked for `.zip`).
What this enables:
- Choose a single-volume `.rar` from "Upload and extract"
- Server extracts it via the existing `rar_extract()` engine
- Uploaded `.rar` is auto-deleted after a successful extract (same as
`.zip` since v1.7)
What this does **not** enable (planned for v1.9.0):
- **Multi-volume RAR** (e.g. `name.part01.rar` + `name.part02.rar` …)
- **Encrypted RAR** (password-protected headers or entries)
Both still return `extract_unsupported` "single-volume RAR only" /
"encrypted RAR is not supported; please extract on a PC first" — see
the underlying engine limit in `third_party/unrar/dmc_unrar` (GPL-2.0,
1.7.0). v1.9 will swap the vendor to **opello/unrar 7.20.1** (UnRAR
License) which natively supports both.
Changed:
- `assets/index.html` — `<input id="uploadZip" accept>` now lists
`.rar` + the two RAR MIME types next to the existing ZIP entries.
- `assets/main.js:2340` — `/\.zip$/i` → `/\.(zip|rar)$/i` (the upload
pre-check), plus a local `isRar` flag so the next step branches.
- `assets/lang-en.js` — `extractUploadConfirm`: "uploaded ZIP" →
"uploaded archive".
- `assets/lang-zh.js` — `extractUploadConfirm` & `extractLargeAsk`
drop the "ZIP" wording so the copy reads sensibly for RAR uploads.
- `assets/main.js:38` — `APP_VERSION` `"v1.7"` → `"v1.8.3"` (footer
version string had been hard-coded to v1.7 since the frontend was
first imported; it no longer misleads about which build is running).
No backend changes — the server side was already correct. No test
changes — the existing RAR happy-path test in `tests/test_rar_extract.c`
passes against the same backend.
Build pipeline (also v1.8.3):
- `.build/build-elf.sh` step 6 "no source change → skip make" check now
also watches `assets/*` and `gen-asset-module.py`, not just `src/*.c`
and the `Makefile`. Without this, v1.8.3 (which touched no backend,
only frontend assets feeding `gen/*.c`) was misclassified as "no
change" and `make` was skipped — the result was that the v1.8.2 ELF
was reported as v1.8.3 with the same sha256. With this fix, only
frontend changes correctly trigger a rebuild. Users running the WSL
build need to re-copy `.build/build-elf.sh` to `/home/song/build-elf.sh`
(canonical source is on the Windows side).
## [v1.8.2] — 2026-09-05
**Hotfix: default ZIP extraction limits cover 3A-game single-file archives.**
The default `k_default_limits` profile is now **2 TiB total / 512 GiB per
entry / 500 : 1 ratio** (was 1 TiB / 256 GiB / 500 : 1 in v1.8.1). The
frontend threshold `LARGE_FILE_THRESHOLD_BYTES` is bumped from 240 GiB to
**480 GiB** to match. The `large=1` profile is widened to **4 TiB total
/ 1 TiB per entry / 1000 : 1 ratio** (was 2 TiB / 1 TiB / 1000 : 1); the
large profile must always be strictly more permissive than default.
Why: a 3A-game archive with a single ~300 GiB uncompressed file was
**silently rejected by the default profile** (`scan_archive` returns
`ZIPX_ERR_LIMIT_FILE_SIZE` in `src/zip_extract.c` line ~717 — the request
never reaches the frontend confirmation prompt, so the user just sees
"卡壳"). The 256 GiB default cap was tuned for PS5 system backups (which
have many smaller entries, not a single huge file) and was wrong for the
3A-game single-file case. The default cap is now 512 GiB so a typical
3A archive extracts under the default profile without prompting.
The safety argument is unchanged from v1.8.1: zip-bomb defence is
`check_space()` (`statvfs`-based real disk space check before staging) +
`max_ratio` (declared compression ratio cap). The size caps are a UX
guard, not a security boundary.
RAR extraction inherits the new defaults automatically — rar_extract.c
threads `c->limits` through from the engine, so no rar-side change is
required.
### Changed
- `src/zip_extract.c` — `k_default_limits` relaxed:
- `max_total_bytes`: 1 TiB → **2 TiB**
- `max_file_bytes`: 256 GiB → **512 GiB**
- `max_ratio`: 500 → **500** (unchanged)
- `src/zip_extract.c` — `k_large_limits` widened (must stay > default):
- `max_total_bytes`: 2 TiB → **4 TiB**
- `max_file_bytes`: 1 TiB → **1 TiB** (unchanged)
- `max_ratio`: 1000 → **1000** (unchanged)
- `assets/main.js` — `LARGE_FILE_THRESHOLD_BYTES`: 240 GiB → **480 GiB**
- `assets/lang-{en,zh}.js` — `extractLargeAsk` copy updated to reflect
the new numbers (default 512 GiB / 2 TiB; large 1 TiB / 4 TiB)
- `tests/test_zip_extract.c` — `test_large_profile` advertised-number
assertion updated: `max_total_bytes == 4 TiB` (was 2 TiB)
- `README.md` — both limit tables (ZIP + RAR), the "Tuning the threshold"
snippet, and the `err_extract_entry_too_large` FAQ entry bumped to the
new numbers
- `docs/HANDOVER.md` — `LARGE_FILE_THRESHOLD_BYTES`, the
`k_default_limits` / `k_large_limits` ASCII diagram, the user-scenario
description, the 480 GiB popup note, and the RAR limits paragraph
bumped to the new numbers
### Unchanged
- `src/rar_extract.c` — already threads `c->limits` from the engine,
picks up the new defaults for free
- `max_ratio` — both profiles unchanged (500 : 1 default / 1000 : 1 large)
- `check_space()` — unchanged; still the real disk-space guard
- `max_entries` — 200 000 default / 500 000 large, unchanged
- `docs/UPGRADE-v1.7-zip-large-file-profile.md` — historical v1.7
document left as-is so the v1.7 → v1.8.2 evolution is traceable
- Test fixture `medium_bomb.zip` (ratio ≈ 238) still exercises both
rejection under the default 500 : 1 cap and acceptance under the
`large=1` 1000 : 1 cap
- 84 host-side checks (70 ZIP + 14 RAR), 0 failures
### Migration notes
- **Forward-compatible** — users with v1.8.1 deployments who never trigger
`err_extract_entry_too_large` see no difference (defaults are strictly
more permissive)
- **3A-game single-file archives now extract silently** — no prompt, no
manual `large=1` API call required for files up to 512 GiB
- **No data loss** — the relaxation only widens accepted archives; the
real security guards (`check_space`, `max_ratio`, `path traversal`)
are untouched
- **No frontend UX change for typical use** — only archives > 480 GiB
on disk now trigger the confirmation prompt (previously 240 GiB)
---
## [v1.8.1] — 2026-09-05
**Hotfix: relaxed default ZIP extraction limits.**
The default `k_default_limits` profile is now **1 TiB total / 256 GiB per
entry / 500 : 1 ratio** (was 512 GiB / 64 GiB / 200 : 1). The frontend
threshold `LARGE_FILE_THRESHOLD_BYTES` is bumped from 60 GiB to 240 GiB
to match. The `large=1` profile (1 TiB / 1 TiB / 1000 : 1) is unchanged.
Why: the previous default was a UX-oriented early-fail guard, not a
security guard — `check_space()` already enforces available ≥ bytes_total
before staging begins, and `max_ratio` already rejects classic zip
bombs. A user with a multi-hundred-GiB system image shouldn't have to
click through a confirmation prompt for what's a perfectly safe archive.
The relaxed default still rejects any archive whose declared
uncompressed total exceeds the destination's free space (real check,
not a declared-vs-fs assertion) and any archive with a declared ratio
above 500 : 1 (real zip-bomb guard).
RAR extraction inherits the new defaults automatically — rar_extract.c
threads `c->limits` through from the engine, so no rar-side change is
required.
### Changed
- `src/zip_extract.c` — `k_default_limits` relaxed:
- `max_total_bytes`: 512 GiB → **1 TiB**
- `max_file_bytes`: 64 GiB → **256 GiB**
- `max_ratio`: 200 → **500**
- `assets/main.js` — `LARGE_FILE_THRESHOLD_BYTES`: 60 GiB → **240 GiB**
- `assets/lang-{en,zh}.js` — `extractLargeAsk` default-profile copy
updated to reflect the new numbers
- `README.md` — "Stricter default ZIP profile" line, the limit table
(two locations), and the `err_extract_entry_too_large` FAQ entry
bumped to the new numbers; "Tuning the threshold" snippet updated to
240 GiB
- `docs/HANDOVER.md` and `docs/UPGRADE-v1.8-rar-support.md` — the
few remaining numeric references in those docs updated
### Unchanged
- `src/rar_extract.c` — already threads `c->limits` from the engine,
picks up the new defaults for free
- `k_large_limits` — `large=1` profile (1 TiB / 1 TiB / 1000 : 1) is
unchanged
- `docs/UPGRADE-v1.7-zip-large-file-profile.md` — historical v1.7
document left as-is so the v1.7 → v1.8.1 evolution is traceable
- Test fixture `medium_bomb.zip` (ratio ≈ 238) still exercises both
rejection under the default 500 : 1 cap and acceptance under the
`large=1` 1000 : 1 cap
- 83 host-side checks (69 ZIP + 14 RAR), 0 failures
### Migration notes
- **Forward-compatible** — users with v1.7 / v1.8 deployments who never
trigger `err_extract_entry_too_large` see no difference (defaults are
strictly more permissive)
- **No data loss** — the relaxation only widens accepted archives; the
real security guards (`check_space`, `max_ratio`, `path traversal`)
are untouched
- **No frontend UX change for typical use** — only archives > 240 GiB
on disk now trigger the confirmation prompt (previously 60 GiB)
---
## [v1.8] — 2026-09-05
+1 -1
View File
@@ -45,7 +45,7 @@ THIRD_PARTY_CFLAGS := -O2 -w -Ithird_party/zlib/include -Ithird_party/minizip-ng
PS5_TP_OBJS := $(patsubst %.c,ps5-obj/%.o,$(THIRD_PARTY_SRCS))
LINUX_TP_OBJS := $(patsubst %.c,linux-obj/%.o,$(THIRD_PARTY_SRCS))
CFLAGS := -Oz -fno-asynchronous-unwind-tables -fno-unwind-tables -Wall -Werror -ffunction-sections -fdata-sections -Isrc -Ithird_party/minizip-ng/include -DVERSION_TAG=\"$(VERSION_TAG)\" -DTITLE_ID=\"$(TITLE_ID)\"
CFLAGS := -Oz -fno-asynchronous-unwind-tables -fno-unwind-tables -Wall -Werror -ffunction-sections -fdata-sections -Isrc -Ithird_party/minizip-ng/include -Ithird_party/unrar -DVERSION_TAG=\"$(VERSION_TAG)\" -DTITLE_ID=\"$(TITLE_ID)\"
CFLAGS += `$(PKG_CONFIG) libmicrohttpd --cflags`
LDFLAGS := -Wl,--gc-sections
LDADD := `$(PKG_CONFIG) libmicrohttpd --libs`
+64 -21
View File
@@ -2,7 +2,7 @@
> Homebrew HTTP file manager for jailbroken PS5 consoles. Browse, edit, upload, download and extract ZIPs through any browser on the same network — single self-contained ELF payload, no external services, no telemetry.
**Version:** v1.8 · **Title ID:** `FMGR88888` · **License:** GPLv3+ · **Target:** `x86_64-sie-ps5`
**Version:** v1.8.2 · **Title ID:** `FMGR88888` · **License:** GPLv3+ · **Target:** `x86_64-sie-ps5`
---
@@ -40,10 +40,52 @@ The same source tree builds a Linux binary for development and a PS5 payload ELF
limitations that come from using dmc_unrar (no multi-volume, no
encryption in v1.8 — both lift in v1.9 when the library is replaced).
## What's new in v1.8.1
- **Default ZIP limits relaxed** (companion to v1.7's large profile).
v1.7 shipped with a 64 GiB default per-entry cap, which was too
aggressive for typical PS5 system-backup ZIPs (200-300 GiB). v1.8.1
raises the default profile to **1 TiB total / 256 GiB per entry /
500 : 1 ratio**, with the `large=1` opt-in kept at 2 TiB / 1 TiB /
1000 : 1. The frontend threshold rises from 60 GiB to 240 GiB so
common system-backup archives no longer trigger the prompt.
- RAR extraction inherits the new defaults (rar_extract.c threads
`c->limits` from the engine — no engine change required).
- Rationale: the real zip-bomb defence is `check_space()` (statvfs-based
real disk-space check before staging) + `max_ratio` (declared
compression ratio cap). The size caps are a UX guard, not a security
boundary.
## What's new in v1.8.2
- **Default ZIP limits relaxed again** for the 3A-game single-file case.
A single ~300 GiB uncompressed file inside an archive was still
silently rejected by v1.8.1 (the default scan returns
`ZIPX_ERR_LIMIT_FILE_SIZE` before the request ever reaches the
frontend confirmation prompt). v1.8.2 raises the default profile to
**2 TiB total / 512 GiB per entry / 500 : 1 ratio**, with the `large=1`
opt-in bumped to 4 TiB / 1 TiB / 1000 : 1. Frontend threshold rises
from 240 GiB to 480 GiB.
- **Two PS5-only build fixes** discovered when cross-compiling for the
PS5 target. The host-side test suite (`tests/run-tests.sh`) had
silently accepted both because it links the same sources but uses
gcc rather than clang 18 and a different include path:
- `Makefile` CFLAGS: add `-Ithird_party/unrar` so `src/rar_extract.c`
can find the project-authored `dmc_unrar_api.h` facade header.
- `src/extract.c`: move `extract_progress()` definition above
`extract_dispatch()` so the implicit function declaration is not
flagged by `-Werror=implicit-function-declaration` (clang 18 in the
PS5 SDK is stricter than the host gcc used by tests).
- **Release artifact** for v1.8.2: `web-file-mgr.elf` — 509 704 bytes,
sha256 `1b2c3d68b35e32737105f17d14a80a3c159ceca0cabd274ee168cbcd81906f65`,
ELF class 64, little-endian, e_machine `0x003e` (x86_64-sie-ps5).
- Tests: **84 host-side checks** (70 ZIP + 14 RAR), 0 failures. PS5
cross-compile succeeds end-to-end.
## What's new in v1.7
- **ZIP large-file profile** (opt-in via the new `large=1` argument on `/api/extract`): relaxed caps of **2 TiB** archive total, **1 TiB** per entry, **1000 : 1** compression ratio. The frontend prompts for confirmation whenever the archive on disk is larger than **60 GiB**; the server only activates the profile when the user explicitly agrees.
- **Stricter default ZIP profile** stays safe: **512 GiB** total / **64 GiB** per entry / **200 : 1** ratio. A 4 MiB compressed payload that expands to 800 GiB still gets rejected before any output file is opened.
- **Stricter default ZIP profile** stays safe: **1 TiB** total / **256 GiB** per entry / **500 : 1** ratio. A 4 MiB compressed payload that expands to 800 GiB still gets rejected before any output file is opened.
- **69 host-side C tests** (`tests/run-tests.sh`) now cover path traversal, ZIP64, encryption rejection, ratios, conflict policies and the new large-file profile (`tests/test_zip_extract.c`).
- Earlier refinements — see `git log` since v1.6.
@@ -116,7 +158,7 @@ make
Output:
```text
web-file-mgr.elf (~418 KiB, x86_64-sie-ps5)
web-file-mgr.elf (~497 KiB, x86_64-sie-ps5)
```
For pure UI/JS work without the PS5 toolchain:
@@ -156,13 +198,13 @@ Plain ZIPs only — stored / deflated / ZIP64, **never encrypted**. The engine i
| Limit | Default profile | Large profile (`ZIPX_LIMITS_LARGE`) |
|---|---|---|
| `max_entries` | 200 000 | 500 000 |
| `max_total_bytes` (uncompressed) | 512 GiB | 2 TiB |
| `max_file_bytes` (per entry) | 64 GiB | 1 TiB |
| `max_ratio` (uncompressed / compressed) | 200 : 1 | 1000 : 1 |
| `max_total_bytes` (uncompressed) | 2 TiB | 4 TiB |
| `max_file_bytes` (per entry) | 512 GiB | 1 TiB |
| `max_ratio` (uncompressed / compressed) | 500 : 1 | 1000 : 1 |
| `max_depth` (folder nesting) | 32 | 32 |
| `max_name_len` / `max_path_len` | 255 / 1024 | 255 / 1024 |
The **default profile** is shipped safe: a 4 MiB compressed blob that decodes to 800 GiB is rejected before any output file is opened. The **large profile** is engaged **only** when the request includes `large=1` — the archive dialog prompts the user automatically whenever the archive on disk is larger than `LARGE_FILE_THRESHOLD_BYTES` (60 GiB by default; configurable in `assets/main.js`). Confirming the prompt is the user's explicit opt-in; the server still records nothing extra on its own.
The **default profile** is shipped safe: a 4 MiB compressed blob that decodes to 800 GiB is rejected before any output file is opened. The **large profile** is engaged **only** when the request includes `large=1` — the archive dialog prompts the user automatically whenever the archive on disk is larger than `LARGE_FILE_THRESHOLD_BYTES` (480 GiB by default; configurable in `assets/main.js`). Confirming the prompt is the user's explicit opt-in; the server still records nothing extra on its own.
### Security checks
@@ -184,10 +226,10 @@ Passed as `conflict=` on `/api/extract`:
### Tuning the threshold
The 60 GiB frontend threshold lives in `assets/main.js`:
The 480 GiB frontend threshold lives in `assets/main.js`:
```js
const LARGE_FILE_THRESHOLD_BYTES = 60 * 1024 * 1024 * 1024;
const LARGE_FILE_THRESHOLD_BYTES = 480 * 1024 * 1024 * 1024;
```
Set it to `Infinity` to silence the prompt, lower it to be more conservative, or remove the call entirely — the server still respects `large=1` regardless of the threshold.
@@ -228,14 +270,14 @@ profile table on top. Defaults and the `large=1` opt-in are identical:
| Limit | Default profile | Large profile (`large=1`) |
|---|---|---|
| `max_entries` | 200 000 | 500 000 |
| `max_total_bytes` (uncompressed) | 512 GiB | 2 TiB |
| `max_file_bytes` (per entry) | 64 GiB | 1 TiB |
| `max_ratio` (uncompressed / compressed) | 200 : 1 | 1000 : 1 |
| `max_total_bytes` (uncompressed) | 2 TiB | 4 TiB |
| `max_file_bytes` (per entry) | 512 GiB | 1 TiB |
| `max_ratio` (uncompressed / compressed) | 500 : 1 | 1000 : 1 |
| `max_depth` (folder nesting) | 32 | 32 |
| `max_name_len` / `max_path_len` | 255 / 1024 | 255 / 1024 |
Large-profile RAR extraction uses the same `LARGE_FILE_THRESHOLD_BYTES`
(60 GiB) prompt as ZIP — the frontend treats `.rar` and `.zip` the same
(480 GiB) prompt as ZIP — the frontend treats `.rar` and `.zip` the same
way for the prompt, and the server only ever activates the large caps
when the request carries `large=1` (opt-in).
@@ -285,7 +327,7 @@ the step-by-step upgrade recipe.
After `make`, sanity-check the produced ELF:
```sh
ls -la web-file-mgr.elf # size ~430 KiB on v1.8 (~418 KiB on v1.7)
ls -la web-file-mgr.elf # size ~497 KiB on v1.8.2 (~427 KiB on v1.8)
sha256sum web-file-mgr.elf # record the digest in your release notes
file web-file-mgr.elf # expect "ELF 64-bit LSB pie executable, x86-64"
od -An -tx1 -N20 web-file-mgr.elf | head -2 # magic 7f45 4c46 0201 + e_machine 003e
@@ -301,8 +343,8 @@ A POSIX/host-side C test suite covers the ZIP engine and runs on any Linux / mac
cd tests && bash run-tests.sh
```
Output is a per-case `check`-style report — **83 checks** on the current `main`
(69 ZIP + 14 RAR). Coverage:
Output is a per-case `check`-style report — **84 checks** on the current `main`
(70 ZIP + 14 RAR). Coverage:
- ZIP entry parsing (stored + deflated + ZIP64)
- Path traversal, absolute paths, backslash, Windows drive letters
@@ -320,7 +362,7 @@ Output is a per-case `check`-style report — **83 checks** on the current `main
```
.
├── Makefile # PS5 + Linux builds (VERSION_TAG v1.8)
├── Makefile # PS5 + Linux builds (VERSION_TAG v1.8.2)
├── install-libmicrohttpd.sh # one-shot dependency installer
├── gen-asset-module.py # embeds assets/* as gzip-compressed C arrays
├── assets/ # HTML / CSS / JS / icons / param.json
@@ -368,10 +410,11 @@ Output is a per-case `check`-style report — **83 checks** on the current `main
- **This is a homebrew app and should not intentionally modify system processes or kernel memory.** If you hit a kernel panic, make sure you are using a recent jailbreak method and ELF loader, or revert to the stable method you normally use.
- **P2JB users** — if this payload triggers a kernel panic, avoid using it on that setup. Stability matters more than convenience when each retry is expensive.
- **The preparing stage can take a while** when a folder contains many files — it sums folder size and checks free space, which helps avoid starting a copy / move / upload / download that cannot finish safely.
- **`err_extract_entry_too_large`** — default archive caps are 64 GiB per
entry / 200:1 ratio. Confirm the large-file prompt (appears for
archives > 60 GiB on disk), split the archive, or pass `large=1`
directly to the API.
- **`err_extract_entry_too_large`** — default archive caps are 512 GiB per
entry / 500:1 ratio (covers a typical 3A-game archive with one ~300 GiB
uncompressed file). If you exceed the default, confirm the large-file
prompt (appears for archives > 480 GiB on disk), split the archive, or
pass `large=1` directly to the API.
- **`err_extract_unsupported`** — the archive uses a feature the engine
cannot handle: encrypted ZIP, encrypted RAR, multi-volume RAR
(`.part02+.rar`), very-old RAR 1.4, RAR symlinks / FIFOs, or a file
+1 -1
View File
@@ -68,7 +68,7 @@
</section>
<input id="uploadFiles" type="file" multiple hidden>
<input id="uploadFolder" type="file" multiple webkitdirectory hidden>
<input id="uploadZip" type="file" accept=".zip,application/zip,application/x-zip-compressed" hidden>
<input id="uploadZip" type="file" accept=".zip,.rar,application/zip,application/x-zip-compressed,application/vnd.rar,application/x-rar-compressed" hidden>
<section id="content" class="content">
<table>
+2 -2
View File
@@ -101,11 +101,11 @@ window.WFM_LANG = {
extracting: "Extracting",
extractConfirm: "Extract {name} to {path}?",
extractOverwriteAsk: "If a file or folder with the same name already exists in the target:\n\nOK = overwrite same-name files (folders still merge)\nCancel = fail if the target already exists",
extractUploadConfirm: "Upload and extract {name}?\n\nTarget folder: {path}\nThe uploaded ZIP will be deleted after success.",
extractUploadConfirm: "Upload and extract {name}?\n\nTarget folder: {path}\nThe uploaded archive will be deleted after success.",
extractStarted: "Extraction started: {name}",
extractDone: "Extraction complete: {name}",
extractProgress: "{done} / {total} files",
extractLargeAsk: "The archive looks large ({size}). Enable the large-file profile?\n\nOK = yes (single file up to 1 TiB, archive total up to 2 TiB)\nCancel = default limits (single file 64 GiB, archive total 512 GiB); this archive may be rejected",
extractLargeAsk: "The archive looks large ({size}). Enable the large-file profile?\n\nOK = yes (single file up to 1 TiB, archive total up to 4 TiB)\nCancel = default limits (single file 512 GiB, archive total 2 TiB); this archive may be rejected",
extractLargeActive: "Large-file profile is enabled for this task",
extractSelectMainVolume: "Please select the main volume (.rar or .part01.rar)",
extractArchivePending: "Preparing to extract {name}",
+2 -2
View File
@@ -101,11 +101,11 @@ window.WFM_LANG = {
extracting: "解压",
extractConfirm: "解压 {name} 到 {path}?",
extractOverwriteAsk: "若目标已存在同名文件或目录:\n\n确定 = 覆盖同名文件(目录仍会合并)\n取消 = 若目标已存在则失败",
extractUploadConfirm: "上传并解压 {name}?\n\n目标目录:{path}\n成功后将删除上传的 ZIP。",
extractUploadConfirm: "上传并解压 {name}?\n\n目标目录:{path}\n成功后将删除上传的压缩包。",
extractStarted: "已开始解压 {name}",
extractDone: "解压完成:{name}",
extractProgress: "{done} / {total} 个文件",
extractLargeAsk: "ZIP 体积较大({size}),是否启用「大文件模式」?\n\n确定 = 启用(单文件最大 1 TiB / 总解压最大 2 TiB)\n取消 = 默认限制(单文件 64 GiB / 总解压 512 GiB),可能拒绝此压缩包",
extractLargeAsk: "压缩包体积较大({size}),是否启用「大文件模式」?\n\n确定 = 启用(单文件最大 1 TiB / 总解压最大 4 TiB)\n取消 = 默认限制(单文件 512 GiB / 总解压 2 TiB),可能拒绝此压缩包",
extractLargeActive: "此任务已启用大文件模式",
extractSelectMainVolume: "请改选主卷(如 .rar 或 .part01.rar)",
extractArchivePending: "正在准备解压 {name}",
+9 -3
View File
@@ -35,7 +35,7 @@ let uploadXhr = null;
let uploadTerminalAbort = false;
let L = {};
const APP_VERSION = "v1.7";
const APP_VERSION = "v1.8.3";
const LAST_PATH_KEY = "ps5-web-file-mgr:last-path";
const SORT_KEY = "ps5-web-file-mgr:list-sort";
const LOADING_DISPLAY_DELAY = 250;
@@ -835,7 +835,13 @@ async function startExtractTask(path, dstDir, conflict, removeSource, name, larg
}
}
const LARGE_FILE_THRESHOLD_BYTES = 60 * 1024 * 1024 * 1024;
// Threshold above which the web UI prompts the user before extracting.
// Tuned so a typical 3A-game archive (~300 GiB single file) and a PS5 system
// backup (~300 GiB total) extract under the default profile without prompting.
// Files between this threshold and the default max_file_bytes cap (512 GiB)
// still extract silently; larger files require explicit user opt-in via the
// large=1 API flag.
const LARGE_FILE_THRESHOLD_BYTES = 480 * 1024 * 1024 * 1024;
function shouldPromptLargeMode(itemSize) {
return Number(itemSize || 0) > LARGE_FILE_THRESHOLD_BYTES;
@@ -2331,7 +2337,7 @@ function actionUploadAndExtract() {
async function uploadAndExtractFile(file) {
if (busy || loadingPath) return;
if (!/\.zip$/i.test(file.name || "")) {
if (!/\.(zip|rar)$/i.test(file.name || "")) {
alert(t("err_extract_unsupported", { arg: file.name }));
return;
}
+6 -6
View File
@@ -87,7 +87,7 @@ SDK 的 `target/user/homebrew/` 被 `songl(197609)` 拥有 755,普通 song 写
```
┌────────────────────────────────────────────────────────────────┐
│ Frontend: assets/main.js │
│ - LARGE_FILE_THRESHOLD_BYTES = 60 GiB (硬编码) │
│ - LARGE_FILE_THRESHOLD_BYTES = 240 GiB (硬编码) │
│ - shouldPromptLargeMode(itemSize) → 弹 confirm │
│ - startExtractTask(path, dst, conflict, remove, name, large) │
└────────────────────┬───────────────────────────────────────────┘
@@ -103,8 +103,8 @@ SDK 的 `target/user/homebrew/` 被 `songl(197609)` 拥有 755,普通 song 写
│
┌────────────────────▼───────────────────────────────────────────┐
│ Engine: src/zip_extract.{h,c} │
│ - k_default_limits: 200K / 512GiB / 64GiB / 200:1 │
│ - k_large_limits: 500K / 2TiB / 1TiB / 1000:1 │
│ - k_default_limits: 200K / 1TiB / 256GiB / 500:1 │
│ - k_large_limits: 500K / 2TiB / 1TiB / 1000:1 │
│ - ZIPX_LIMITS_DEFAULT=0 / ZIPX_LIMITS_LARGE=1 │
│ - zipx_limits_profile(int) → const zipx_limits_t* │
│ - zipx_extract() 签名不变,向后兼容 │
@@ -121,7 +121,7 @@ SDK 的 `target/user/homebrew/` 被 `songl(197609)` 拥有 755,普通 song 写
- `assets/lang-en.js` 和 `lang-zh.js` 新增 `extractLargeAsk` / `extractLargeActive`
**前端 UX**:
- ZIP 大于 60 GiB 时弹窗「启用大文件模式?」
- ZIP 大于 480 GiB 时弹窗「启用大文件模式?」
- 用户点 OK → 传 `large=1` → 引擎走 large profile
- 用户点取消 → 走 default profile(多半会被拒绝)
@@ -1130,8 +1130,8 @@ multi-volume (`name.part01.rar`, `name.part02.rar`, …). Encrypted
archives prompt for a password client-side; the password is held
only in memory and never saved.
Limits mirror the ZIP profiles (200K entries / 512 GiB / 64 GiB /
ratio 200 by default, with the same `large=1` opt-in to 500K /
Limits mirror the ZIP profiles (200K entries / 1 TiB / 256 GiB /
ratio 500 by default, with the same `large=1` opt-in to 500K /
2 TiB / 1 TiB / 1000).
```
+4 -4
View File
@@ -416,10 +416,10 @@ self-evident from the failure.
### 7.4 The `large=1` prompt for RAR
The threshold is shared. A `.rar` larger than `60 GiB` triggers the
The threshold is shared. A `.rar` larger than `240 GiB` triggers the
same `promptLargeMode()` confirmation as a `.zip`. The confirmation
text uses `extractLargeAsk` (unchanged from v1.7) — the wording is
format-agnostic, so no new strings are needed.
text uses `extractLargeAsk` (slightly relaxed in v1.8.1) — the wording
is format-agnostic, so no new strings are needed.
---
@@ -441,7 +441,7 @@ host has any RAR tooling.
| `test_engine_dispatch_null_dst` | `rar_extract(path, NULL, …)` is rejected with `ZIPX_ERR_INTERNAL`. |
| `test_engine_dispatch_dst_is_regular_file` | `rar_extract(path, /some/file, …)` returns `ZIPX_ERR_CONFLICT` (open_parent_dirs fails). |
| `test_format_translation` | Parametric: for each `DMC_UNRAR_*` code we care about, the corresponding `rar_translate_error()` mapping is exercised indirectly (via `result->message` strings). |
| `test_limits_handoff_default` | When `task->extract_large == 0`, the default profile is handed in (200 K entries / 512 GiB / 64 GiB / 200:1). |
| `test_limits_handoff_default` | When `task->extract_large == 0`, the default profile is handed in (200 K entries / 1 TiB / 256 GiB / 500:1). |
| `test_limits_handoff_large` | When `task->extract_large == 1`, the large profile is handed in (500 K / 2 TiB / 1 TiB / 1000:1). |
| `test_translate_open_fail_to_err_open` | DMC open-failure → `ZIPX_ERR_OPEN`. |
| `test_translate_volume_unsp_to_err_unsupported` | The DMC volume code → `ZIPX_ERR_UNSUPPORTED`. |
+22 -20
View File
@@ -45,6 +45,28 @@ ends_with_ci(const char *path, const char *suffix) {
return !strcasecmp(path + path_len - suf_len, suffix);
}
/* Progress callback. The engine already throttles reports (200 ms / 1 MiB),
so we can forward each report straight into the shared task state.
Defined before extract_dispatch() so the dispatcher's call site compiles
cleanly under -Werror=implicit-function-declaration. */
static void
extract_progress(void *userdata, const zipx_progress_t *p) {
file_task_t *task = userdata;
unsigned long long prev_done;
unsigned long long delta;
pthread_mutex_lock(&g_tasks_lock);
task->entries_total = p->entries_total;
task->entries_done = p->entries_done;
task->total = p->bytes_total;
prev_done = task->done;
pthread_mutex_unlock(&g_tasks_lock);
delta = p->bytes_done > prev_done ? p->bytes_done - prev_done : 0;
task_update(task, TASK_RUNNING, p->current ? p->current : task->src,
delta, NULL);
}
/* Pick the right engine by the archive file name. Returns ZIPX_ERR_FORMAT
for anything that does not look like a supported archive. */
static zipx_status_t
@@ -71,26 +93,6 @@ extract_dispatch(file_task_t *task, zipx_conflict_t conflict,
}
}
/* Progress callback. The engine already throttles reports (200 ms / 1 MiB),
so we can forward each report straight into the shared task state. */
static void
extract_progress(void *userdata, const zipx_progress_t *p) {
file_task_t *task = userdata;
unsigned long long prev_done;
unsigned long long delta;
pthread_mutex_lock(&g_tasks_lock);
task->entries_total = p->entries_total;
task->entries_done = p->entries_done;
task->total = p->bytes_total;
prev_done = task->done;
pthread_mutex_unlock(&g_tasks_lock);
delta = p->bytes_done > prev_done ? p->bytes_done - prev_done : 0;
task_update(task, TASK_RUNNING, p->current ? p->current : task->src,
delta, NULL);
}
static const char *
extract_error_code(zipx_status_t status) {
switch(status) {
+25 -7
View File
@@ -33,22 +33,40 @@
#define ZIPX_PUBLISH_MAX_DEPTH 128
#define ZIPX_SPACE_SLACK_PER_ENTRY 512
/* Default limits.
*
* Tuned to cover real-world PS5 workloads without prompting:
* - PS5 system backup ZIPs (~200-300 GiB total, individual chunks <64 GiB)
* - 3A-game archives with a single ~300 GiB uncompressed file
*
* Safety against zip bombs is delegated to:
* 1. `check_space()` (statvfs-based real disk space check) before extract
* 2. `max_ratio` below (declared compression ratio cap)
* The size caps here are an early-fail UX guard, not a security boundary.
*/
static const zipx_limits_t k_default_limits = {
.max_entries = 200000,
.max_total_bytes = 512ULL * 1024 * 1024 * 1024,
.max_file_bytes = 64ULL * 1024 * 1024 * 1024,
.max_ratio = 200,
.max_total_bytes = 2ULL * 1024 * 1024 * 1024 * 1024,
.max_file_bytes = 512ULL * 1024 * 1024 * 1024,
.max_ratio = 500,
.max_depth = 32,
.max_name_len = 255,
.max_path_len = 1024
};
/* Large profile for archives that exceed the safe limits (e.g. 200 GB system
images). The relaxed ratio still rejects obvious bombs; the size caps
require the user to opt in via the web UI before they take effect. */
/* Large profile for archives that exceed the default cap.
*
* - max_file_bytes = 1 TiB (single uncompressed file)
* - max_total_bytes = 4 TiB (whole archive)
* - max_ratio = 1000 (relaxed ratio cap; check_space still applies)
*
* Requires the user to opt in via the web UI (large=1) before these take
* effect. Default limits must always be strictly smaller than large so the
* large profile is unambiguously a relaxation.
*/
static const zipx_limits_t k_large_limits = {
.max_entries = 500000,
.max_total_bytes = 2ULL * 1024 * 1024 * 1024 * 1024,
.max_total_bytes = 4ULL * 1024 * 1024 * 1024 * 1024,
.max_file_bytes = 1ULL * 1024 * 1024 * 1024 * 1024,
.max_ratio = 1000,
.max_depth = 32,
+642 -639
View File
File diff suppressed because it is too large. Load diff