Repository: open-telemetry/opentelemetry-python

Issue:
Skipped Baggage entries in propagation still count against max entries
The decrement operation should be moved after the last continue block if the over-long entry is truly skipped, otherwise this behavior should probably be documented/tested for.

https://github.com/open-telemetry/opentelemetry-python/blob/4250078e43ddb24c88e19270c7af01ae63336fb9/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py#L57-L65


Discussion:

Resolving patch:
diff --git a/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py b/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py
--- a/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py
+++ b/opentelemetry-api/src/opentelemetry/baggage/propagation/__init__.py
@@ -54,9 +54,6 @@ def extract(
         baggage_entries = header.split(",")
         total_baggage_entries = self._MAX_PAIRS
         for entry in baggage_entries:
-            if total_baggage_entries <= 0:
-                return context
-            total_baggage_entries -= 1
             if len(entry) > self._MAX_PAIR_LENGTH:
                 continue
             try:
@@ -68,6 +65,9 @@ def extract(
                 unquote_plus(value).strip(),
                 context=context,
             )
+            total_baggage_entries -= 1
+            if total_baggage_entries == 0:
+                break
 
         return context
 


Test patch:
diff --git a/opentelemetry-api/tests/baggage/test_baggage_propagation.py b/opentelemetry-api/tests/baggage/test_baggage_propagation.py
--- a/opentelemetry-api/tests/baggage/test_baggage_propagation.py
+++ b/opentelemetry-api/tests/baggage/test_baggage_propagation.py
@@ -118,6 +118,46 @@ def test_extract_unquote_plus(self):
             {"key/key": "value/value"},
         )
 
+    def test_header_max_entries_skip_invalid_entry(self):
+
+        self.assertEqual(
+            self._extract(
+                ",".join(
+                    [
+                        f"key{index}=value{index}"
+                        if index != 2
+                        else (
+                            f"key{index}="
+                            f"value{'s' * (W3CBaggagePropagator._MAX_PAIR_LENGTH + 1)}"
+                        )
+                        for index in range(W3CBaggagePropagator._MAX_PAIRS + 1)
+                    ]
+                )
+            ),
+            {
+                f"key{index}": f"value{index}"
+                for index in range(W3CBaggagePropagator._MAX_PAIRS + 1)
+                if index != 2
+            },
+        )
+        self.assertEqual(
+            self._extract(
+                ",".join(
+                    [
+                        f"key{index}=value{index}"
+                        if index != 2
+                        else f"key{index}xvalue{index}"
+                        for index in range(W3CBaggagePropagator._MAX_PAIRS + 1)
+                    ]
+                )
+            ),
+            {
+                f"key{index}": f"value{index}"
+                for index in range(W3CBaggagePropagator._MAX_PAIRS + 1)
+                if index != 2
+            },
+        )
+
     def test_inject_no_baggage_entries(self):
         values = {}
         output = self._inject(values)