diff --git a/docs/changelog.rst b/docs/changelog.rst index 252c0e562..4e81adfc1 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -10,6 +10,10 @@ To update |kitty|, :doc:`follow the instructions `. - macOS: Fix themes kitten failing to download themes because of missing SSL certificates (:iss:`3936`) +- A new option :opt:`clipboard_max_size` to control the maximum size + of data that kitty will transmit to the system clipboard on behalf of + programs running inside it (:iss:`3937`) + - A new :doc:`themes kitten ` to easily change kitty themes. 0.23.0 [2021-08-16] ---------------------- diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 610d5abb6..36e082c31 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -2533,10 +2533,17 @@ control exactly which actions are allowed. The set of possible actions is: write-clipboard read-clipboard write-primary read-primary. The default is to allow writing to the clipboard and primary selection. Note that enabling the read functionality is a security risk as it means that any program, even one -running on a remote server via SSH can read your clipboard. +running on a remote server via SSH can read your clipboard. See also :opt:` +clipboard_max_size`. ''' ) +opt('clipboard_max_size', 64, option_type='positive_float', long_text=''' +The maximum size (in MB) of data from programs running in kitty that will be +stored for writing to the system clipboard. See also :opt:`clipboard_control`. +A value of zero means no size limit is applied. +''') + opt('allow_hyperlinks', 'yes', option_type='allow_hyperlinks', ctype='bool', long_text=''' diff --git a/kitty/options/parse.py b/kitty/options/parse.py index f0731585b..581a25d25 100644 --- a/kitty/options/parse.py +++ b/kitty/options/parse.py @@ -102,6 +102,9 @@ class Parser: def clipboard_control(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['clipboard_control'] = clipboard_control(val) + def clipboard_max_size(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: + ans['clipboard_max_size'] = positive_float(val) + def close_on_child_death(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['close_on_child_death'] = to_bool(val) diff --git a/kitty/options/types.py b/kitty/options/types.py index 919d04847..b3fb63e9d 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -65,6 +65,7 @@ option_names = ( # {{{ 'clear_all_shortcuts', 'click_interval', 'clipboard_control', + 'clipboard_max_size', 'close_on_child_death', 'color0', 'color1', @@ -458,6 +459,7 @@ class Options: clear_all_shortcuts: bool = False click_interval: float = -1.0 clipboard_control: typing.Tuple[str, ...] = ('write-clipboard', 'write-primary') + clipboard_max_size: float = 64.0 close_on_child_death: bool = False command_on_bell: typing.List[str] = ['none'] confirm_os_window_close: int = 0 diff --git a/kitty/window.py b/kitty/window.py index d83bf46bb..7190964e6 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -791,7 +791,8 @@ class Window: self.clipboard_pending = ClipboardPending(where, text) else: self.clipboard_pending = self.clipboard_pending._replace(data=self.clipboard_pending[1] + text) - if len(self.clipboard_pending.data) > 8 * 1024 * 1024: + limit = get_options().clipboard_max_size + if limit and len(self.clipboard_pending.data) > limit * 1024 * 1024: log_error('Discarding part of too large OSC 52 paste request') self.clipboard_pending = self.clipboard_pending._replace(data='', truncated=True) return