@@ -200,6 +200,38 @@ def test_control_chars_with_echo_char(self):
200200 self .assertEqual (result , expect_result )
201201 self .assertEqual ('Password: *******\x08 \x08 ' , mock_output .getvalue ())
202202
203+ class GetpassEchoCharValidationTest (unittest .TestCase ):
204+ def test_accepts_none (self ):
205+ getpass ._check_echo_char (None )
206+
207+ def test_accepts_single_printable_ascii (self ):
208+ for ch in ["*" , "A" , " " ]:
209+ getpass ._check_echo_char (ch )
210+
211+ def test_rejects_multi_character_strings (self ):
212+ for s in ["***" , "AA" , "aA*!" ]:
213+ with self .assertRaises (ValueError ):
214+ getpass ._check_echo_char (s )
215+
216+ def test_rejects_non_ascii (self ):
217+ for s in ["Æ" , "❤️" , "🐍" ]:
218+ with self .assertRaises (ValueError ):
219+ getpass ._check_echo_char (s )
220+
221+ def test_rejects_control_characters (self ):
222+ for ch in ["\n " , "\t " , "\r " , "\x00 " , "\x7f " , "\x07 " ]:
223+ with self .assertRaises (ValueError ):
224+ getpass ._check_echo_char (ch )
225+
226+ def test_rejects_non_string (self ):
227+ for item in [b"*" , 0 ]:
228+ with self .assertRaises (TypeError ):
229+ getpass ._check_echo_char (item )
230+
231+ def test_rejects_empty_string (self ):
232+ for item in ["" ]:
233+ with self .assertRaises (ValueError ):
234+ getpass ._check_echo_char (item )
203235
204236if __name__ == "__main__" :
205237 unittest .main ()
0 commit comments