From bf4546ad0887bfedab638c40817562458b77b69e Mon Sep 17 00:00:00 2001 From: EminY <57416756+emincan2000@users.noreply.github.com> Date: Mon, 2 Nov 2026 15:08:00 +0000 Subject: [PATCH] Reject 0x, signs, underscores and stray hyphens in uuid() UUID() drops every hyphen wherever it is and parses the rest with int(), so strings like "0x" plus 30 hex digits or a UUID with a moved hyphen were accepted. The regex fallback meant to catch this never ran because a UUID object is always truthy. Match the forms UUID() documents directly instead. --- src/validators/uuid.py | 12 ++++++------ tests/test_uuid.py | 11 +++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/validators/uuid.py b/src/validators/uuid.py index ca6b1ba0..c3f149a7 100644 --- a/src/validators/uuid.py +++ b/src/validators/uuid.py @@ -35,9 +35,9 @@ def uuid(value: Union[str, UUID], /): return False if isinstance(value, UUID): return True - try: - return UUID(value) or re.match( - r"^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$", value - ) - except ValueError: - return False + # Not UUID(value): it drops hyphens wherever they are and reads the rest with int(), + # which also takes "0x", signs, underscores, surrounding spaces and non-ASCII digits. + return re.fullmatch( + r"(?:urn:uuid:)?(\{)?[0-9a-fA-F]{8}(-?)(?:[0-9a-fA-F]{4}\2){3}[0-9a-fA-F]{12}(?(1)\})", + value, + ) diff --git a/tests/test_uuid.py b/tests/test_uuid.py index b4f40d29..c0c03d35 100644 --- a/tests/test_uuid.py +++ b/tests/test_uuid.py @@ -18,6 +18,10 @@ ("2bc1c94f-0deb-43e9-92a1-4775189ec9f8",), (uuid4(),), ("888256d7c49341f19fa33f29d3f820d7",), + ("2BC1C94F-0DEB-43E9-92A1-4775189EC9F8",), + ("{2bc1c94f-0deb-43e9-92a1-4775189ec9f8}",), + ("{888256d7c49341f19fa33f29d3f820d7}",), + ("urn:uuid:2bc1c94f-0deb-43e9-92a1-4775189ec9f8",), ], ) def test_returns_true_on_valid_uuid(value: Union[str, UUID]): @@ -32,6 +36,13 @@ def test_returns_true_on_valid_uuid(value: Union[str, UUID]): ("2bc1c94f-0deb-43e9-92a1-4775189ec9f",), ("gbc1c94f-0deb-43e9-92a1-4775189ec9f8",), ("2bc1c94f 0deb-43e9-92a1-4775189ec9f8",), + ("2bc1c94f-0deb4-3e9-92a1-4775189ec9f8",), + ("2bc1c94f-0deb43e992a14775189ec9f8",), + ("0xc1c94f0deb43e992a14775189ec9f8",), + ("+bc1c94f0deb43e992a14775189ec9f8",), + ("2bc1c94f_deb43e992a14775189ec9f8",), + (" bc1c94f0deb43e992a14775189ec9f ",), + ("2bc1c94f-0deb-43e9-92a1-4775189ec9f8}",), ], ) def test_returns_failed_validation_on_invalid_uuid(value: Union[str, UUID]):