Skip to content

Commit 634ee67

Browse files
committed
fix(image-uris): resolve review-bot issues
ClineProvider.convertToWebviewUri: align JSDoc with non-throwing behavior and fallback to file URI. imageDataUrl.webviewUriToFilePath: remove impossible CDN host check from vscode-resource branch; expand Windows path regex to allow spaces while keeping bounds. ChatTextArea: clear pendingImageUploadsRef via captured ref in cleanup to avoid stale closure.
1 parent 9dc853c commit 634ee67

File tree

3 files changed

+14
-23
lines changed

3 files changed

+14
-23
lines changed

src/core/webview/ClineProvider.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2790,13 +2790,11 @@ export class ClineProvider
27902790
}
27912791

27922792
/**
2793-
* Convert a file path to a webview-accessible URI
2794-
* This method safely converts file paths to URIs that can be loaded in the webview
2793+
* Convert a file path to a webview-accessible URI.
2794+
* Safely returns a string and does not throw; logs errors and falls back to a file: URI when conversion is not possible.
27952795
*
27962796
* @param filePath - The absolute file path to convert
2797-
* @returns The webview URI string, or the original file URI if conversion fails
2798-
* @throws {Error} When webview is not available
2799-
* @throws {TypeError} When file path is invalid
2797+
* @returns The webview URI string when a webview is available; otherwise a file: URI string
28002798
*/
28012799
public convertToWebviewUri(filePath: string): string {
28022800
try {

src/integrations/misc/imageDataUrl.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,7 @@ function webviewUriToFilePath(webviewUri: string): string {
7373

7474
// Handle VS Code webview URIs that contain encoded paths
7575
// Use strict prefix matching to prevent arbitrary host injection
76-
if (
77-
webviewUri.startsWith("vscode-resource://vscode-webview/") &&
78-
(webviewUri.includes("vscode-userdata") || isValidVsCodeCdnHost(webviewUri))
79-
) {
76+
if (webviewUri.startsWith("vscode-resource://vscode-webview/") && webviewUri.includes("vscode-userdata")) {
8077
try {
8178
// Decode safely with length limits
8279
if (webviewUri.length > 2048) {
@@ -94,7 +91,7 @@ function webviewUriToFilePath(webviewUri: string): string {
9491
return unixMatch[0]
9592
}
9693

97-
const windowsMatch = decoded.match(/^[^?#]*C:\\[a-zA-Z0-9._\\-]{1,300}\.(png|jpg|jpeg|gif|webp)$/i)
94+
const windowsMatch = decoded.match(/^[^?#]*[A-Za-z]:\\[^?#]{1,300}\.(png|jpg|jpeg|gif|webp)$/i)
9895
if (windowsMatch) {
9996
return windowsMatch[0]
10097
}
@@ -110,19 +107,6 @@ function webviewUriToFilePath(webviewUri: string): string {
110107
/**
111108
* Gets the MIME type from a file path
112109
*/
113-
/**
114-
* Safely validates if a webview URI is from the trusted vscode-cdn.net host
115-
* Prevents host injection attacks by properly parsing the URL
116-
*/
117-
function isValidVsCodeCdnHost(webviewUri: string): boolean {
118-
try {
119-
const url = new URL(webviewUri)
120-
return url.host === "vscode-cdn.net"
121-
} catch {
122-
// URL parsing failed - not a valid URL
123-
return false
124-
}
125-
}
126110

127111
function getMimeTypeFromPath(filePath: string): string {
128112
const ext = path.extname(filePath).toLowerCase()

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,15 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
652652
// This ensures the frontend never retains image data URLs
653653
const pendingImageUploadsRef = useRef<Set<string>>(new Set())
654654

655+
// Cleanup pending uploads on unmount to prevent leaks
656+
useEffect(() => {
657+
// Capture ref value to avoid stale closure
658+
const uploads = pendingImageUploadsRef.current
659+
return () => {
660+
uploads.clear()
661+
}
662+
}, [])
663+
655664
const handlePaste = useCallback(
656665
async (e: React.ClipboardEvent) => {
657666
const items = e.clipboardData.items

0 commit comments

Comments
 (0)