diff --git a/api/core/helper/trace_id_helper.py b/api/core/helper/trace_id_helper.py index e1ebd45e074..acf89706c93 100644 --- a/api/core/helper/trace_id_helper.py +++ b/api/core/helper/trace_id_helper.py @@ -22,7 +22,7 @@ def is_valid_trace_id(trace_id: str) -> bool: Requirements: 1-128 characters, only letters, numbers, '-', and '_'. """ - return bool(re.match(r"^[a-zA-Z0-9\-_]{1,128}$", trace_id)) + return bool(re.fullmatch(r"[a-zA-Z0-9\-_]{1,128}", trace_id)) def get_external_trace_id(request: Any) -> str | None: diff --git a/api/tests/unit_tests/core/helper/test_trace_id_helper.py b/api/tests/unit_tests/core/helper/test_trace_id_helper.py index b5f6d6a11aa..ef03c7b5bf5 100644 --- a/api/tests/unit_tests/core/helper/test_trace_id_helper.py +++ b/api/tests/unit_tests/core/helper/test_trace_id_helper.py @@ -16,6 +16,24 @@ from core.helper.trace_id_helper import ( ) +@pytest.mark.parametrize( + ("trace_id", "expected"), + [ + ("abc", True), + ("a" * 128, True), + ("a" * 129, False), + # `$` also matches before a trailing newline, so "abc\n" used to slip + # through the character filter and the 128-character ceiling. + ("abc\n", False), + ("\nabc", False), + ("a" * 128 + "\n", False), + ("abc\r", False), + ], +) +def test_is_valid_trace_id_boundaries(trace_id: str, expected: bool) -> None: + assert is_valid_trace_id(trace_id) is expected + + def test_extract_trace_session_id_from_args_for_generator_extras(): assert extract_trace_session_id_from_args({"trace_session_id": "session-1"}) == { "trace_session_id": "session-1",