Fix custom key loading for compressed game inputs (#204)

nsz 4.6.1 rejects --keys and loads keys.txt beside argv[0] during import.
Run the converter in its temporary output folder with the selected key
file linked there before import, using absolute input and output paths.
Remove the temporary link on both successful and failed conversions.

Integrate PR #204 with XCZ and relative-path regressions, rename the test
flag that shadowed unittest.TestCase.fail, and qualify the documentation
for the verified nsz release. Record the packing finding and provenance.

Validation: reproduced the exact parser failure using real nsz 4.6.1;
a synthetic NSZ conversion verifies selected-key lookup and link cleanup;
52 NSP tests, four documentation tests and git diff --check pass.
The synthetic payload is unencrypted and uses dummy keys. Real-game
decryption, actual XCZ conversion and a full IPA build remain unverified.

Co-authored-by: Fernando Messias <fernandomessias95@gmail.com>
This commit is contained in:
seeddsandFernando Messias committed 2026-10-26 10:36:23 +08:00
1 parent 435a231051
commit 62a640b037
7 files changed
+59 -15

No files matched your search

+4 -2
View File
@@ -435,7 +435,7 @@ def decompress_nsz(nsp_dir, app, fam, keys, env):
if not todo: return fam
if importlib.util.find_spec('nsz') is None:
raise BuildError(f'NSZ / XCZ files need the nsz tool in the current Python ({sys.executable}): pip install nsz')
out = nsp_dir / f'{app:016X}_build' / 'nsp'; logs, tmp = out.parent / 'logs', out / 'partial'
out = nsp_dir.absolute() / f'{app:016X}_build' / 'nsp'; logs, tmp = out.parent / 'logs', out / 'partial'
PROG.plan(1); PROG.stage('decompress NSZ', done=0, total=len(todo))
conv, made = {}, 0
for i, p in enumerate(todo):
@@ -446,7 +446,9 @@ def decompress_nsz(nsp_dir, app, fam, keys, env):
rmtree(tmp); tmp.mkdir(parents=True); rmtree(dst); keyfile.unlink(missing_ok=True)
log = logs / f'nsz_{p.stem}.log'
try:
run([sys.executable, '-c', NSZ_MAIN, '-D', '--keys', keys, '-o', tmp, p], log, env=env)
# nsz 4.6.1 loads keys.txt beside argv[0] at import time; with argv[0] = 'nsz' that is cwd. That release has no --keys option.
(tmp / 'keys.txt').symlink_to(keys.resolve())
run([sys.executable, '-c', NSZ_MAIN, '-D', '-o', tmp, p.resolve()], log, env=env, cwd=tmp)
if not (tmp / dst.name).is_file(): raise BuildError(f'nsz made no {dst.name} (full output: {log})')
(tmp / dst.name).rename(dst)
finally: rmtree(tmp)