Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-opentelemetry-api for 
openSUSE:Factory checked in at 2026-11-03 17:51:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-opentelemetry-api (Old)
 and      /work/SRC/openSUSE:Factory/.python-opentelemetry-api.new.1257 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-opentelemetry-api"

Tue Nov  3 17:51:46 2026 rev:28 rq:1394355 version:1.45.1

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-opentelemetry-api/python-opentelemetry-api.changes
        2026-09-30 16:23:10.870674132 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-opentelemetry-api.new.1257/python-opentelemetry-api.changes
      2026-11-03 17:51:51.178009905 +0100
@@ -1,0 +2,10 @@
+Sun Nov  1 15:11:12 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to 1.45.1:
+  * Make AnyValue and AttributeValue explicit type aliases.
+  * Fix quadratic-time parsing of the tracestate header and
+    discard headers longer than 8192 characters.
+  * CVE-2026-114603: denial of service via unbounded whitespace
+    matching in TraceState.from_header (boo#1287483)
+
+-------------------------------------------------------------------

Old:
----
  opentelemetry_api-1.45.0.tar.gz

New:
----
  opentelemetry_api-1.45.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-opentelemetry-api.spec ++++++
--- /var/tmp/diff_new_pack.PuS05O/_old  2026-11-03 17:51:52.445062866 +0100
+++ /var/tmp/diff_new_pack.PuS05O/_new  2026-11-03 17:51:52.447062950 +0100
@@ -26,7 +26,7 @@
 %endif
 %{?sle15_python_module_pythons}
 Name:           python-opentelemetry-api%{?psuffix}
-Version:        1.45.0
+Version:        1.45.1
 Release:        0
 Summary:        OpenTelemetry Python API
 License:        Apache-2.0
@@ -44,7 +44,7 @@
 # /SECTION
 %if %{with test}
 BuildRequires:  %{python_module opentelemetry-api = %{version}}
-BuildRequires:  %{python_module opentelemetry-test-utils = 0.66b0}
+BuildRequires:  %{python_module opentelemetry-test-utils = 0.66b1}
 BuildRequires:  %{python_module pytest}
 %endif
 %python_subpackages

++++++ opentelemetry_api-1.45.0.tar.gz -> opentelemetry_api-1.45.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/opentelemetry_api-1.45.0/PKG-INFO 
new/opentelemetry_api-1.45.1/PKG-INFO
--- old/opentelemetry_api-1.45.0/PKG-INFO       2020-02-02 01:00:00.000000000 
+0100
+++ new/opentelemetry_api-1.45.1/PKG-INFO       2020-02-02 01:00:00.000000000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.5
 Name: opentelemetry-api
-Version: 1.45.0
+Version: 1.45.1
 Summary: OpenTelemetry Python API
 Project-URL: Homepage, 
https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-api
 Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_api-1.45.0/src/opentelemetry/trace/propagation/tracecontext.py
 
new/opentelemetry_api-1.45.1/src/opentelemetry/trace/propagation/tracecontext.py
--- 
old/opentelemetry_api-1.45.0/src/opentelemetry/trace/propagation/tracecontext.py
    2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_api-1.45.1/src/opentelemetry/trace/propagation/tracecontext.py
    2020-02-02 01:00:00.000000000 +0100
@@ -1,13 +1,19 @@
 # Copyright The OpenTelemetry Authors
 # SPDX-License-Identifier: Apache-2.0
 #
+import logging
 import re
 
 from opentelemetry import trace
 from opentelemetry.context.context import Context
 from opentelemetry.propagators import textmap
 from opentelemetry.trace import format_span_id, format_trace_id
-from opentelemetry.trace.span import TraceState
+from opentelemetry.trace.span import (
+    _TRACECONTEXT_MAXIMUM_TRACESTATE_LENGTH,
+    TraceState,
+)
+
+_logger = logging.getLogger(__name__)
 
 
 class TraceContextTextMapPropagator(textmap.TextMapPropagator):
@@ -57,6 +63,16 @@
         tracestate_headers = getter.get(carrier, self._TRACESTATE_HEADER_NAME)
         if tracestate_headers is None:
             tracestate = None
+        elif (
+            # multiple header fields are combined with "," (RFC 9110, section 
5.3)
+            sum(len(header) for header in tracestate_headers) + 
len(tracestate_headers) - 1
+            > _TRACECONTEXT_MAXIMUM_TRACESTATE_LENGTH
+        ):
+            _logger.warning(
+                "tracestate header exceeded the maximum length of %d 
characters",
+                _TRACECONTEXT_MAXIMUM_TRACESTATE_LENGTH,
+            )
+            tracestate = None
         else:
             tracestate = TraceState.from_header(tracestate_headers)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_api-1.45.0/src/opentelemetry/trace/span.py 
