Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,36 @@ describe('securityIssueHoverProvider', () => {
)
})

it('renders finding text as plain text and only enables its own commands', () => {
const link = '[x](command:workbench.action.terminal.sendSequence?%7B%22text%22%3A%22ls%22%7D)'
const issues = [
createCodeScanIssue({ title: `title ${link}`, suggestedFixes: [{ code: 'code', description: link }] }),
createCodeScanIssue({ title: '<a href="command:workbench.action.reloadWindow">x</a>', suggestedFixes: [] }),
]
issues[1].recommendation.text = link
setupIssues(issues)
const actual = securityIssueHoverProvider.provideHover(mockDocument, new vscode.Position(0, 0), token.token)
assert.strictEqual(actual.contents.length, 2)

for (const content of actual.contents as vscode.MarkdownString[]) {
assert.deepStrictEqual(content.isTrusted, {
enabledCommands: [
'aws.amazonq.explainIssue',
'aws.amazonq.generateFix',
'aws.amazonq.security.ignore',
'aws.amazonq.security.ignoreAll',
],
})
assert.ok(!content.supportHtml)
assert.ok(!content.value.includes('](command:workbench'))
assert.ok(content.value.includes('](command:aws.amazonq.explainIssue?'))
assert.ok(content.value.includes('](command:aws.amazonq.generateFix?'))
assert.ok(content.value.includes('](command:aws.amazonq.security.ignore?'))
assert.ok(content.value.includes('](command:aws.amazonq.security.ignoreAll?'))
}
assert.ok(actual.contents.every((c) => (c as vscode.MarkdownString).value.includes('\\[x\\]\\(command:')))
})

it('should not show issues that are not visible', () => {
setupIssues([createCodeScanIssue({ visible: false })])
const actual = securityIssueHoverProvider.provideHover(mockDocument, new vscode.Position(0, 0), token.token)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { createCodeScanIssue } from 'aws-core-vscode/test'
import assert from 'assert'
import sinon from 'sinon'
import path from 'path'
import * as vscode from 'vscode'

describe('SecurityIssueTreeViewProvider', function () {
let securityIssueTreeViewProvider: SecurityIssueTreeViewProvider
Expand Down Expand Up @@ -174,4 +175,15 @@ describe('IssueItem', function () {
const issueItem = new IssueItem('file/path', createCodeScanIssue({ ruleId: sasRuleId }))
assert.strictEqual(issueItem.contextValue, 'issueWithFixDisabled')
})

it('renders finding text in the tooltip as plain text with no commands enabled', function () {
const link = '[x](command:workbench.action.terminal.sendSequence?%7B%22text%22%3A%22ls%22%7D)'
const issue = createCodeScanIssue({ title: `title ${link}` })
issue.recommendation.text = link
const tooltip = new IssueItem('file/path', issue).tooltip as vscode.MarkdownString
assert.deepStrictEqual(tooltip.isTrusted, { enabledCommands: [] })
assert.ok(!tooltip.supportHtml)
assert.ok(!tooltip.value.includes('](command:'))
assert.ok(tooltip.value.includes('\\[x\\]\\(command:'))
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ import { AuthUtil } from '../util/authUtil'
import { TelemetryHelper } from '../util/telemetryHelper'
import { SecurityIssueProvider } from './securityIssueProvider'

/** The only commands the hover links to; command links to anything else are not run. */
const hoverCommandIds = [
'aws.amazonq.explainIssue',
'aws.amazonq.generateFix',
'aws.amazonq.security.ignore',
'aws.amazonq.security.ignoreAll',
] as const

export class SecurityIssueHoverProvider implements vscode.HoverProvider {
static #instance: SecurityIssueHoverProvider
private issueProvider: SecurityIssueProvider = SecurityIssueProvider.instance
Expand Down Expand Up @@ -66,17 +74,20 @@ export class SecurityIssueHoverProvider implements vscode.HoverProvider {

private _getContent(filePath: string, issue: CodeScanIssue) {
const markdownString = new vscode.MarkdownString()
markdownString.isTrusted = true
markdownString.supportHtml = true
markdownString.isTrusted = { enabledCommands: [...hoverCommandIds] }
markdownString.supportThemeIcons = true
markdownString.baseUri = vscode.Uri.file(path.join(globals.context.extensionPath, 'resources/images/'))

const [suggestedFix] = issue.suggestedFixes

markdownString.appendMarkdown(`## ${issue.title} ${this._makeSeverityBadge(issue.severity)}\n`)
markdownString.appendMarkdown(
`${suggestedFix?.code && suggestedFix.description !== '' ? suggestedFix.description : issue.recommendation.text}\n\n`
// Finding text is appended as plain text so it cannot add links, images or HTML to the hover.
markdownString.appendMarkdown('## ')
markdownString.appendText(issue.title)
markdownString.appendMarkdown(` ${this._makeSeverityBadge(issue.severity)}\n`)
markdownString.appendText(
suggestedFix?.code && suggestedFix.description !== '' ? suggestedFix.description : issue.recommendation.text
)
markdownString.appendMarkdown('\n\n')

const explainWithQCommand = this._getCommandMarkdown(
'aws.amazonq.explainIssue',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,13 @@ export class IssueItem extends vscode.TreeItem {

private getTooltipMarkdown() {
const markdown = new vscode.MarkdownString()
markdown.isTrusted = true
markdown.supportHtml = true
// The tooltip has no command links; finding text is appended as plain text so it cannot add any.
markdown.isTrusted = { enabledCommands: [] }
markdown.supportThemeIcons = true
markdown.appendMarkdown(`## ${this.issue.title} ![${this.issue.severity}](${this.getSeverityImage()})\n`)
markdown.appendMarkdown(this.issue.recommendation.text)
markdown.appendMarkdown('## ')
markdown.appendText(this.issue.title)
markdown.appendMarkdown(` ![${this.issue.severity}](${this.getSeverityImage()})\n`)
markdown.appendText(this.issue.recommendation.text)

return markdown
}
Expand Down
Loading