Add ability to open the query file

This makes it possible to open the query file in the editor when
clicking on the query filename.

This is a slightly different implementation from the remote queries
implementation. The remote queries implementation will send the file
path to open to the extension host, and the extension host will simply
open the given file path. If someone is able to inject JavaScript into
the webview, this would allow them to open an arbitrary file in VSCode.

By moving the file path logic to the extension host, we can ensure that
we only allow opening the actual query file.
This commit is contained in:
Koen Vlaswinkel
2022-10-12 13:46:37 +02:00
parent 2ae95144a5
commit a69ec03c6e
3 changed files with 33 additions and 3 deletions

View File

@@ -464,6 +464,10 @@ export interface RequestRepositoryResultsMessage {
repositoryFullName: string;
}
export interface OpenQueryFileMessage {
t: 'openQueryFile';
}
export type ToVariantAnalysisMessage =
| SetVariantAnalysisMessage
| SetRepoResultsMessage
@@ -472,4 +476,5 @@ export type ToVariantAnalysisMessage =
export type FromVariantAnalysisMessage =
| ViewLoadedMsg
| StopVariantAnalysisMessage
| RequestRepositoryResultsMessage;
| RequestRepositoryResultsMessage
| OpenQueryFileMessage;

View File

@@ -1,4 +1,4 @@
import { commands, ExtensionContext, ViewColumn } from 'vscode';
import { commands, ExtensionContext, ViewColumn, window as Window, workspace } from 'vscode';
import { AbstractWebview, WebviewPanelConfig } from '../abstract-webview';
import { logger } from '../logging';
import { FromVariantAnalysisMessage, ToVariantAnalysisMessage } from '../pure/interface-types';
@@ -89,6 +89,9 @@ export class VariantAnalysisView extends AbstractWebview<ToVariantAnalysisMessag
case 'requestRepositoryResults':
void commands.executeCommand('codeQL.loadVariantAnalysisRepoResults', this.variantAnalysisId, msg.repositoryFullName);
break;
case 'openQueryFile':
await this.openQueryFile();
break;
default:
assertNever(msg);
}
@@ -111,4 +114,20 @@ export class VariantAnalysisView extends AbstractWebview<ToVariantAnalysisMessag
variantAnalysis,
});
}
private async openQueryFile(): Promise<void> {
const variantAnalysis = await this.manager.getVariantAnalysis(this.variantAnalysisId);
if (!variantAnalysis) {
void showAndLogWarningMessage('Could not open variant analysis query file');
return;
}
try {
const textDocument = await workspace.openTextDocument(variantAnalysis.query.filePath);
await Window.showTextDocument(textDocument, ViewColumn.One);
} catch (error) {
void showAndLogWarningMessage(`Could not open file: ${variantAnalysis.query.filePath}`);
}
}
}

View File

@@ -18,6 +18,12 @@ type Props = {
repoResults?: VariantAnalysisScannedRepositoryResult[];
}
const openQueryFile = () => {
vscode.postMessage({
t: 'openQueryFile',
});
};
export function VariantAnalysis({
variantAnalysis: initialVariantAnalysis,
repoStates: initialRepoStates = [],
@@ -68,7 +74,7 @@ export function VariantAnalysis({
<>
<VariantAnalysisHeader
variantAnalysis={variantAnalysis}
onOpenQueryFileClick={() => console.log('Open query')}
onOpenQueryFileClick={openQueryFile}
onViewQueryTextClick={() => console.log('View query')}
onStopQueryClick={() => console.log('Stop query')}
onCopyRepositoryListClick={() => console.log('Copy repository list')}