Skip to content

Commit dd7fa6b

Browse files
antonpirkerarjenzorgdoc
authored andcommitted
Handle also byte arras as strings (getsentry#3101)
In some cases it can happen that the array of redis keys to get can be byte arrays and not string. Make sure we can deal with all kinds of keys, no matter if byte array or string.
1 parent c25b121 commit dd7fa6b

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

sentry_sdk/integrations/redis/utils.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,27 @@ def _get_safe_key(method_name, args, kwargs):
5353
key = ""
5454
if args is not None and method_name.lower() in _MULTI_KEY_COMMANDS:
5555
# for example redis "mget"
56-
key = ", ".join(args)
56+
key = ", ".join(x.decode() if isinstance(x, bytes) else x for x in args)
57+
5758
elif args is not None and len(args) >= 1:
5859
# for example django "set_many/get_many" or redis "get"
59-
key = args[0]
60+
key = args[0].decode() if isinstance(args[0], bytes) else args[0]
61+
6062
elif kwargs is not None and "key" in kwargs:
6163
# this is a legacy case for older versions of django (I guess)
62-
key = kwargs["key"]
64+
key = (
65+
kwargs["key"].decode()
66+
if isinstance(kwargs["key"], bytes)
67+
else kwargs["key"]
68+
)
6369

6470
if isinstance(key, dict):
6571
# Django caching set_many() has a dictionary {"key": "data", "key2": "data2"}
6672
# as argument. In this case only return the keys of the dictionary (to not leak data)
67-
key = ", ".join(key.keys())
73+
key = ", ".join(x.decode() if isinstance(x, bytes) else x for x in key.keys())
6874

6975
if isinstance(key, list):
70-
key = ", ".join(key)
76+
key = ", ".join(x.decode() if isinstance(x, bytes) else x for x in key)
7177

7278
return str(key)
7379

tests/integrations/redis/test_redis_cache_module.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import pytest
2+
13
import fakeredis
24
from fakeredis import FakeStrictRedis
35

46
from sentry_sdk.integrations.redis import RedisIntegration
7+
from sentry_sdk.integrations.redis.utils import _get_safe_key
58
from sentry_sdk.utils import parse_version
69
import sentry_sdk
710

@@ -185,3 +188,22 @@ def test_cache_data(sentry_init, capture_events):
185188
assert spans[4]["data"]["network.peer.address"] == "mycacheserver.io"
186189

187190
assert spans[5]["op"] == "db.redis" # we ignore db spans in this test.
191+
192+
193+
@pytest.mark.parametrize(
194+
"method_name,args,kwargs,expected_key",
195+
[
196+
(None, None, None, ""),
197+
("", None, None, ""),
198+
("set", ["bla", "valuebla"], None, "bla"),
199+
("setex", ["bla", 10, "valuebla"], None, "bla"),
200+
("get", ["bla"], None, "bla"),
201+
("mget", ["bla", "blub", "foo"], None, "bla, blub, foo"),
202+
("set", [b"bla", "valuebla"], None, "bla"),
203+
("setex", [b"bla", 10, "valuebla"], None, "bla"),
204+
("get", [b"bla"], None, "bla"),
205+
("mget", [b"bla", "blub", "foo"], None, "bla, blub, foo"),
206+
],
207+
)
208+
def test_get_safe_key(method_name, args, kwargs, expected_key):
209+
assert _get_safe_key(method_name, args, kwargs) == expected_key

0 commit comments

Comments
 (0)