Skip to content

Commit c445cfe

Browse files
committed
fix(images): remove legacy file:// URI support and use centralized image utils
- Remove file:// URI handling from webviewUriToFilePath (legacy support no longer needed) - Update tests to reflect modern CDN-style URIs only - Use MAX_IMAGE_BYTES and estimateBytesFromBase64DataUrl from webview-ui/src/utils/image.ts in ChatTextArea for consistent 10MB enforcement Fixes knip unused export error and test failure
1 parent 09d512b commit c445cfe

File tree

2 files changed

+11
-51
lines changed

2 files changed

+11
-51
lines changed

src/integrations/misc/__tests__/imageDataUrl.spec.ts

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,40 +18,13 @@ describe("normalizeImageRefsToDataUrls", () => {
1818
expect(result).toEqual([dataUrl])
1919
})
2020

21-
it("should convert webview URIs to data URLs", async () => {
22-
const webviewUri = "file:///path/to/test.png"
23-
const mockBuffer = Buffer.from("test image data")
24-
25-
vi.mocked(fs.readFile).mockResolvedValue(mockBuffer)
26-
27-
const result = await normalizeImageRefsToDataUrls([webviewUri])
28-
29-
expect(result).toHaveLength(1)
30-
expect(result[0]).toMatch(/^data:image\/png;base64,/)
31-
expect(fs.readFile).toHaveBeenCalledWith("/path/to/test.png")
32-
})
33-
34-
it("should handle mixed arrays of data URLs and webview URIs", async () => {
35-
const dataUrl = "data:image/jpeg;base64,test123"
36-
const webviewUri = "file:///path/to/test.png"
37-
const mockBuffer = Buffer.from("test image data")
38-
39-
vi.mocked(fs.readFile).mockResolvedValue(mockBuffer)
40-
41-
const result = await normalizeImageRefsToDataUrls([dataUrl, webviewUri])
42-
43-
expect(result).toHaveLength(2)
44-
expect(result[0]).toBe(dataUrl) // Data URL unchanged
45-
expect(result[1]).toMatch(/^data:image\/png;base64,/) // Webview URI converted
46-
})
47-
4821
it("should handle errors gracefully by skipping problematic images", async () => {
4922
const validDataUrl = "data:image/png;base64,valid"
50-
const invalidWebviewUri = "file:///nonexistent/test.png"
23+
const invalidCdnUri = "vscode-file://vscode-app/nonexistent/test.png"
5124

5225
vi.mocked(fs.readFile).mockRejectedValue(new Error("File not found"))
5326

54-
const result = await normalizeImageRefsToDataUrls([validDataUrl, invalidWebviewUri])
27+
const result = await normalizeImageRefsToDataUrls([validDataUrl, invalidCdnUri])
5528

5629
expect(result).toEqual([validDataUrl]) // Only valid ones returned
5730
})

webview-ui/src/components/chat/ChatTextArea.tsx

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { ExtensionMessage } from "@roo/ExtensionMessage"
1111
import { vscode } from "@src/utils/vscode"
1212
import { useExtensionState } from "@src/context/ExtensionStateContext"
1313
import { useAppTranslation } from "@src/i18n/TranslationContext"
14+
import { MAX_IMAGE_BYTES, estimateBytesFromBase64DataUrl } from "@src/utils/image"
1415
import {
1516
ContextMenuOptionType,
1617
getContextMenuOptions,
@@ -732,18 +733,11 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
732733
if (dataUrls.length > 0) {
733734
// Process each image: enforce 10MB limit and send to backend to save as temp file
734735
for (const dataUrl of dataUrls) {
735-
// Approximate bytes from base64 (ignore header and padding)
736-
const commaIdx = dataUrl.indexOf(",")
737-
let tooLarge = false
738-
if (commaIdx !== -1) {
739-
const base64 = dataUrl.slice(commaIdx + 1).replace(/=+$/, "")
740-
const approxBytes = Math.floor((base64.length * 3) / 4)
741-
if (approxBytes > 10 * 1024 * 1024) {
742-
console.warn("Pasted image exceeds 10MB; skipping")
743-
tooLarge = true
744-
}
736+
const approxBytes = estimateBytesFromBase64DataUrl(dataUrl)
737+
if (approxBytes > MAX_IMAGE_BYTES) {
738+
console.warn("Pasted image exceeds 10MB; skipping")
739+
continue
745740
}
746-
if (tooLarge) continue
747741

748742
const requestId = Math.random().toString(36).substring(2, 9)
749743

@@ -910,18 +904,11 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
910904
if (dataUrls.length > 0) {
911905
// Process each dropped image: enforce 10MB limit and send to backend to save as temp file
912906
for (const dataUrl of dataUrls) {
913-
// Approximate bytes from base64 (ignore header and padding)
914-
const commaIdx = dataUrl.indexOf(",")
915-
let tooLarge = false
916-
if (commaIdx !== -1) {
917-
const base64 = dataUrl.slice(commaIdx + 1).replace(/=+$/, "")
918-
const approxBytes = Math.floor((base64.length * 3) / 4)
919-
if (approxBytes > 10 * 1024 * 1024) {
920-
console.warn("Dropped image exceeds 10MB; skipping")
921-
tooLarge = true
922-
}
907+
const approxBytes = estimateBytesFromBase64DataUrl(dataUrl)
908+
if (approxBytes > MAX_IMAGE_BYTES) {
909+
console.warn("Dropped image exceeds 10MB; skipping")
910+
continue
923911
}
924-
if (tooLarge) continue
925912

926913
const requestId = Math.random().toString(36).substring(2, 9)
927914

0 commit comments

Comments
 (0)