Steam's art lives in Program Files, which was never an allowed art root #215
Merged
enricobuehler
merged 3 commits from 2026-08-14 07:51:32 +00:00
worktree-steam-art-root-windows into main
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0f9ccfa8b6 |
fix(ci): funnel the art tests' env overrides through one RAII guard
ci / bun-nix (pull_request) Successful in 24s
apple / swift (pull_request) Successful in 2m8s
apple / distribute (pull_request) Skipped
apple / screenshots (pull_request) Skipped
android / android (pull_request) Successful in 3m59s
ci / web (pull_request) Successful in 5m47s
ci / docs-site (pull_request) Successful in 5m51s
ci / rust-arm64 (pull_request) Successful in 5m54s
ci / rust (pull_request) Successful in 18m16s
CI gate C (unsafe hygiene) failed on the previous commit: `library/art.rs` went from 4 process-global-API mentions to 10, because the two new tests each hand-rolled a set/restore pair the way the two existing ones already did. The gate says fix the call sites rather than raise the baseline, and it is right to here — the hand-rolled pattern was also leaking. Each test set `PUNKTFUNK_LIBRARY_ART_ROOTS` and unset it at the end, so any assertion firing between the two halves left the override installed for every later test in the process, turning one real failure into a cascade. `ArtRootsEnv` now holds the lock and the saved values and restores them on drop, which runs on an unwind too. `write_env` is the single write point, so the gate has exactly one pair of call sites to judge: the count drops to 2, below the old baseline of 4, and stays flat however many tests are added. Baseline lowered to 2 in the same commit, as the ratchet's policy requires. ⚠ The gate greps for the API names in COMMENTS as well as code, so the SAFETY comments here deliberately describe the calls instead of naming them. Re-verified after the refactor: .25 493/493 + clippy clean, .133 12/12 art tests + clippy clean, `check-unsafe-hygiene.sh` clean locally. |
||
|
|
8d60f1cec0 |
Merge remote-tracking branch 'origin/main' into worktree-steam-art-root-windows
ci / web (pull_request) Successful in 1m10s
ci / rust-arm64 (pull_request) Successful in 1m34s
ci / bun-nix (pull_request) Successful in 1m51s
android / android (pull_request) Successful in 3m57s
ci / docs-site (pull_request) Successful in 3m8s
ci / rust (pull_request) Failing after 6m35s
# Conflicts: # CHANGELOG.md |
||
|
|
6dd4add11b |
fix(library): Steam's art lives in Program Files, which was never an allowed art root
ci / bun-nix (pull_request) Successful in 20s
android / android (pull_request) Canceled after 1m22s
ci / rust-arm64 (pull_request) Successful in 1m17s
ci / rust (pull_request) Canceled after 1m22s
ci / web (pull_request) Canceled after 1m18s
ci / docs-site (pull_request) Canceled after 1m18s
A field report: the Steam plugin installed, the grid stayed empty, and the only clue was one warn per sync — `art.hero: local art must be an image file … inside an allowed art root`. Two defects, both here. The art roots defaulted to the users base (`C:\Users`, from `%PUBLIC%`'s parent). That covers the launchers that install per-user, but not Steam, which installs to `C:\Program Files (x86)\Steam` and keeps both the things the plugin publishes there — `appcache\librarycache\<appid>\<hash>\` and each account's `userdata\<id>\config\grid\`. So every cover was out of root. It is a v0.28.0 regression: the built-in scanner the plugin replaced served covers through the legacy `steam:` art-proxy branch, which never passed through the H-2 confinement, so deleting the scanner routed that art through a gate it had never been measured against. `art_roots()` now also carries every Steam install it can find, from the three Program Files vars and from HKLM `Valve\Steam\InstallPath` so a Steam on another drive counts too. POSIX needs no equivalent — native and Flatpak Steam are both already under `$HOME`. The confinement is not weakened. It exists to stop the host (SYSTEM) reading what the plugin lane (LocalService) cannot reach itself; the Steam directory is readable by LocalService already, so nothing there is reachable *because* the host is privileged, and the extension, regular-file, magic-byte and config-dir gates still apply on top. Tested: `config.vdf` is not servable from an art root, nor is a non-image wearing `.png`. Second, and the reason this cost a whole library rather than a thumbnail: the provider reconcile validated art per entry and 400'd the WHOLE payload on the first bad value. A path mismatch therefore deleted every game from that store, and the plugin — which only ever sees `HostRequestError` — could not say which. A reconcile now strips unservable local art and syncs the rest, logging one aggregated warn with the count, an example path and the env var. The invariant the 400 held is unchanged: no unservable path is persisted. The operator's own single-entry writes keep the hard 400, because there the path was typed by hand and silence would be the wrong answer. Verified on Linux (.25: 493/493, clippy clean) and Windows (.133: 12/12 art tests, clippy clean). The new Windows test is hermetic — it repoints `%ProgramFiles(x86)%` at a synthetic Steam tree rather than asserting over whatever Steam the box happens to have, since the vacuous version of that test is what would have let this ship. Confirmed non-vacuous by disabling the fix: it fails on "the DEFAULT art roots must include it". |