Skip to content

fix(pythonlib): write downloaded files beside their destination, not via mkdtemp - #14

Open
JWriter20 wants to merge 1 commit into
mainfrom
fix/windows-private-temp-acl
Open

JWriter20 wants to merge 1 commit into
mainfrom
fix/windows-private-temp-acl

Conversation

@JWriter20

Copy link
Copy Markdown
Owner

Fork CI run before the upstream PR. Windows + Python 3.13+: model/GeoIP files installed by one account or elevation level are unreadable by another.

🤖 Generated with Claude Code

…via mkdtemp

The fpgen model was staged in tempfile.mkdtemp() and os.replace'd into
fpgen's data directory, and an extracted GeoIP database was unpacked in
tempfile.TemporaryDirectory() and shutil.move'd into the cache. Since
Python 3.13, mkdtemp() on Windows creates an owner-only directory, and a
file moved out of it on the same volume keeps that ACL. So a model or
database installed from an elevated shell (or over SSH, which is elevated)
could not be read by the same user unelevated, or by any other account:
the launch failed with "fpgen's model directory is not writable by this
user", though the failure was a read. Found on Windows 11 with
camoufox 0.5.7b5 under Python 3.14.

Add pkgman.write_atomic(): write a temporary file beside the destination,
so it takes the directory's permissions, then os.replace it into place.
The model's members are all verified before any is written, as before.
The permission error now names the file and says how to recover from a
model another account installed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown

✅ Tests passed

Camoufox 156.0.1 (beta.32), built on Firefox 156, tested against Playwright v1.62.0 — the newest released suite not ahead of Firefox 156 (it targets Firefox 153.0).

Suite Result Detail
native_rules ✅ pass 28 passed, 0 failed, 28 collected
pythonlib ✅ pass 459 passed, 0 failed, 461 collected
typescript ✅ pass 632 passed, 0 failed, 651 collected
build ✅ pass restored a browser whose compiled half was built from identical sources, and laid this branch's resources over it; nothing was compiled
patch_guards_spoofing ✅ pass 9 passed, 0 failed, 9 collected
patch_guards_automation ✅ pass 14 passed, 0 failed, 14 collected
patch_guards_parity ✅ pass 8 passed, 0 failed, 8 collected
skiplist_audit ✅ pass 17 passed, 0 failed, 17 collected
native_browser ✅ pass 46 passed, 0 failed, 46 collected
build_tester ✅ pass 478 passed, 4 failed, 482 collected
playwright ✅ pass 2248 passed, 0 failed, 2315 collected (across 6 shards), 328 via main-world fallback
typescript_browser ✅ pass 16 passed, 0 failed, 19 collected
native_growth ✅ pass 7 passed, 0 failed, 7 collected (across 7 shards)
sundial ✅ pass grade A+ — 626/630 in-scope checks passed

The Playwright suite is upstream playwright-python at the tag above, fetched fresh, with tests/camoufox/ overlaid. It runs with world isolation on — the configuration Camoufox ships — and only the failures are re-run with it off; those count as passes and are reported above as main-world fallbacks, which is the size of the isolated-world gap. Tests Camoufox cannot pass by design are deselected via ci/skiplist.yml — each with a stated reason. The stealth check reports a grade only; its per-vector detail is deliberately never published.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant