From 306f9e57355c39ef8f5d87ce547cbd347ca9b80d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 29 Dec 2022 17:04:02 +0530 Subject: [PATCH] Prettify URLs before displaying them to the user --- kitty/boss.py | 8 +++----- kitty/utils.py | 15 +++++++++++++++ kitty_tests/datatypes.py | 4 +++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/kitty/boss.py b/kitty/boss.py index b87b694f2..6017a24d6 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -8,7 +8,7 @@ import os import re import sys from contextlib import suppress -from functools import lru_cache, partial +from functools import partial from gettext import gettext as _ from time import monotonic, sleep from typing import ( @@ -64,7 +64,7 @@ from .utils import ( cleanup_ssh_control_masters, func_name, get_editor, get_new_os_window_size, is_path_in_temp_dir, less_version, log_error, macos_version, open_url, parse_address_spec, parse_uri_list, platform_window_id, remove_socket_file, - safe_print, single_instance, startup_notification_handler, which, + safe_print, single_instance, startup_notification_handler, which, sanitize_url_for_dispay_to_user ) from .window import CommandOutput, CwdRequest, Window @@ -2603,7 +2603,5 @@ class Boss: pass mouse_discard_event = discard_event - @lru_cache(maxsize=64) def sanitize_url_for_dispay_to_user(self, url: str) -> str: - # TODO: Use punycode, remove percent encoding, etc. - return url + return sanitize_url_for_dispay_to_user(url) diff --git a/kitty/utils.py b/kitty/utils.py index 48e14dff8..dc568be54 100644 --- a/kitty/utils.py +++ b/kitty/utils.py @@ -1088,3 +1088,18 @@ def sanitize_for_bracketed_paste(text: bytes) -> bytes: break text = new_text return text + + +@lru_cache(maxsize=64) +def sanitize_url_for_dispay_to_user(url: str) -> str: + from urllib.parse import urlparse, urlunparse, unquote + try: + purl = urlparse(url) + if purl.netloc: + purl = purl._replace(netloc=purl.netloc.encode('idna').decode('ascii')) + if purl.path: + purl = purl._replace(path=unquote(purl.path)) + url = urlunparse(purl) + except Exception: + url = 'Unpareseable URL: ' + url + return url diff --git a/kitty_tests/datatypes.py b/kitty_tests/datatypes.py index 3061883c4..9b6f12e81 100644 --- a/kitty_tests/datatypes.py +++ b/kitty_tests/datatypes.py @@ -12,7 +12,7 @@ from kitty.fast_data_types import ( wcwidth, expand_ansi_c_escapes ) from kitty.rgb import to_color -from kitty.utils import is_path_in_temp_dir, sanitize_title +from kitty.utils import is_path_in_temp_dir, sanitize_title, sanitize_url_for_dispay_to_user from . import BaseTest, filled_cursor, filled_history_buf, filled_line_buf @@ -436,6 +436,8 @@ class TestDataTypes(BaseTest): 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))) + self.ae(sanitize_url_for_dispay_to_user( + 'h://a\u0430b.com/El%20Ni%C3%B1o/'), 'h://xn--ab-7kc.com/El NiƱo/') def test_color_profile(self): c = ColorProfile()