Skip to content

Preserve unicode game titles from ludusavi - #60

Merged
Vasanthdev2004 merged 2 commits into
Vasanthdev2004:mainfrom
Tudzer:main
Sep 4, 2026
Merged

Vasanthdev2004 merged 2 commits into
Vasanthdev2004:mainfrom
Tudzer:main

Conversation

@Tudzer

@Tudzer Tudzer commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

When encoding is not specified explicitly as "utf-8", subprocess.run uses the default system encoding, which is typically CP1252 on Windows. This causes UTF-8 characters in game titles to be decoded incorrectly.

After this fix, titles like "Grand Theft Auto: The Trilogy – The Definitive Edition" are correctly displayed as "Grand Theft Auto: The Trilogy – The Definitive Edition".

When encoding is not specified explicitly as "utf-8", `subprocess.run` uses the default system encoding, which is typically CP1252 on Windows. This causes UTF-8 characters in game titles to be decoded incorrectly.

After this fix, titles like "Grand Theft Auto: The Trilogy – The Definitive Edition" are correctly displayed as "Grand Theft Auto: The Trilogy – The Definitive Edition".
@Tudzer

Tudzer commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Sorry in advance for not adding a test for this; I'm just not competent
enough in Python testing to do that 🙈

Tudzer's fix was right and the diagnosis was exact: text=True decodes with
the locale default, which is cp1252 on a stock Windows install, while
Ludusavi emits UTF-8. Confirmed here - locale.getpreferredencoding() returns
cp1252 on this machine.

Five other calls had the same defect. One of them matters more than the
original.

run_rclone parses rclone's output into the remote version listing that prune
and restore work from, and _slugify keeps non-ASCII rather than stripping it -
'Pokemon' with an accent slugs to an id that still has the accent, and that id
is the remote path. A mangled listing there is not a cosmetic wrong title, it
is retention and restore reading the wrong names.

The rest are the Xbox package query, which shells out to PowerShell, and the
three systemctl calls.

The test is a whole-tree AST assertion rather than six separate ones, because
the bug is "somebody added a subprocess call and forgot", and that is the
thing worth catching. It also proves it can see a violation, since a guard
that cannot fail is not a guard.
@Vasanthdev2004

Copy link
Copy Markdown
Owner

Correct, and the diagnosis was exact. Confirmed here: locale.getpreferredencoding() returns cp1252 on this machine, so text=True was decoding Ludusavi's UTF-8 JSON as cp1252 exactly as you describe.

I have pushed the rest onto this branch rather than sending you back round again. Five other calls had the same defect:

cloud.py:312     run_rclone
launcher.py:121  PowerShell Get-AppxPackage
cli.py           three systemctl calls

run_rclone is the one worth knowing about, because it is not a cosmetic wrong title. _slugify keeps non-ASCII rather than stripping it, so a game called Pôkemon gets an id that still has the accent, and that id is the remote path. rclone's output gets parsed into the version listing that prune and restore work from. Mangling it there means retention and restore reading the wrong names.

So your one-line fix turned out to sit on top of a systemic one, and the systemic one reaches the code that deletes things.

The test is a single AST assertion over the whole tree rather than six separate ones, because the bug is "somebody adds a subprocess call and forgets" and that is the shape worth catching. It also asserts it can detect a violation, since a guard that cannot fail is not a guard.

Second one of these you have found now. The timestamp bug had been shipping since 0.6.0, and this one since the beginning — both in code I have read many times.

@Vasanthdev2004
Vasanthdev2004 merged commit cc40758 into Vasanthdev2004:main Sep 4, 2026
6 checks passed
@Vasanthdev2004

Copy link
Copy Markdown
Owner

thanks for contribution no proplem with the test i added it @Tudzer

@Vasanthdev2004 Vasanthdev2004 mentioned this pull request Sep 4, 2026
Vasanthdev2004 added a commit that referenced this pull request Sep 4, 2026
Two fixes, one found by a contributor and one found by using the thing.

Game titles with non-ASCII characters were mangled: text=True decodes with
the locale default, cp1252 on a stock Windows install, while Ludusavi and
rclone emit UTF-8. Found by @Tudzer in #60, who fixed the Ludusavi call. Five
others had the same defect, and rclone's mattered most - a game id keeps the
non-ASCII from its title and an id is part of the remote path, so a mangled
listing is retention and restore reading the wrong paths.

Removing a game now sticks. `gsg remove --purge` deleted a game and its
backups and the next scan added it straight back, because nothing recorded
the removal and a launcher-owned game only stays skipped while its launcher
reports it installed (#61).

Co-authored-by: Vasanthdev2004 <Vasanthdev2004@users.noreply.github.com>
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