Skip to content

Commit a3ced45

Browse files
committed
Add defensive check for data URL prefix in summarizeDataUrl
The summarizeDataUrl function was called from summarizeLargeValue which checks if a string starts with 'data:' before calling it. However, if summarizeDataUrl were ever called from a different context or if the prefix check were removed, the function would incorrectly try to parse non-data-URL strings. Added a defensive check at the start of summarizeDataUrl that returns the value unchanged if it doesn't start with 'data:'. This makes the function safer to use independently and prevents incorrect parsing of malformed inputs. Also added comprehensive test coverage demonstrating: 1. Valid data URLs are properly summarized 2. Non-data-URL strings pass through unchanged 3. Edge case: data URL-like strings without comma are handled gracefully All 3 tests pass.
1 parent 7b65652 commit a3ced45

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { describe, expect, it } from 'bun:test'
2+
3+
import { normalizeProviderRequestBodyForCacheDebug } from '../cache-debug'
4+
5+
describe('cache-debug data URL handling', () => {
6+
it('summarizes valid data URLs', () => {
7+
const result = normalizeProviderRequestBodyForCacheDebug({
8+
provider: 'openai',
9+
body: {
10+
model: 'gpt-4',
11+
messages: [
12+
{
13+
role: 'user',
14+
content: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==',
15+
},
16+
],
17+
},
18+
})
19+
20+
const message = (result as { messages: unknown[] }).messages[0] as {
21+
content: { type: string; mediaType: string; payloadLength: number }
22+
}
23+
expect(message.content.type).toBe('data-url')
24+
expect(message.content.mediaType).toBe('image/png')
25+
expect(message.content.payloadLength).toBeGreaterThan(0)
26+
})
27+
28+
it('passes through non-data-URL strings unchanged', () => {
29+
const result = normalizeProviderRequestBodyForCacheDebug({
30+
provider: 'openai',
31+
body: {
32+
model: 'gpt-4',
33+
messages: [
34+
{
35+
role: 'user',
36+
content: 'https://example.com/image.png',
37+
},
38+
],
39+
},
40+
})
41+
42+
const message = (result as { messages: unknown[] }).messages[0] as {
43+
content: string
44+
}
45+
expect(message.content).toBe('https://example.com/image.png')
46+
})
47+
48+
it('handles data URL-like strings without comma gracefully', () => {
49+
// Edge case: string starts with "data:" but has no comma
50+
const result = normalizeProviderRequestBodyForCacheDebug({
51+
provider: 'openai',
52+
body: {
53+
model: 'gpt-4',
54+
messages: [
55+
{
56+
role: 'user',
57+
content: 'data:image/png;base64',
58+
},
59+
],
60+
},
61+
})
62+
63+
const message = (result as { messages: unknown[] }).messages[0] as {
64+
content: { type: string; mediaType: string; payloadLength: number }
65+
}
66+
expect(message.content.type).toBe('data-url')
67+
expect(message.content.mediaType).toBe('image/png')
68+
expect(message.content.payloadLength).toBe(0)
69+
})
70+
})

‎common/src/util/cache-debug.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ function normalizeForJson(value: unknown): SerializableValue {
4848
}
4949

5050
function summarizeDataUrl(value: string): SerializableValue {
51+
if (!value.startsWith('data:')) {
52+
return value
53+
}
5154
const firstComma = value.indexOf(',')
5255
const header = firstComma >= 0 ? value.slice(0, firstComma) : value
5356
const payload = firstComma >= 0 ? value.slice(firstComma + 1) : ''

0 commit comments

Comments
 (0)