Graphics protocol: Only delete temp files if they have the string tty-graphics-protocol in their file paths.

This prevents deletion of arbitrary files in /tmp via the graphics
protocol.
This commit is contained in:
Kovid Goyal 2022-08-16 11:19:32 +05:30
parent ca2a121696
commit d0c50248ea
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 12 additions and 8 deletions

View File

@ -44,6 +44,9 @@ Detailed list of changes
- A new option :opt:`modify_font` to adjust various font metrics like underlines, cell sizes etc. (:pull:`5265`) - A new option :opt:`modify_font` to adjust various font metrics like underlines, cell sizes etc. (:pull:`5265`)
- Graphics protocol: Only delete temp files if they have the string
:code:`tty-graphics-protocol` in their file paths. This prevents deletion of arbitrary files in :file:`/tmp`.
- Deprecate the ``adjust_baseline``, ``adjust_line_height`` and ``adjust_column_width`` options in favor of :opt:`modify_font` - Deprecate the ``adjust_baseline``, ``adjust_line_height`` and ``adjust_column_width`` options in favor of :opt:`modify_font`
- Wayland: Fix a regression in the previous release that caused mouse cursor - Wayland: Fix a regression in the previous release that caused mouse cursor

View File

@ -237,7 +237,8 @@ Value of `t` Meaning
the terminal emulator should only delete the file if it the terminal emulator should only delete the file if it
is in a known temporary directory, such as :file:`/tmp`, is in a known temporary directory, such as :file:`/tmp`,
:file:`/dev/shm`, :file:`TMPDIR env var if present` and any platform :file:`/dev/shm`, :file:`TMPDIR env var if present` and any platform
specific temporary directories. specific temporary directories and the file has the
string :code:`tty-graphics-protocol` in its full file path.
``s`` A *shared memory object*, which on POSIX systems is a ``s`` A *shared memory object*, which on POSIX systems is a
`POSIX shared memory object <https://pubs.opengroup.org/onlinepubs/9699919799/functions/shm_open.html>`_ `POSIX shared memory object <https://pubs.opengroup.org/onlinepubs/9699919799/functions/shm_open.html>`_
and on Windows is a and on Windows is a

View File

@ -353,7 +353,7 @@ def process(path: str, args: IcatCLIOptions, parsed_opts: ParsedOpts, is_tempfil
else: else:
import struct import struct
use_number = max(1, struct.unpack('@I', os.urandom(4))[0]) use_number = max(1, struct.unpack('@I', os.urandom(4))[0])
with NamedTemporaryFile() as f: with NamedTemporaryFile(prefix='tty-graphics-protocol-') as f:
prefix = f.name prefix = f.name
frame_data = render_image( frame_data = render_image(
path, prefix, m, available_width, available_height, args.scale_up, path, prefix, m, available_width, available_height, args.scale_up,
@ -405,7 +405,7 @@ def detect_support(wait_for: float = 10, silent: bool = False) -> bool:
parse_responses() parse_responses()
return 1 not in responses or 2 not in responses return 1 not in responses or 2 not in responses
with NamedTemporaryFile() as f: with NamedTemporaryFile(prefix='tty-graphics-protocol') as f:
f.write(b'abcd') f.write(b'abcd')
f.flush() f.flush()
gc = GraphicsCommand() gc = GraphicsCommand()
@ -472,13 +472,13 @@ def process_single_item(
file_removed = False file_removed = False
try: try:
if isinstance(item, bytes): if isinstance(item, bytes):
with NamedTemporaryFile(prefix='stdin-image-data-', delete=False) as tf: with NamedTemporaryFile(prefix='tty-graphics-protocol-', delete=False) as tf:
tf.write(item) tf.write(item)
item = tf.name item = tf.name
is_tempfile = True is_tempfile = True
if url_pat is not None and url_pat.match(item) is not None: if url_pat is not None and url_pat.match(item) is not None:
from urllib.request import urlretrieve from urllib.request import urlretrieve
with NamedTemporaryFile(prefix='url-image-data-', delete=False) as tf: with NamedTemporaryFile(prefix='tty-graphics-protocol-', delete=False) as tf:
try: try:
with socket_timeout(30): with socket_timeout(30):
urlretrieve(item, filename=tf.name) urlretrieve(item, filename=tf.name)

View File

@ -301,7 +301,7 @@ def render_as_single_image(
remove_alpha: str = '', flip: bool = False, flop: bool = False, remove_alpha: str = '', flip: bool = False, flop: bool = False,
) -> Tuple[str, int, int]: ) -> Tuple[str, int, int]:
import tempfile import tempfile
fd, output = tempfile.mkstemp(prefix='icat-', suffix=f'.{m.mode}', dir=tdir) fd, output = tempfile.mkstemp(prefix='tty-graphics-protocol-', suffix=f'.{m.mode}', dir=tdir)
os.close(fd) os.close(fd)
result = render_image( result = render_image(
path, output, m, available_width, available_height, scale_up, path, output, m, available_width, available_height, scale_up,

View File

@ -419,7 +419,7 @@ load_image_data(GraphicsManager *self, Image *img, const GraphicsCommand *g, con
if (fd == -1) ABRT("EBADF", "Failed to open file for graphics transmission with error: [%d] %s", errno, strerror(errno)); if (fd == -1) ABRT("EBADF", "Failed to open file for graphics transmission with error: [%d] %s", errno, strerror(errno));
load_data->loading_completed_successfully = mmap_img_file(self, fd, g->data_sz, g->data_offset); load_data->loading_completed_successfully = mmap_img_file(self, fd, g->data_sz, g->data_offset);
safe_close(fd, __FILE__, __LINE__); safe_close(fd, __FILE__, __LINE__);
if (transmission_type == 't') { if (transmission_type == 't' && strstr(fname, "tty-graphics-protocol") != NULL) {
if (global_state.boss) { call_boss(safe_delete_temp_file, "s", fname); } if (global_state.boss) { call_boss(safe_delete_temp_file, "s", fname); }
else unlink(fname); else unlink(fname);
} }

View File

@ -360,7 +360,7 @@ class TestGraphics(BaseTest):
self.ae(img['data'], random_data) self.ae(img['data'], random_data)
# Test loading from file # Test loading from file
f = tempfile.NamedTemporaryFile() f = tempfile.NamedTemporaryFile(prefix='tty-graphics-protocol-')
f.write(random_data), f.flush() f.write(random_data), f.flush()
sl(f.name, s=24, v=32, t='f', expecting_data=random_data) sl(f.name, s=24, v=32, t='f', expecting_data=random_data)
self.assertTrue(os.path.exists(f.name)) self.assertTrue(os.path.exists(f.name))