From f50c5bb1b2c0ab92d1fb13a334f846acac981dd6 Mon Sep 17 00:00:00 2001 From: Apeksha_2022 <70309060+Apeksha9389@users.noreply.github.com> Date: Sun, 18 Oct 2026 02:48:16 +0530 Subject: [PATCH] Require complete bytes in Base16 encodings --- src/validators/encoding.py | 4 +++- tests/test_encoding.py | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/validators/encoding.py b/src/validators/encoding.py index c4ec2cea..7af12fcd 100644 --- a/src/validators/encoding.py +++ b/src/validators/encoding.py @@ -11,6 +11,8 @@ def base16(value: str, /): """Return whether or not given value is a valid base16 encoding. + Each encoded byte requires two hexadecimal characters. + Examples: >>> base16('a3f4b2') True @@ -25,7 +27,7 @@ def base16(value: str, /): (Literal[True]): If `value` is a valid base16 encoding. (ValidationError): If `value` is an invalid base16 encoding. """ - return re.fullmatch(r"^[0-9A-Fa-f]+$", value) if value else False + return re.fullmatch(r"(?:[0-9A-Fa-f]{2})+", value) if value else False @validator diff --git a/tests/test_encoding.py b/tests/test_encoding.py index 9728a8fe..c92d04e5 100644 --- a/tests/test_encoding.py +++ b/tests/test_encoding.py @@ -38,6 +38,12 @@ def test_returns_failed_validation_on_invalid_base16(value: str): assert isinstance(base16(value), ValidationError) +@pytest.mark.parametrize("value", ["0", "a", "ABC", "012345678", "abcdef01234567890"]) +def test_base16_rejects_incomplete_bytes(value: str): + """Reject a dangling half-byte even when every character is hexadecimal.""" + assert isinstance(base16(value), ValidationError) + + # ==> base32 <== #