Sanitize user vars

This commit is contained in:
Kovid Goyal
2023-07-27 19:00:21 +05:30
parent d9b41b7715
commit 950fbfbd73
3 changed files with 11 additions and 9 deletions

View File

@@ -620,7 +620,7 @@ def _launch(
new_window.overlay_type = OverlayType.main new_window.overlay_type = OverlayType.main
if opts.var: if opts.var:
for key, val in parse_var(opts.var): for key, val in parse_var(opts.var):
new_window.user_vars[key] = val new_window.set_user_var(key, val)
return new_window return new_window
return None return None

View File

@@ -30,21 +30,19 @@ class SetUserVars(RemoteCommand):
return {'match': opts.match, 'var': args, 'self': True} return {'match': opts.match, 'var': args, 'self': True}
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType: def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
remove = set()
val = {} val = {}
for x in payload_get('var') or (): for x in payload_get('var') or ():
a, sep, b = x.partition('=') a, sep, b = x.partition('=')
if sep: if sep:
val[a] = b val[a] = b
else: else:
remove.add(a) val[a] = None
lines = [] lines = []
for window in self.windows_for_match_payload(boss, window, payload_get): for window in self.windows_for_match_payload(boss, window, payload_get):
if window: if window:
if val or remove: if val:
window.user_vars.update(val) for k, v in val.items():
for x in remove: window.set_user_var(k, v)
window.user_vars.pop(x, None)
else: else:
lines.append('\n'.join(f'{k}={v}' for k, v in window.user_vars.items())) lines.append('\n'.join(f'{k}={v}' for k, v in window.user_vars.items()))
return '\n\n'.join(lines) return '\n\n'.join(lines)

View File

@@ -100,6 +100,7 @@ from .utils import (
path_from_osc7_url, path_from_osc7_url,
resolve_custom_file, resolve_custom_file,
resolved_shell, resolved_shell,
sanitize_control_codes,
sanitize_for_bracketed_paste, sanitize_for_bracketed_paste,
sanitize_title, sanitize_title,
sanitize_url_for_dispay_to_user, sanitize_url_for_dispay_to_user,
@@ -850,13 +851,16 @@ class Window:
self.override_title = title or None self.override_title = title or None
self.title_updated() self.title_updated()
def set_user_var(self, key: str, val: Optional[bytes]) -> None: def set_user_var(self, key: str, val: Optional[Union[str, bytes]]) -> None:
key = sanitize_control_codes(key).replace('\n', ' ')
self.user_vars.pop(key, None) # ensure key will be newest in user_vars even if already present self.user_vars.pop(key, None) # ensure key will be newest in user_vars even if already present
if len(self.user_vars) > 64: # dont store too many user vars if len(self.user_vars) > 64: # dont store too many user vars
oldest_key = next(iter(self.user_vars)) oldest_key = next(iter(self.user_vars))
self.user_vars.pop(oldest_key) self.user_vars.pop(oldest_key)
if val is not None: if val is not None:
self.user_vars[key] = val.decode('utf-8', 'replace') if isinstance(val, bytes):
val = val.decode('utf-8', 'replace')
self.user_vars[key] = sanitize_control_codes(val).replace('\n', ' ')
# screen callbacks {{{ # screen callbacks {{{