From 9b92c453ea82ac037bc5a82e568ead6488c3e72d Mon Sep 17 00:00:00 2001 From: Rohit Bhati Date: Mon, 16 Mar 2026 15:53:43 +0530 Subject: [PATCH] Fixed Process Watcher garbled text on Windows with non-UTF-8 locales. #9457 --- .../misc/bgprocess/process_executor.py | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/web/pgadmin/misc/bgprocess/process_executor.py b/web/pgadmin/misc/bgprocess/process_executor.py index b52d672a708..193cc9df06c 100755 --- a/web/pgadmin/misc/bgprocess/process_executor.py +++ b/web/pgadmin/misc/bgprocess/process_executor.py @@ -34,6 +34,7 @@ import sys import os import subprocess +import locale from datetime import datetime, timedelta, tzinfo, timezone from subprocess import Popen, PIPE from threading import Thread @@ -45,6 +46,7 @@ _fs_encoding = None _out_dir = None _log_file = None +_subprocess_encoding = None def _log(msg): @@ -191,7 +193,7 @@ def log(self, msg): This function will update log file Args: - msg: message + msg: message (bytes from subprocess) Returns: None @@ -205,9 +207,22 @@ def log(self, msg): ).encode('utf-8') ) self.logger.write(b',') - self.logger.write( - msg.lstrip(b'\r\n' if _IS_WIN else b'\n') - ) + + # Convert subprocess output from system encoding to UTF-8 + # This fixes garbled text on Windows with non-UTF-8 locales + # (e.g., Japanese CP932, Chinese GBK) + msg = msg.lstrip(b'\r\n' if _IS_WIN else b'\n') + if _subprocess_encoding and \ + _subprocess_encoding.lower() not in ('utf-8', 'utf8'): + try: + msg = msg.decode( + _subprocess_encoding, 'replace' + ).encode('utf-8') + except (UnicodeDecodeError, LookupError): + # If decoding fails, write as-is + pass + + self.logger.write(msg) self.logger.write(os.linesep.encode('utf-8')) return True @@ -427,6 +442,12 @@ def convert_environment_variables(env): # encoding or 'ascii'. _fs_encoding = 'utf-8' + # Detect subprocess output encoding (important for Windows with non-UTF-8 + # locales like Japanese CP932, Chinese GBK, etc.) + _subprocess_encoding = locale.getpreferredencoding(False) + if not _subprocess_encoding or _subprocess_encoding == 'ascii': + _subprocess_encoding = 'utf-8' + _out_dir = os.environ['OUTDIR'] _log_file = os.path.join(_out_dir, ('log_%s' % os.getpid()))