Skip to content

Commit 67a2abd

Browse files
pranaysblzchenemdnetoherin049xrmx
authored
Fix Context in-place mutability bypass via inherited dict methods (open-telemetry#5399)
* opentelemetry-api: Fix Context in-place mutability bypass via inherited dict methods * Rename context-immutability.fixed to 5399.fixed --------- Co-authored-by: Leighton Chen <lechen@microsoft.com> Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Lukas Hering <40302054+herin049@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti <riccardo.magliocchetti@gmail.com>
1 parent 87baad9 commit 67a2abd

3 files changed

Lines changed: 38 additions & 2 deletions

File tree

.changelog/5399.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
`opentelemetry-api`: Prevent in-place mutation of `Context` via inherited `dict` methods

opentelemetry-api/src/opentelemetry/context/context.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,27 @@ class Context(dict[str, object]):
1111
def __setitem__(self, key: str, value: object) -> None:
1212
raise ValueError
1313

14+
def __delitem__(self, key: str) -> None:
15+
raise ValueError
16+
17+
def setdefault(self, key: str, default: object = None) -> object:
18+
raise ValueError
19+
20+
def pop(self, key: str, *args: object) -> object:
21+
raise ValueError
22+
23+
def popitem(self) -> tuple[str, object]:
24+
raise ValueError
25+
26+
def clear(self) -> None:
27+
raise ValueError
28+
29+
def update(self, *args: object, **kwargs: object) -> None:
30+
raise ValueError
31+
32+
def __ior__(self, other: object) -> Context:
33+
raise ValueError
34+
1435

1536
class _RuntimeContext(ABC):
1637
"""The RuntimeContext interface provides a wrapper for the different

opentelemetry-api/tests/context/test_context.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,23 @@ def test_set_value(self):
5454
self.assertEqual(None, context.get_value("a"))
5555

5656
def test_context_is_immutable(self):
57+
ctx = context.get_current()
5758
with self.assertRaises(ValueError):
58-
# ensure a context
59-
context.get_current()["test"] = "cant-change-immutable"
59+
ctx["test"] = "cant-change-immutable"
60+
with self.assertRaises(ValueError):
61+
del ctx["test"]
62+
with self.assertRaises(ValueError):
63+
ctx.pop("test")
64+
with self.assertRaises(ValueError):
65+
ctx.popitem()
66+
with self.assertRaises(ValueError):
67+
ctx.clear()
68+
with self.assertRaises(ValueError):
69+
ctx.update({"test": "cant-change-immutable"})
70+
with self.assertRaises(ValueError):
71+
ctx.setdefault("test", "cant-change-immutable")
72+
with self.assertRaises(ValueError):
73+
ctx |= {"test": "cant-change-immutable"}
6074

6175
def test_set_current(self):
6276
context.attach(context.set_value("a", "yyy"))

0 commit comments

Comments
 (0)