Skip to content

Commit 753cd82

Browse files
author
Kapil Borle
committed
Fix extent of AvoidUsernamdAndPasswordParams rule
The new extent includes only the region between the username and password parameters rather than the entire function.
1 parent 4600e39 commit 753cd82

File tree

3 files changed

+58
-7
lines changed

3 files changed

+58
-7
lines changed

Rules/AvoidUserNameAndPasswordParams.cs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
5050

5151
// Finds all ParamAsts.
5252
IEnumerable<Ast> paramAsts = funcAst.FindAll(testAst => testAst is ParameterAst, true);
53+
54+
ParameterAst usernameAst = null;
55+
ParameterAst passwordAst = null;
5356
// Iterates all ParamAsts and check if their names are on the list.
5457
foreach (ParameterAst paramAst in paramAsts)
5558
{
@@ -67,7 +70,6 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
6770
|| paramAttribute.TypeName.GetReflectionType() == typeof(System.Security.SecureString));
6871

6972
String paramName = paramAst.Name.VariablePath.ToString();
70-
7173
foreach (String password in passwords)
7274
{
7375
if (paramName.IndexOf(password, StringComparison.OrdinalIgnoreCase) != -1)
@@ -79,6 +81,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
7981
}
8082

8183
hasPwd = true;
84+
passwordAst = paramAst;
8285
break;
8386
}
8487
}
@@ -88,6 +91,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
8891
if (paramName.IndexOf(username, StringComparison.OrdinalIgnoreCase) != -1)
8992
{
9093
hasUserName = true;
94+
usernameAst = paramAst;
9195
break;
9296
}
9397
}
@@ -97,11 +101,49 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
97101
{
98102
yield return new DiagnosticRecord(
99103
String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsernameAndPasswordParamsError, funcAst.Name),
100-
funcAst.Extent, GetName(), DiagnosticSeverity.Error, fileName);
104+
GetExtent(usernameAst, passwordAst, ast), GetName(), DiagnosticSeverity.Error, fileName);
101105
}
102106
}
103107
}
104108

109+
/// <summary>
110+
/// Returns script extent of username and password parameters
111+
/// </summary>
112+
/// <param name="usernameAst"></param>
113+
/// <param name="passwordAst"></param>
114+
/// <returns>IScriptExtent</returns>
115+
private IScriptExtent GetExtent(ParameterAst usernameAst, ParameterAst passwordAst, Ast scriptAst)
116+
{
117+
var usrExt = usernameAst.Extent;
118+
var pwdExt = passwordAst.Extent;
119+
IScriptExtent startExt, endExt;
120+
var usrBeforePwd
121+
= (usrExt.StartLineNumber == pwdExt.StartLineNumber
122+
&& usrExt.StartColumnNumber < pwdExt.StartColumnNumber)
123+
|| usrExt.StartLineNumber < pwdExt.StartLineNumber;
124+
if (usrBeforePwd)
125+
{
126+
startExt = usrExt;
127+
endExt = pwdExt;
128+
}
129+
else
130+
{
131+
startExt = pwdExt;
132+
endExt = usrExt;
133+
}
134+
var startPos = new ScriptPosition(
135+
startExt.File,
136+
startExt.StartLineNumber,
137+
startExt.StartColumnNumber,
138+
startExt.StartScriptPosition.Line);
139+
var endPos = new ScriptPosition(
140+
endExt.File,
141+
endExt.EndLineNumber,
142+
endExt.EndColumnNumber,
143+
endExt.EndScriptPosition.Line);
144+
return new ScriptExtent(startPos, endPos);
145+
}
146+
105147
/// <summary>
106148
/// GetName: Retrieves the name of this rule.
107149
/// </summary>

Tests/Rules/AvoidUserNameAndPasswordParams.ps1

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ function MyFunction3
5353
)
5454
}
5555

56-
function TestFunction($password, [PSCredential[]]$passwords, $username){
56+
function TestFunction1($password, $username, [PSCredential[]]$passwords){
5757
}
5858

59-
59+
function TestFunction2($username, $password, [PSCredential[]]$passwords){
60+
}
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Import-Module PSScriptAnalyzer
22

3-
$violationMessage = "Function 'TestFunction' has both Username and Password parameters. Either set the type of the Password parameter to SecureString or replace the Username and Password parameters with a Credential parameter of type PSCredential. If using a Credential parameter in PowerShell 4.0 or earlier, please define a credential transformation attribute after the PSCredential type attribute."
3+
$violationMessage = "Function 'TestFunction1' has both Username and Password parameters. Either set the type of the Password parameter to SecureString or replace the Username and Password parameters with a Credential parameter of type PSCredential. If using a Credential parameter in PowerShell 4.0 or earlier, please define a credential transformation attribute after the PSCredential type attribute."
44
$violationName = "PSAvoidUsingUserNameAndPasswordParams"
55
$directory = Split-Path -Parent $MyInvocation.MyCommand.Path
66
$violations = Invoke-ScriptAnalyzer $directory\AvoidUserNameAndPasswordParams.ps1 | Where-Object {$_.RuleName -eq $violationName}
@@ -9,17 +9,25 @@ $noViolations = Invoke-ScriptAnalyzer $directory\AvoidUserNameAndPasswordParamsN
99
Describe "AvoidUserNameAndPasswordParams" {
1010
Context "When there are violations" {
1111
It "has 1 avoid username and password parameter violations" {
12-
$violations.Count | Should Be 1
12+
$violations.Count | Should Be 2
1313
}
1414

1515
It "has the correct violation message" {
1616
$violations[0].Message | Should Be $violationMessage
1717
}
18+
19+
It "has correct extent" {
20+
$expectedExtent = '$password, $username'
21+
$violations[0].Extent.Text | Should Be $expectedExtent
22+
23+
$expectedExtent = '$username, $password'
24+
$violations[1].Extent.Text | Should Be $expectedExtent
25+
}
1826
}
1927

2028
Context "When there are no violations" {
2129
It "returns no violations" {
2230
$noViolations.Count | Should Be 0
2331
}
2432
}
25-
}
33+
}

0 commit comments

Comments
 (0)