new/opentelemetry_api-1.45.1/src/opentelemetry/trace/span.py
--- old/opentelemetry_api-1.45.0/src/opentelemetry/trace/span.py        
2020-02-02 01:00:00.000000000 +0100
+++ new/opentelemetry_api-1.45.1/src/opentelemetry/trace/span.py        
2020-02-02 01:00:00.000000000 +0100
@@ -43,8 +43,8 @@
 
 
 _TRACECONTEXT_MAXIMUM_TRACESTATE_KEYS = 32
-_delimiter_pattern = re.compile(r"[ \t]*,[ \t]*")
-_member_pattern = re.compile(f"({_KEY_FORMAT})(=)({_VALUE_FORMAT})[ \t]*")
+_TRACECONTEXT_MAXIMUM_TRACESTATE_LENGTH = 8192
+_member_pattern = re.compile(f"({_KEY_FORMAT})=({_VALUE_FORMAT})")
 _logger = logging.getLogger(__name__)
 
 
@@ -397,8 +397,9 @@
         """
         pairs = {}  # type: dict[str, str]
         for header in header_list:
-            members: list[str] = re.split(_delimiter_pattern, header)
-            for member in members:
+            for member in header.split(","):
+                # remove optional whitespace (RFC 9110, section 5.6.3)
+                member = member.strip(" \t")
                 # empty members are valid, but no need to process further.
                 if not member:
                     continue
@@ -409,8 +410,7 @@
                         member,
                     )
                     return cls()
-                groups: tuple[str, ...] = match.groups()
-                key, _eq, value = groups
+                key, value = match.groups()
                 # duplicate keys are not legal in header
                 if key in pairs:
                     return cls()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_api-1.45.0/src/opentelemetry/util/types.py 
new/opentelemetry_api-1.45.1/src/opentelemetry/util/types.py
--- old/opentelemetry_api-1.45.0/src/opentelemetry/util/types.py        
2020-02-02 01:00:00.000000000 +0100
+++ new/opentelemetry_api-1.45.1/src/opentelemetry/util/types.py        
2020-02-02 01:00:00.000000000 +0100
@@ -2,11 +2,13 @@
 # SPDX-License-Identifier: Apache-2.0
 
 from collections.abc import Mapping, Sequence
+from typing import TypeAlias
 
 # This is the implementation of the "Any" type as specified by the 
specifications of OpenTelemetry data model for logs.
 # For more details, refer to the OTel specification:
 # 
https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#type-any
-AnyValue = AttributeValue = str | bool | int | float | bytes | 
Sequence["AnyValue"] | Mapping[str, "AnyValue"] | None
+AnyValue: TypeAlias = str | bool | int | float | bytes | Sequence["AnyValue"] 
| Mapping[str, "AnyValue"] | None
+AttributeValue: TypeAlias = AnyValue
 Attributes = Mapping[str, AnyValue] | None
 
 # Deprecated type, do not use.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_api-1.45.0/src/opentelemetry/version/__init__.py 
new/opentelemetry_api-1.45.1/src/opentelemetry/version/__init__.py
--- old/opentelemetry_api-1.45.0/src/opentelemetry/version/__init__.py  
2020-02-02 01:00:00.000000000 +0100
+++ new/opentelemetry_api-1.45.1/src/opentelemetry/version/__init__.py  
2020-02-02 01:00:00.000000000 +0100
@@ -1,4 +1,4 @@
 # Copyright The OpenTelemetry Authors
 # SPDX-License-Identifier: Apache-2.0
 
-__version__ = "1.45.0"
+__version__ = "1.45.1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_api-1.45.0/tests/trace/propagation/test_tracecontexthttptextformat.py
 
new/opentelemetry_api-1.45.1/tests/trace/propagation/test_tracecontexthttptextformat.py
--- 
old/opentelemetry_api-1.45.0/tests/trace/propagation/test_tracecontexthttptextformat.py
     2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_api-1.45.1/tests/trace/propagation/test_tracecontexthttptextformat.py
     2020-02-02 01:00:00.000000000 +0100
@@ -180,6 +180,46 @@
         )
         self.assertEqual(span.get_span_context().trace_state["foo"], "1")
 
+    def test_tracestate_header_exceeds_maximum_length(self):
+        """Discard tracestate exceeding the maximum combined length, but keep 
traceparent."""
+        cases = {
+            "single header": ["foo=1" + " " * 8188],
+            "combined headers": ["foo=1" + " " * 4091, "bar=2" + " " * 4091],
+        }
+        for name, tracestate in cases.items():
+            with self.subTest(name):
+                with self.assertLogs(tracecontext.__name__, level="WARNING"):
+                    span = trace.get_current_span(
+                        FORMAT.extract(
+                            {
+                                "traceparent": 
["00-12345678901234567890123456789012-1234567890123456-00"],
+                                "tracestate": tracestate,
+                            },
+                        )
+                    )
+                span_context = span.get_span_context()
+                self.assertEqual(span_context.trace_id, self.TRACE_ID)
+                self.assertEqual(span_context.span_id, self.SPAN_ID)
+                self.assertEqual(len(span_context.trace_state), 0)
+
+    def test_tracestate_header_at_maximum_length(self):
+        """Accept tracestate with a combined length equal to the maximum."""
+        cases = {
+            "single header": ["foo=1" + " " * 8187],
+            "combined headers": ["foo=1" + " " * 4090, "bar=2" + " " * 4091],
+        }
+        for name, tracestate in cases.items():
+            with self.subTest(name):
+                span = trace.get_current_span(
+                    FORMAT.extract(
+                        {
+                            "traceparent": 
["00-12345678901234567890123456789012-1234567890123456-00"],
+                            "tracestate": tracestate,
+                        },
+                    )
+                )
+                self.assertEqual(span.get_span_context().trace_state["foo"], 
"1")
+
     def test_tracestate_keys(self):
         """Test for valid key patterns in the tracestate"""
         tracestate_value = ",".join(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_api-1.45.0/tests/trace/test_tracestate.py 
new/opentelemetry_api-1.45.1/tests/trace/test_tracestate.py
--- old/opentelemetry_api-1.45.0/tests/trace/test_tracestate.py 2020-02-02 
01:00:00.000000000 +0100
+++ new/opentelemetry_api-1.45.1/tests/trace/test_tracestate.py 2020-02-02 
01:00:00.000000000 +0100
@@ -2,6 +2,7 @@
 # SPDX-License-Identifier: Apache-2.0
 # pylint: disable=no-member
 
+import time
 import unittest
 
 from opentelemetry.trace.span import TraceState
@@ -128,3 +129,28 @@
         self.assertIsNone(state.get("bar"))
         with self.assertRaises(KeyError):
             state["bar"]  # pylint:disable=W0104
+
+    def test_tracestate_from_header_optional_whitespace(self):
+        cases = [
+            ("foo=1 , bar=2", {"foo": "1", "bar": "2"}),
+            ("\tfoo=1,\tbar=2\t", {"foo": "1", "bar": "2"}),
+            (" foo=1", {"foo": "1"}),
+            ("foo=1,  ,bar=2", {"foo": "1", "bar": "2"}),
+            ("foo=1,", {"foo": "1"}),
+            ("foo=a b", {"foo": "a b"}),
+        ]
+        for header, expected in cases:
+            with self.subTest(header=header):
+                state = TraceState.from_header([header])
+                self.assertEqual(dict(state), expected)
+
+    def test_tracestate_from_header_long_whitespace_run(self):
+        for whitespace in (" ", "\t"):
+            with self.subTest(whitespace=repr(whitespace)):
+                header = "a=b" + whitespace * 100_000 + "x"
+                start = time.perf_counter()
+                with self.assertLogs(level="WARNING"):
+                    state = TraceState.from_header([header])
+                elapsed = time.perf_counter() - start
+                self.assertEqual(len(state), 0)
+                self.assertLess(elapsed, 1)

Reply via email to