Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Bug Fix",
"description": "/review: ignored lines should not show up in scan issues"
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { timeoutUtils } from 'aws-core-vscode/shared'
import assert from 'assert'
import sinon from 'sinon'
import * as vscode from 'vscode'
import fs from 'fs' // eslint-disable-line no-restricted-imports
import path from 'path'

const buildRawCodeScanIssue = (params?: Partial<RawCodeScanIssue>): RawCodeScanIssue => ({
filePath: 'workspaceFolder/python3.7-plain-sam-app/hello_world/app.py',
Expand Down Expand Up @@ -65,17 +65,18 @@ const buildMockListCodeScanFindingsResponse = (
nextToken: nextToken ? 'nextToken' : undefined,
})

function getWorkspaceFolder(): string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use something like vscode.workspace.workspaceFolders[0].uri instead ? Aren't we already in the workspace folder?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

return (
vscode.workspace.workspaceFolders?.[0]?.uri.fsPath ??
path.join(__dirname, '../../../../../../core/src/testFixtures/workspaceFolder')
)
}

describe('securityScanHandler', function () {
describe('listScanResults', function () {
let mockClient: Stub<DefaultCodeWhispererClient>
beforeEach(function () {
mockClient = stub(DefaultCodeWhispererClient)
sinon.stub(fs, 'existsSync').returns(true)
sinon.stub(fs, 'statSync').returns({ isFile: () => true } as fs.Stats)
})

afterEach(function () {
sinon.restore()
})

it('should make ListCodeScanFindings request and aggregate findings by file path', async function () {
Expand All @@ -85,14 +86,13 @@ describe('securityScanHandler', function () {
mockClient,
'jobId',
'codeScanFindingsSchema',
['projectPath'],
[getWorkspaceFolder()],
CodeAnalysisScope.PROJECT,
undefined
)

assert.equal(aggregatedCodeScanIssueList.length, 2)
assert.equal(aggregatedCodeScanIssueList.length, 1)
assert.equal(aggregatedCodeScanIssueList[0].issues.length, 1)
assert.equal(aggregatedCodeScanIssueList[1].issues.length, 1)
})

it('should handle ListCodeScanFindings request with paginated response', async function () {
Expand Down Expand Up @@ -123,12 +123,12 @@ describe('securityScanHandler', function () {
mockClient,
'jobId',
'codeScanFindingsSchema',
['projectPath'],
[getWorkspaceFolder()],
CodeAnalysisScope.PROJECT,
undefined
)

assert.equal(aggregatedCodeScanIssueList.length, 2)
assert.equal(aggregatedCodeScanIssueList.length, 1)
assert.equal(aggregatedCodeScanIssueList[0].issues.length, 3)
})

Expand All @@ -145,7 +145,7 @@ describe('securityScanHandler', function () {
mockClient,
'jobId',
'codeScanFindingsSchema',
['projectPath'],
[getWorkspaceFolder()],
scope,
undefined
)
Expand Down
24 changes: 14 additions & 10 deletions packages/core/src/codewhisperer/service/securityScanHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,20 @@ export async function listScanResults(
// Do not use .. in between because there could be multiple project paths in the same parent dir.
const filePath = path.join(projectPath, key.split('/').slice(1).join('/'))
if (existsSync(filePath) && statSync(filePath).isFile()) {
const document = await vscode.workspace.openTextDocument(filePath)
const aggregatedCodeScanIssue: AggregatedCodeScanIssue = {
filePath: filePath,
issues: issues.map((issue) => mapRawToCodeScanIssue(issue, editor, jobId, scope)),
issues: issues.map((issue) => mapRawToCodeScanIssue(issue, document, jobId, scope)),
}
aggregatedCodeScanIssueList.push(aggregatedCodeScanIssue)
}
}
const maybeAbsolutePath = `/${key}`
if (existsSync(maybeAbsolutePath) && statSync(maybeAbsolutePath).isFile()) {
const document = await vscode.workspace.openTextDocument(maybeAbsolutePath)
const aggregatedCodeScanIssue: AggregatedCodeScanIssue = {
filePath: maybeAbsolutePath,
issues: issues.map((issue) => mapRawToCodeScanIssue(issue, editor, jobId, scope)),
issues: issues.map((issue) => mapRawToCodeScanIssue(issue, document, jobId, scope)),
}
aggregatedCodeScanIssueList.push(aggregatedCodeScanIssue)
}
Expand All @@ -103,18 +105,20 @@ export async function listScanResults(

function mapRawToCodeScanIssue(
issue: RawCodeScanIssue,
editor: vscode.TextEditor | undefined,
document: vscode.TextDocument,
jobId: string,
scope: CodeWhispererConstants.CodeAnalysisScope
): CodeScanIssue {
const isIssueTitleIgnored = CodeWhispererSettings.instance.getIgnoredSecurityIssues().includes(issue.title)
const isSingleIssueIgnored =
editor &&
detectCommentAboveLine(editor.document, issue.startLine - 1, CodeWhispererConstants.amazonqIgnoreNextLine)
const language = editor
? runtimeLanguageContext.getLanguageContext(editor.document.languageId, path.extname(editor.document.fileName))
.language
: 'plaintext'
const isSingleIssueIgnored = detectCommentAboveLine(
document,
issue.startLine - 1,
CodeWhispererConstants.amazonqIgnoreNextLine
)
const language = runtimeLanguageContext.getLanguageContext(
document.languageId,
path.extname(document.fileName)
).language
return {
startLine: issue.startLine - 1 >= 0 ? issue.startLine - 1 : 0,
endLine: issue.endLine,
Expand Down
Loading