Allow previews to open readable files (#1214)

* Allow previews to open readable files

* Fix Windows file preview path test

* Address file preview review comments
This commit is contained in:
Mohamed Boudra
2026-05-29 11:35:38 +08:00
committed by GitHub
parent 2e1b907c63
commit 3585c80266
11 changed files with 361 additions and 132 deletions
+19 -20
View File
@@ -233,10 +233,7 @@ export function parseFileProtocolUrl(value: string): InlinePathTarget | null {
};
}
function parseAssistantInlinePathLink(
value: string,
options: AssistantHrefParseOptions,
): InlinePathTarget | null {
function parseAssistantInlinePathLink(value: string): InlinePathTarget | null {
const inlinePathTarget = parseInlinePathToken(value);
if (!inlinePathTarget) {
return null;
@@ -247,10 +244,6 @@ function parseAssistantInlinePathLink(
return null;
}
if (!isAllowedAbsolutePath(normalizedPath, options.workspaceRoot)) {
return null;
}
return {
...inlinePathTarget,
path: normalizedPath,
@@ -314,9 +307,7 @@ export function parseAssistantFileLink(
return null;
}
const inlinePathTarget = parseAssistantInlinePathLink(trimmed, {
workspaceRoot: options.workspaceRoot,
});
const inlinePathTarget = parseAssistantInlinePathLink(trimmed);
if (inlinePathTarget) {
return inlinePathTarget;
}
@@ -324,7 +315,7 @@ export function parseAssistantFileLink(
const windowsPathMatch = trimmed.match(/^([A-Za-z]:[\\/][^?#]*)(#[^?]+)?$/);
if (windowsPathMatch) {
const normalizedPath = normalizePathToken(windowsPathMatch[1] ?? "");
if (!normalizedPath || !isAllowedAbsolutePath(normalizedPath, options.workspaceRoot)) {
if (!normalizedPath) {
return null;
}
@@ -363,10 +354,6 @@ export function parseAssistantFileLink(
return null;
}
if (!isAllowedAbsolutePath(normalizedPath, options.workspaceRoot)) {
return null;
}
const lines = parseLineFragment(parsedUrl.hash);
if (!lines) {
return null;
@@ -402,13 +389,21 @@ function parseWorkspaceRelativeFileLink(
value: string,
options: AssistantHrefParseOptions,
): InlinePathTarget | null {
const workspaceRoot = normalizePathInput(options.workspaceRoot);
if (!workspaceRoot) {
const parsed = parseLocalPathParts(value);
if (!parsed || isAbsolutePath(parsed.path)) {
return null;
}
const parsed = parseLocalPathParts(value);
if (!parsed || isAbsolutePath(parsed.path)) {
if (isHomeRelativePath(parsed.path)) {
return {
raw: value,
path: parsed.path,
...parsed.lines,
};
}
const workspaceRoot = normalizePathInput(options.workspaceRoot);
if (!workspaceRoot) {
return null;
}
@@ -529,6 +524,10 @@ function isAllowedAbsolutePath(pathValue: string, workspaceRoot?: string): boole
return comparePath === compareWorkspaceRoot || comparePath.startsWith(comparePrefix);
}
function isHomeRelativePath(pathValue: string): boolean {
return pathValue === "~" || pathValue.startsWith("~/") || pathValue.startsWith("~\\");
}
function isExternalHref(value: string): boolean {
if (value.includes("://")) {
return !value.toLowerCase().startsWith(`${FILE_PROTOCOL}//`);