Skip to content

fix: make subprocess and cache-file text IO locale-independent - #2440

Open
sun04222 wants to merge 1 commit into
unclecode:developfrom
sun04222:fix/locale-hardening-text-io
Open

sun04222 wants to merge 1 commit into
unclecode:developfrom
sun04222:fix/locale-hardening-text-io

Conversation

@sun04222

Copy link
Copy Markdown

Summary

Three spots used the platform default codec for text IO, which breaks under non-UTF-8 locales (cp1252/cp936) and under UTF-8 mode — the default from Python 3.15 (PEP 686). Fixes #2439.

Spot Failure mode
BrowserProfiler._is_browser_running (tasklist probe, text=True without encoding) UnicodeDecodeError on ANSI/OEM output escapes the except (ProcessLookupError, PermissionError, OSError) tuple → a live builtin browser is treated as dead, kill/skip logic degrades, processes leak
Chromium stdout/stderr launch diagnostics (browser_manager, 5 × bare bytes.decode()) decoding localized early-exit output raises, converting a diagnosable launch failure into an opaque Failed to start browser
Common Crawl URL cache (_from_cc, aiofiles.open without encoding) non-ASCII URLs raise UnicodeEncodeError mid-generator under cp1252/cp936; cache files mojibake across locales

Changes

  • browser_profiler.py: the tasklist probe gets encoding="utf-8", errors="replace" — it only searches for the ASCII PID digits, which survive lossy decoding.
  • browser_manager.py: the five diagnostic decodes get errors="replace" (valid-UTF-8 output is unchanged).
  • async_url_seeder.py: both Common Crawl cache opens pin encoding="utf-8".

Testing

New tests/unit/test_non_utf8_locale_hardening.py (5 tests):

  • tasklist probe pins tolerant decoding kwargs (portable), plus a real-tasklist canary on win32
  • startup check tolerates non-UTF-8 browser output (stubbed process, real method body)
  • CC cache round-trips non-ASCII URLs and serves them from cache with no network
  • CC cache survives a simulated latin-1 system locale — an aiofiles.open wrapper injects the locale codec only where the caller did not pin one, so the old code fails with UnicodeEncodeError on any platform

Verified locally on a cp936 Windows machine with UTF-8 mode on: 5/5 pass with this patch; 4/5 fail against unpatched develop — including a live UnicodeDecodeError from the real tasklist probe and the startup-check decode crash.

Related open PRs in the same theme, with disjoint files/hunks: #1807 (CLI file operations), #2406 (seeder head metadata), #2418 (bundled JS/c4a scripts).

- browser_profiler: the tasklist probe decoded ANSI/OEM output with the
  strict default codec; under UTF-8 mode (the default from Python 3.15,
  PEP 686) the probe raises on CJK Windows and escapes its except tuple,
  making a live builtin browser look dead. Decode tolerantly - the probe
  only searches for the ASCII PID digits, which survive lossy decoding.
- browser_manager: decode Chromium stdout/stderr launch diagnostics
  tolerantly so localized early-exit text cannot crash the startup check.
- async_url_seeder: pin UTF-8 for the Common Crawl URL cache so
  non-ASCII URLs round-trip on any system locale.
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