From 7bfa03a78ca1143bf11bafa89c1b9cf0c08c942b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 10 Feb 2021 15:20:53 +0100 Subject: Add common message text sanitization. --- alot/settings/manager.py | 36 +++++++++++++++++++++++++++++++++++- alot/widgets/search.py | 4 +--- alot/widgets/thread.py | 6 ++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/alot/settings/manager.py b/alot/settings/manager.py index 1be5a0cc..a1e2ab6d 100644 --- a/alot/settings/manager.py +++ b/alot/settings/manager.py @@ -2,8 +2,9 @@ # This file is released under the GNU GPL, version 3 or a later revision. # For further details see the COPYING file -from datetime import datetime, timedelta +from datetime import datetime, timedelta import email +from functools import cached_property import importlib.util import itertools import logging @@ -596,3 +597,36 @@ class SettingsManager: else: rep = _pretty_datetime(d) return rep + + def _make_trans_table(self, tab_width): + table = {} + + # remove C1 control codes + for i in range(0x80, 0xa0): + table[i] = None + + # replace C0 control codes with characters for their graphical + # representations i.e. "control pictures", which start at U+2400 + for i in range(ord(' ')): + table[i] = 0x2400 + i + + # "delete" character + table[0x7f] = 0x2421 + + # delete LF + table[ord('\r')] = None + + # handle CR normally + del table[ord('\n')] + + # expand tabs + table[ord('\t')] = ' ' * tab_width + + return table + + @cached_property + def sanitize_text_table(self): + return self._make_trans_table(self.get('tabwidth')) + @cached_property + def sanitize_header_table(self): + return self._make_trans_table(1) diff --git a/alot/widgets/search.py b/alot/widgets/search.py index 12cf84e8..43a71434 100644 --- a/alot/widgets/search.py +++ b/alot/widgets/search.py @@ -212,9 +212,7 @@ def prepare_string(partname, thread, query, maxw): # get string s = content(thread, query) - # sanitize - s = s.replace('\n', ' ') - s = s.replace('\r', '') + s = s.translate(settings.sanitize_header_table) # shorten if max width is requested if maxw: diff --git a/alot/widgets/thread.py b/alot/widgets/thread.py index 7d3bafca..90eeabdf 100644 --- a/alot/widgets/thread.py +++ b/alot/widgets/thread.py @@ -40,6 +40,8 @@ class MessageSummaryWidget(urwid.WidgetWrap): if date is not None: text += " (%s)" % date + text = text.translate(settings.sanitize_header_table) + cols = [urwid.Text(text)] if settings.get('msg_summary_hides_threadwide_tags'): @@ -288,6 +290,8 @@ class _TextPart(_MIMEPartWidget): self._fold_context = settings.get('thread_fold_context') + text = text.translate(settings.sanitize_text_table) + # try highlighting with pygments first hilit = self._highlight_pygments(text, part, attr_text) if hilit is None: @@ -562,6 +566,8 @@ class HeadersWidget(urwid.WidgetWrap): widgets = [] for key, value in headers: + value = value.translate(settings.sanitize_header_table) + # TODO even/odd keyw = ('fixed', max_key_len + 1, urwid.Text((self._key_attr, key))) -- cgit v1.2.3