Graphics protocol: Only delete temporary image-data files if they are in a known temporary file location
This commit is contained in:
parent
4a8562a85f
commit
d20c65ef80
@ -201,7 +201,11 @@ Value of `t` Meaning
|
|||||||
================== ============
|
================== ============
|
||||||
``d`` Direct (the data is transmitted within the escape code itself)
|
``d`` Direct (the data is transmitted within the escape code itself)
|
||||||
``f`` A simple file
|
``f`` A simple file
|
||||||
``t`` A temporary file, the terminal emulator will delete the file after reading the pixel data
|
``t`` A temporary file, the terminal emulator will delete the file after reading the pixel data. For security reasons
|
||||||
|
the terminal emulator should only delete the file if it
|
||||||
|
is in a known temporary directory, such as :file:`/tmp`,
|
||||||
|
:file:`/dev/shm`, :file:`TMPDIR env var if present` and any platform
|
||||||
|
specific temporary directories.
|
||||||
``s`` A `POSIX shared memory object <http://man7.org/linux/man-pages/man7/shm_overview.7.html>`_.
|
``s`` A `POSIX shared memory object <http://man7.org/linux/man-pages/man7/shm_overview.7.html>`_.
|
||||||
The terminal emulator will delete it after reading the pixel data
|
The terminal emulator will delete it after reading the pixel data
|
||||||
================== ============
|
================== ============
|
||||||
|
|||||||
@ -32,9 +32,9 @@ from .rgb import Color, color_from_int
|
|||||||
from .session import create_session
|
from .session import create_session
|
||||||
from .tabs import SpecialWindow, SpecialWindowInstance, TabManager
|
from .tabs import SpecialWindow, SpecialWindowInstance, TabManager
|
||||||
from .utils import (
|
from .utils import (
|
||||||
get_editor, get_primary_selection, log_error, open_url, parse_address_spec,
|
get_editor, get_primary_selection, is_path_in_temp_dir, log_error,
|
||||||
remove_socket_file, safe_print, set_primary_selection, single_instance,
|
open_url, parse_address_spec, remove_socket_file, safe_print,
|
||||||
startup_notification_handler
|
set_primary_selection, single_instance, startup_notification_handler
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -959,3 +959,7 @@ class Boss:
|
|||||||
for tm in self.all_tab_managers:
|
for tm in self.all_tab_managers:
|
||||||
tm.tab_bar.patch_colors(spec)
|
tm.tab_bar.patch_colors(spec)
|
||||||
patch_global_colors(spec, configured)
|
patch_global_colors(spec, configured)
|
||||||
|
|
||||||
|
def safe_delete_temp_file(self, path):
|
||||||
|
if is_path_in_temp_dir(path):
|
||||||
|
os.remove(path)
|
||||||
|
|||||||
@ -368,7 +368,7 @@ handle_add_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_
|
|||||||
if (fd == -1) ABRT(EBADF, "Failed to open file %s for graphics transmission with error: [%d] %s", fname, errno, strerror(errno));
|
if (fd == -1) ABRT(EBADF, "Failed to open file %s for graphics transmission with error: [%d] %s", fname, errno, strerror(errno));
|
||||||
img->data_loaded = mmap_img_file(self, img, fd, g->data_sz, g->data_offset);
|
img->data_loaded = mmap_img_file(self, img, fd, g->data_sz, g->data_offset);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (tt == 't') unlink(fname);
|
if (tt == 't') { call_boss(safe_delete_temp_file, "s", fname); }
|
||||||
else if (tt == 's') shm_unlink(fname);
|
else if (tt == 's') shm_unlink(fname);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -432,3 +432,20 @@ def get_editor():
|
|||||||
ans = shlex.split(ans)
|
ans = shlex.split(ans)
|
||||||
get_editor.ans = ans
|
get_editor.ans = ans
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
|
def is_path_in_temp_dir(path):
|
||||||
|
if not path:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def abspath(x):
|
||||||
|
if x:
|
||||||
|
return os.path.abspath(os.path.realpath(x))
|
||||||
|
|
||||||
|
import tempfile
|
||||||
|
path = abspath(path)
|
||||||
|
candidates = frozenset(map(abspath, ('/tmp', '/dev/shm', os.environ.get('TMPDIR', None), tempfile.gettempdir())))
|
||||||
|
for q in candidates:
|
||||||
|
if q and path.startswith(q):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|||||||
@ -2,13 +2,16 @@
|
|||||||
# vim:fileencoding=utf-8
|
# vim:fileencoding=utf-8
|
||||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
|
||||||
from kitty.config import build_ansi_color_table, defaults
|
from kitty.config import build_ansi_color_table, defaults
|
||||||
from kitty.fast_data_types import (
|
from kitty.fast_data_types import (
|
||||||
REVERSE, ColorProfile, Cursor as C, HistoryBuf, LineBuf,
|
REVERSE, ColorProfile, Cursor as C, HistoryBuf, LineBuf,
|
||||||
parse_input_from_terminal, wcswidth, wcwidth, truncate_point_for_length
|
parse_input_from_terminal, truncate_point_for_length, wcswidth, wcwidth
|
||||||
)
|
)
|
||||||
from kitty.rgb import to_color
|
from kitty.rgb import to_color
|
||||||
from kitty.utils import sanitize_title
|
from kitty.utils import is_path_in_temp_dir, sanitize_title
|
||||||
|
|
||||||
from . import BaseTest, filled_cursor, filled_history_buf, filled_line_buf
|
from . import BaseTest, filled_cursor, filled_history_buf, filled_line_buf
|
||||||
|
|
||||||
@ -384,6 +387,12 @@ class TestDataTypes(BaseTest):
|
|||||||
tp('a\033', '_', 'x\033', '\\b', text='a b', apc='x')
|
tp('a\033', '_', 'x\033', '\\b', text='a b', apc='x')
|
||||||
tp('a\033_', 'x', '\033', '\\', 'b', text='a b', apc='x')
|
tp('a\033_', 'x', '\033', '\\', 'b', text='a b', apc='x')
|
||||||
|
|
||||||
|
for prefix in ('/tmp', tempfile.gettempdir()):
|
||||||
|
for path in ('a.png', 'x/b.jpg', 'y/../c.jpg'):
|
||||||
|
self.assertTrue(is_path_in_temp_dir(os.path.join(prefix, path)))
|
||||||
|
for path in ('/home/xy/d.png', '/tmp/../home/x.jpg'):
|
||||||
|
self.assertFalse(is_path_in_temp_dir(os.path.join(path)))
|
||||||
|
|
||||||
def test_color_profile(self):
|
def test_color_profile(self):
|
||||||
c = ColorProfile()
|
c = ColorProfile()
|
||||||
c.update_ansi_color_table(build_ansi_color_table())
|
c.update_ansi_color_table(build_ansi_color_table())
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user