Skip to content

Commit eb4393d

Browse files
ericapisaniclaude
andcommitted
test(pydantic-ai): Add tests for data URLs with optional parameters
Cover the case where data URLs include optional parameters between the MIME type and base64 encoding, e.g. `data:image/png;name=file.png;base64,...` and `data:text/plain;charset=utf-8;name=hello.txt;base64,...`. These should be matched and redacted by DATA_URL_BASE64_REGEX. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 2f01be8 commit eb4393d

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

sentry_sdk/integrations/pydantic_ai/consts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
# Matches data URLs with base64-encoded content, e.g. "data:image/png;base64,iVBORw0K..."
66
# Group 1: MIME type (e.g. "image/png"), Group 2: base64 data
77
DATA_URL_BASE64_REGEX = re.compile(
8-
r"^data:([a-zA-Z0-9][a-zA-Z0-9.+\-]*/[a-zA-Z0-9][a-zA-Z0-9.+\-]*);base64,([A-Za-z0-9+/\-_]+={0,2})$"
8+
r"^data:([a-zA-Z0-9][a-zA-Z0-9.+\-]*/[a-zA-Z0-9][a-zA-Z0-9.+\-]*)(?:;[a-zA-Z0-9\-]+=[^;,]*)*;base64,([A-Za-z0-9+/\-_]+={0,2})$"
99
)

tests/integrations/pydantic_ai/test_pydantic_ai.py

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2959,7 +2959,6 @@ def test_image_url_http_url_with_base64_data_in_query_param_is_not_redacted_no_m
29592959
def test_image_url_redacts_base64_data_url_with_complex_mime_type(
29602960
sentry_init, capture_events
29612961
):
2962-
"""Test that ImageUrl with a data URL using a complex MIME type (e.g. image/svg+xml) is redacted."""
29632962
sentry_init(
29642963
integrations=[PydanticAIIntegration()],
29652964
traces_sample_rate=1.0,
@@ -2987,6 +2986,68 @@ def test_image_url_redacts_base64_data_url_with_complex_mime_type(
29872986
assert _find_image_content(messages_data, "image/svg+xml")
29882987

29892988

2989+
def test_image_url_redacts_base64_data_url_with_optional_parameters(
2990+
sentry_init, capture_events
2991+
):
2992+
sentry_init(
2993+
integrations=[PydanticAIIntegration()],
2994+
traces_sample_rate=1.0,
2995+
send_default_pii=True,
2996+
)
2997+
2998+
events = capture_events()
2999+
3000+
with sentry_sdk.start_transaction(op="test", name="test"):
3001+
span = sentry_sdk.start_span(op="test_span")
3002+
# Data URL with a charset parameter before the base64 marker
3003+
image_url = ImageUrl(
3004+
url="data:image/png;name=file.png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs"
3005+
)
3006+
user_part = UserPromptPart(content=["Look at this image:", image_url])
3007+
mock_msg = MagicMock()
3008+
mock_msg.parts = [user_part]
3009+
mock_msg.instructions = None
3010+
3011+
_set_input_messages(span, [mock_msg])
3012+
span.finish()
3013+
3014+
(event,) = events
3015+
span_data = event["spans"][0]["data"]
3016+
messages_data = _get_messages_from_span(span_data)
3017+
assert _find_image_content(messages_data, "image/png")
3018+
3019+
3020+
def test_image_url_redacts_base64_data_url_with_multiple_optional_parameters(
3021+
sentry_init, capture_events
3022+
):
3023+
sentry_init(
3024+
integrations=[PydanticAIIntegration()],
3025+
traces_sample_rate=1.0,
3026+
send_default_pii=True,
3027+
)
3028+
3029+
events = capture_events()
3030+
3031+
with sentry_sdk.start_transaction(op="test", name="test"):
3032+
span = sentry_sdk.start_span(op="test_span")
3033+
# Data URL with multiple parameters before the base64 marker
3034+
image_url = ImageUrl(
3035+
url="data:text/plain;charset=utf-8;name=hello.txt;base64,SGVsbG8sIFdvcmxkIQ=="
3036+
)
3037+
user_part = UserPromptPart(content=["Look at this text:", image_url])
3038+
mock_msg = MagicMock()
3039+
mock_msg.parts = [user_part]
3040+
mock_msg.instructions = None
3041+
3042+
_set_input_messages(span, [mock_msg])
3043+
span.finish()
3044+
3045+
(event,) = events
3046+
span_data = event["spans"][0]["data"]
3047+
messages_data = _get_messages_from_span(span_data)
3048+
assert _find_image_content(messages_data, "text/plain")
3049+
3050+
29903051
@pytest.mark.asyncio
29913052
async def test_invoke_agent_image_url_http_url_no_redaction(
29923053
sentry_init, capture_events

0 commit comments

Comments
 (0)