diff --git a/CHANGELOG.md b/CHANGELOG.md index 359ad7d7876..fae7b823869 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-distro` & `opentelemetry-sdk` Moved Auto Instrumentation Configurator code to SDK to let distros use its default implementation ([#1937](https://github.com/open-telemetry/opentelemetry-python/pull/1937)) +- Add Trace ID validation to meet [TraceID spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/overview.md#spancontext) ([#1992](https://github.com/open-telemetry/opentelemetry-python/pull/1992)) ## [0.23.1](https://github.com/open-telemetry/opentelemetry-python/pull/1987) - 2021-07-26 diff --git a/opentelemetry-api/src/opentelemetry/trace/span.py b/opentelemetry-api/src/opentelemetry/trace/span.py index c4c713cf3e7..832b8b62f6a 100644 --- a/opentelemetry-api/src/opentelemetry/trace/span.py +++ b/opentelemetry-api/src/opentelemetry/trace/span.py @@ -389,6 +389,7 @@ def values(self) -> typing.ValuesView[str]: DEFAULT_TRACE_STATE = TraceState.get_default() +_TRACE_ID_HEX_LENGTH = 2 ** 128 - 1 class SpanContext( @@ -420,7 +421,11 @@ def __new__( if trace_state is None: trace_state = DEFAULT_TRACE_STATE - is_valid = trace_id != INVALID_TRACE_ID and span_id != INVALID_SPAN_ID + is_valid = ( + trace_id != INVALID_TRACE_ID + and span_id != INVALID_SPAN_ID + and trace_id < _TRACE_ID_HEX_LENGTH + ) return tuple.__new__( cls, diff --git a/opentelemetry-api/tests/trace/test_span_context.py b/opentelemetry-api/tests/trace/test_span_context.py index c109d006a53..1ec32253c31 100644 --- a/opentelemetry-api/tests/trace/test_span_context.py +++ b/opentelemetry-api/tests/trace/test_span_context.py @@ -34,3 +34,12 @@ def test_span_context_pickle(self): pickle_sc = pickle.loads(pickle.dumps(sc)) self.assertEqual(sc.trace_id, pickle_sc.trace_id) self.assertEqual(sc.span_id, pickle_sc.span_id) + + invalid_sc = trace.SpanContext( + 9999999999999999999999999999999999999999999999999999999999999999999999999999, + 9, + is_remote=False, + trace_flags=trace.DEFAULT_TRACE_OPTIONS, + trace_state=trace.DEFAULT_TRACE_STATE, + ) + self.assertFalse(invalid_sc.is_valid)