Skip to content

Commit 1611784

Browse files
author
Kapil Borle
authored
Merge pull request #566 from PowerShell/kapilmb/FixRuleSuppressionOffsets
Fix rule suppression bug caused by modified extents
2 parents 0e287f7 + 9cf3d04 commit 1611784

File tree

2 files changed

+84
-4
lines changed

2 files changed

+84
-4
lines changed

Engine/Helper.cs

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,15 +1310,17 @@ public Tuple<List<SuppressedRecord>, List<DiagnosticRecord>> SuppressRule(
13101310
}
13111311

13121312
List<RuleSuppression> ruleSuppressions = ruleSuppressionsDict[ruleName];
1313-
1313+
var offsetArr = GetOffsetArray(diagnostics);
13141314
int recordIndex = 0;
13151315
int startRecord = 0;
13161316
bool[] suppressed = new bool[diagnostics.Count];
1317-
13181317
foreach (RuleSuppression ruleSuppression in ruleSuppressions)
13191318
{
13201319
int suppressionCount = 0;
1321-
while (startRecord < diagnostics.Count && diagnostics[startRecord].Extent.StartOffset < ruleSuppression.StartOffset)
1320+
while (startRecord < diagnostics.Count
1321+
// && diagnostics[startRecord].Extent.StartOffset < ruleSuppression.StartOffset)
1322+
// && diagnostics[startRecord].Extent.StartLineNumber < ruleSuppression.st)
1323+
&& offsetArr[startRecord].Item1 < ruleSuppression.StartOffset)
13221324
{
13231325
startRecord += 1;
13241326
}
@@ -1329,8 +1331,10 @@ public Tuple<List<SuppressedRecord>, List<DiagnosticRecord>> SuppressRule(
13291331
while (recordIndex < diagnostics.Count)
13301332
{
13311333
DiagnosticRecord record = diagnostics[recordIndex];
1334+
var curOffset = offsetArr[recordIndex];
13321335

1333-
if (record.Extent.EndOffset > ruleSuppression.EndOffset)
1336+
//if (record.Extent.EndOffset > ruleSuppression.EndOffset)
1337+
if (curOffset.Item2 > ruleSuppression.EndOffset)
13341338
{
13351339
break;
13361340
}
@@ -1378,6 +1382,57 @@ public Tuple<List<SuppressedRecord>, List<DiagnosticRecord>> SuppressRule(
13781382
return result;
13791383
}
13801384

1385+
private Tuple<int,int>[] GetOffsetArray(List<DiagnosticRecord> diagnostics)
1386+
{
1387+
Func<int,int,Tuple<int,int>> GetTuple = (x, y) => new Tuple<int, int>(x, y);
1388+
Func<Tuple<int, int>> GetDefaultTuple = () => GetTuple(0, 0);
1389+
var offsets = new Tuple<int, int>[diagnostics.Count];
1390+
for (int k = 0; k < diagnostics.Count; k++)
1391+
{
1392+
var ext = diagnostics[k].Extent;
1393+
if (ext.StartOffset == 0 && ext.EndOffset == 0)
1394+
{
1395+
// check if line and column number correspond to 0 offsets
1396+
if (ext.StartLineNumber == 1
1397+
&& ext.StartColumnNumber == 1
1398+
&& ext.EndLineNumber == 1
1399+
&& ext.EndColumnNumber == 1)
1400+
{
1401+
offsets[k] = GetDefaultTuple();
1402+
continue;
1403+
}
1404+
// created using the ScriptExtent constructor, which sets
1405+
// StartOffset and EndOffset to 0
1406+
// find the token the corresponding start line and column number
1407+
var startToken = Tokens.Where(x
1408+
=> x.Extent.StartLineNumber == ext.StartLineNumber
1409+
&& x.Extent.StartColumnNumber == ext.StartColumnNumber)
1410+
.FirstOrDefault();
1411+
if (startToken == null)
1412+
{
1413+
offsets[k] = GetDefaultTuple();
1414+
continue;
1415+
}
1416+
var endToken = Tokens.Where(x
1417+
=> x.Extent.EndLineNumber == ext.EndLineNumber
1418+
&& x.Extent.EndColumnNumber == ext.EndColumnNumber)
1419+
.FirstOrDefault();
1420+
if (endToken == null)
1421+
{
1422+
offsets[k] = GetDefaultTuple();
1423+
continue;
1424+
}
1425+
offsets[k] = GetTuple(startToken.Extent.StartOffset, endToken.Extent.EndOffset);
1426+
}
1427+
else
1428+
{
1429+
// Extent has valid offsets
1430+
offsets[k] = GetTuple(ext.StartOffset, ext.EndOffset);
1431+
}
1432+
}
1433+
return offsets;
1434+
}
1435+
13811436
public static string[] ProcessCustomRulePaths(string[] rulePaths, SessionState sessionState, bool recurse = false)
13821437
{
13831438
//if directory is given, list all the psd1 files

Tests/Engine/RuleSuppression.tests.ps1

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,21 @@ $securePassword = ConvertTo-SecureString $decryptedPassword -AsPlainText -Force
3030
}
3131
'@
3232

33+
# If function doesn't starts at offset 0, then the test case fails before commit b551211
34+
$ruleSuppressionAvoidUsernameAndPassword = @'
35+
36+
function SuppressUserAndPwdRule()
37+
{
38+
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams", "")]
39+
[CmdletBinding()]
40+
param
41+
(
42+
[System.String] $username,
43+
[System.Boolean] $password
44+
)
45+
}
46+
'@
47+
3348
Describe "RuleSuppressionWithoutScope" {
3449
Context "Function" {
3550
It "Does not raise violations" {
@@ -38,6 +53,16 @@ Describe "RuleSuppressionWithoutScope" {
3853
$suppression = $violationsUsingScriptDefinition | Where-Object { $_.RuleName -eq "PSProvideCommentHelp" }
3954
$suppression.Count | Should Be 0
4055
}
56+
57+
It "Suppresses rule with extent created using ScriptExtent constructor" {
58+
Invoke-ScriptAnalyzer `
59+
-ScriptDefinition $ruleSuppressionAvoidUsernameAndPassword `
60+
-IncludeRule "PSAvoidUsingUserNameAndPassWordParams" `
61+
-OutVariable ruleViolations `
62+
-SuppressedOnly
63+
$ruleViolations.Count | Should Be 1
64+
}
65+
4166
}
4267

4368
Context "Script" {

0 commit comments

Comments
 (0)