From 562ae285729fef946446c0c3dbf28b095a855e0c Mon Sep 17 00:00:00 2001
From: Daniel Estévez <daniel@destevez.net>
Date: Sat, 19 Sep 2020 14:12:31 +0200
Subject: grc: ensure that strings are valid utf8 when evaluating parameters

Some objects, notably PMTs can produce non-UTF-8 strings when
their __str__() method is called. For instance

>>> str(pmt.init_u8vector(1, [203]))
'#[\udccb]'

These kinds of strings eventually give a UnicodeEncodeError, for
instance when calling print() or displaying them with GTK. Python3
strings are supposed to be valid UTF-8.

When these objects are used inside block parameters in GRC, it will
produce several tracebacks and hang up. This commit fixes the problem
by sanitizing the strings to convert them to valid UTF-8. The sanitization
uses the 'backslashreplace' error response from Python.

Issue #3398 is caused by this problem.

Signed-off-by: Martin Braun <martin@gnuradio.org>
---
 grc/gui/canvas/param.py | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'grc/gui/canvas/param.py')

diff --git a/grc/gui/canvas/param.py b/grc/gui/canvas/param.py
index 92d1f84941..3480d79618 100644
--- a/grc/gui/canvas/param.py
+++ b/grc/gui/canvas/param.py
@@ -73,6 +73,9 @@ class Param(CoreParam):
             if hasattr(value, "__len__"):
                 tooltip_lines.append('Length: {}'.format(len(value)))
             value = str(value)
+            # ensure that value is a UTF-8 string
+            # Old PMTs could produce non-UTF-8 strings
+            value = value.encode('utf-8', 'backslashreplace').decode('utf-8')
             if len(value) > 100:
                 value = '{}...{}'.format(value[:50], value[-50:])
             tooltip_lines.append('Value: ' + value)
@@ -139,6 +142,9 @@ class Param(CoreParam):
         else:
             # Other types
             dt_str = str(e)
+            # ensure that value is a UTF-8 string
+            # Old PMTs could produce non-UTF-8 strings
+            dt_str = dt_str.encode('utf-8', 'backslashreplace').decode('utf-8')
 
         # Done
         return _truncate(dt_str, truncate)
-- 
cgit v1.2.3