From 169315d33d6bba6907346cde3628ea6fa459ed33 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 4 Nov 2023 07:23:59 +0530 Subject: [PATCH] Improve paste sanitization Replace C0 chars with their graphical equivalents and \n with \eE which has the same visual effect. C1 chars are replaced by reverse question mark. --- kitty/utils.py | 2 +- kitty/window.py | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/kitty/utils.py b/kitty/utils.py index dbd4444b3..2c0127afd 100644 --- a/kitty/utils.py +++ b/kitty/utils.py @@ -1022,7 +1022,7 @@ def reload_conf_in_all_kitties() -> None: @run_once def control_codes_pat() -> 'Pattern[str]': - return re.compile('[\x00-\x09\x0b-\x1f\x7f\x80-\x9f]') + return re.compile('[\x00-\x09\x0b-\x1f\x7f-\x9f]') def sanitize_control_codes(text: str, replace_with: str = '') -> str: diff --git a/kitty/window.py b/kitty/window.py index 1029f8ead..f8747e9d0 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -479,6 +479,18 @@ class GlobalWatchers: global_watchers = GlobalWatchers() +def replace_control_codes(text: str) -> str: + # Replace all control codes other than tab, newline and space with their graphical counterparts + def sub(m: re.Match[str]) -> str: + c = ord(m.group()) + if c < 0x20: + return chr(0x2400 + c) + if c == 0x7f: + return '\u2421' + return '\u2426' + return re.sub(r'[\0-\x08\x0b-\x19\x7f-\x9f]', sub, text) + + class Window: window_custom_type: str = '' @@ -1499,12 +1511,14 @@ class Window: text = shlex.quote(text) btext = text.encode('utf-8') if 'confirm' in opts.paste_actions: - sanitized = sanitize_control_codes(text) + sanitized = replace_control_codes(text) if not self.screen.in_bracketed_paste_mode: # \n is converted to \r and \r is interpreted as the enter key # by legacy programs that dont support the full kitty keyboard protocol, - # which in the case of shells can lead to command execution - sanitized = re.sub(r'[\r\n]', ' ', sanitized) + # which in the case of shells can lead to command execution. + # \eE has the same visual effect as \r\n but without the + # command execution risk. + sanitized = sanitized.replace('\n', '\x1bE') if sanitized != text: msg = _('The text to be pasted contains terminal control codes.\n\nIf the terminal program you are pasting into does not properly' ' sanitize pasted text, this can lead to \x1b[31mcode execution vulnerabilities\x1b[39m.\n\nHow would you like to proceed?')