Skip to content

Commit 74b1a3b

Browse files
Fixed Process Watcher garbled text on Windows with non-UTF-8 locales. #9457
1 parent 01c2d12 commit 74b1a3b

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

web/pgadmin/misc/bgprocess/process_executor.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import sys
3535
import os
3636
import subprocess
37+
import locale
3738
from datetime import datetime, timedelta, tzinfo, timezone
3839
from subprocess import Popen, PIPE
3940
from threading import Thread
@@ -45,6 +46,7 @@
4546
_fs_encoding = None
4647
_out_dir = None
4748
_log_file = None
49+
_subprocess_encoding = None
4850

4951

5052
def _log(msg):
@@ -191,7 +193,7 @@ def log(self, msg):
191193
This function will update log file
192194
193195
Args:
194-
msg: message
196+
msg: message (bytes from subprocess)
195197
196198
Returns:
197199
None
@@ -205,9 +207,22 @@ def log(self, msg):
205207
).encode('utf-8')
206208
)
207209
self.logger.write(b',')
208-
self.logger.write(
209-
msg.lstrip(b'\r\n' if _IS_WIN else b'\n')
210-
)
210+
211+
# Convert subprocess output from system encoding to UTF-8
212+
# This fixes garbled text on Windows with non-UTF-8 locales
213+
# (e.g., Japanese CP932, Chinese GBK)
214+
msg = msg.lstrip(b'\r\n' if _IS_WIN else b'\n')
215+
if _subprocess_encoding and \
216+
_subprocess_encoding.lower() not in ('utf-8', 'utf8'):
217+
try:
218+
msg = msg.decode(
219+
_subprocess_encoding, 'replace'
220+
).encode('utf-8')
221+
except (UnicodeDecodeError, LookupError):
222+
# If decoding fails, write as-is
223+
pass
224+
225+
self.logger.write(msg)
211226
self.logger.write(os.linesep.encode('utf-8'))
212227

213228
return True
@@ -427,6 +442,12 @@ def convert_environment_variables(env):
427442
# encoding or 'ascii'.
428443
_fs_encoding = 'utf-8'
429444

445+
# Detect subprocess output encoding (important for Windows with non-UTF-8
446+
# locales like Japanese CP932, Chinese GBK, etc.)
447+
_subprocess_encoding = locale.getpreferredencoding(False)
448+
if not _subprocess_encoding or _subprocess_encoding == 'ascii':
449+
_subprocess_encoding = 'utf-8'
450+
430451
_out_dir = os.environ['OUTDIR']
431452
_log_file = os.path.join(_out_dir, ('log_%s' % os.getpid()))
432453

0 commit comments

Comments
 (0)