Skip to content

Fix long-path extraction past MAX_PATH on Windows (#1468) - #1516

Closed
rockysscenery wants to merge 2 commits into
NotRexed:mainfrom
rockysscenery:contrib/windows-long-path-extract
Closed

rockysscenery wants to merge 2 commits into
NotRexed:mainfrom
rockysscenery:contrib/windows-long-path-extract

Conversation

@rockysscenery

Copy link
Copy Markdown
Contributor

What

Adds one narrow case to nx2/nup.py: when extracting, hand absolute normalized Windows paths through the long-path prefix (\?\) so deep folders that run past 260 characters work correctly. The whole path logic stays exactly as-is; nothing changes about safety checks or links — just the way Python passes them down to the OS at one choke point (the new win_long helper).

Why

Right where reporter hit it: extraction died halfway through a game folder named normally plus the deepest romfs leaf. makedirs succeeded but opening .part gave ENOENT for any path >260 chars because Python uses ANSI APIs without long-path support by default on Windows. This fixes exactly that without touching policy or making unsafe names suddenly legal.

Results

  • New test fixtures an author deep path (forces prefix need on ANY machine, even ones with system-wide long paths enabled) plus a short name too; both files must land correctly via extract(). Runs green when run solo; full suite unchanged except pre-existing symlink privilege failures from lacking Developer Mode.
  • Existing codec/verify tests still pass cleanly — no regressions beyond what was already there.

Testing performed

  • Added regression test in nx2/test_nup_paths.py that specifically breaks without the fix but passes with it (author fixture root + deep leaf >260 total length). Test confirms both short and long names extract correctly regardless of whether your machine has OS-level long path support turned on or off.
  • Ran existing nup tests (test_nup_codec, test_nup_verify) — all green, same five pre-existing symlink failures due to lack of Developer Mode privileges on the test machine (unrelated to this change).

Closes: #1468

🤖 Generated with Claude Code

rockysscenery and others added 2 commits November 9, 2026 21:40
nup's extractor wrote deep paths raw. makedirs passed but the open of the .part died with ENOENT for any path over 260 characters, so a game folder named normally plus the deepest romfs leaf stopped the build halfway through extraction — right where the reporter hit it. Hand absolute normalized Windows paths to the wide API via the long-path prefix at exactly one choke point (win_long) so no policy about unsafe names or existing links changes. A test fixture authors a deep path that forces the boundary on a machine with long paths enabled and confirms both files land; short-name paths must pass unchanged too.

Co-Authored-By: Claude Code <noreply@anthropic.com>
The fixture authors a deep path that forces the boundary on any machine, including ones where Python resolves long raw paths. Two files must land — one >260 characters after joining with the temp root (the failing case in NotRexed#1468), and one short leaf to prove ordinary names pass through win_long unchanged too.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@NotRexed

Copy link
Copy Markdown
Owner

Thanks for this. Long paths are handled on main now by #1497, which covers the extraction (as this PR does) and also the game's own file reads, links and the shader census. I played from a game folder whose deepest file path is 374 characters: it reached gameplay with no file errors. Closing this one as superseded.

@NotRexed NotRexed closed this Nov 10, 2026
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.

2 participants