Skip to content

Commit ac68fcf

Browse files
authored
Merge pull request #6917 from kozlovsky/fix/handle_non_utf8_core_output
Handle non-utf8 Tribler Core output in Tribler GUI
2 parents 485ab17 + 410fb73 commit ac68fcf

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

src/tribler/gui/core_manager.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def on_core_stdout_read_ready(self):
107107
return
108108

109109
raw_output = bytes(self.core_process.readAllStandardOutput())
110-
self.last_core_stdout_output = raw_output.decode("utf-8").strip()
110+
self.last_core_stdout_output = self.decode_raw_core_output(raw_output).strip()
111111

112112
try:
113113
print(self.last_core_stdout_output) # print core output # noqa: T001
@@ -121,7 +121,7 @@ def on_core_stderr_read_ready(self):
121121
return
122122

123123
raw_output = bytes(self.core_process.readAllStandardError())
124-
self.last_core_stderr_output = raw_output.decode("utf-8").strip()
124+
self.last_core_stderr_output = self.decode_raw_core_output(raw_output).strip()
125125

126126
try:
127127
print(self.last_core_stderr_output, file=sys.stderr) # print core output # noqa: T001
@@ -162,3 +162,14 @@ def on_core_finished(self, exit_code, exit_status):
162162
self.events_manager.connect_timer.stop()
163163

164164
raise CoreCrashedError(error_message)
165+
166+
@staticmethod
167+
def decode_raw_core_output(output: bytes) -> str:
168+
try:
169+
# Let's optimistically try to decode from UTF8.
170+
# If it is not UTF8, we should get UnicodeDecodeError "invalid continuation byte".
171+
return output.decode('utf-8')
172+
except UnicodeDecodeError:
173+
# It may be hard to guess the real encoding on some systems,
174+
# but by using the "backslashreplace" error handler we can keep all the received data.
175+
return output.decode('ascii', errors='backslashreplace')

src/tribler/gui/tests/test_core_manager.py

+6
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,9 @@ def test_on_core_read_ready_os_error_suppressed(core_manager):
6161
core_manager.on_core_stdout_read_ready()
6262
core_manager.on_core_stderr_read_ready()
6363
assert print.call_count == 2
64+
65+
66+
def test_decode_raw_core_output(core_manager):
67+
assert core_manager.decode_raw_core_output(b'test') == 'test'
68+
assert core_manager.decode_raw_core_output('test привет'.encode('utf-8')) == 'test привет'
69+
assert core_manager.decode_raw_core_output('test привет'.encode('cp1251')) == r'test \xef\xf0\xe8\xe2\xe5\xf2'

0 commit comments

Comments
 (0)