From fad3e5187e7ee556b9732ad1473ad88837b084fc Mon Sep 17 00:00:00 2001 From: Vlad Doloman Date: Sat, 15 Aug 2026 05:26:31 +0300 Subject: [PATCH] Add optional charset restriction to InputField Co-Authored-By: Claude Opus 5 --- openvpncertupdate.py | 22 +++++++++++++--------- tests/test_widgets.py | 27 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/openvpncertupdate.py b/openvpncertupdate.py index 57c8d92..5541c4b 100644 --- a/openvpncertupdate.py +++ b/openvpncertupdate.py @@ -689,15 +689,16 @@ class InputField: def __init__( self, win, y: int, x: int, width: int, - initial: str = "", mask: bool = False, + initial: str = "", mask: bool = False, allowed: Optional[str] = None, ) -> None: - self._win = win - self._y = y - self._x = x - self._width = width - self._mask = mask - self._buf = list(initial) - self._cur = len(self._buf) + self._win = win + self._y = y + self._x = x + self._width = width + self._mask = mask + self._allowed = allowed + self._buf = list(initial) + self._cur = len(self._buf) @property def value(self) -> str: @@ -737,7 +738,10 @@ class InputField: if self._cur < len(self._buf): del self._buf[self._cur] elif 32 <= key <= 126: - self._buf.insert(self._cur, chr(key)) + ch = chr(key) + if self._allowed is not None and ch not in self._allowed: + return + self._buf.insert(self._cur, ch) self._cur += 1 diff --git a/tests/test_widgets.py b/tests/test_widgets.py index b0d4b7d..19d17ed 100644 --- a/tests/test_widgets.py +++ b/tests/test_widgets.py @@ -94,3 +94,30 @@ def test_init_colors_survives_init_pair_rejecting_every_pair(): side_effect=_curses.error("init_pair() returned ERR")), \ patch.object(_curses, "COLORS", 256, create=True): init_colors() # must not raise + + +def test_allowed_charset_accepts_listed_characters(): + f = InputField(MagicMock(), 0, 0, 10, initial="", allowed="0123456789") + for ch in "90": + f.handle_key(ord(ch)) + assert f.value == "90" + + +def test_allowed_charset_drops_other_characters(): + f = InputField(MagicMock(), 0, 0, 10, initial="", allowed="0123456789") + for ch in "9a0-!": + f.handle_key(ord(ch)) + assert f.value == "90" + + +def test_allowed_none_accepts_everything(): + f = InputField(MagicMock(), 0, 0, 10, initial="") + for ch in "a-1!": + f.handle_key(ord(ch)) + assert f.value == "a-1!" + + +def test_allowed_charset_still_supports_editing_keys(): + f = InputField(MagicMock(), 0, 0, 10, initial="90", allowed="0123456789") + f.handle_key(_curses.KEY_BACKSPACE) + assert f.value == "9"