Skip to content

Commit e919621

Browse files
author
Kapil Borle
committed
Merge pull request #493 from PowerShell/FixAvoidUsernameAndPasswordParamsExtent
Fix extent of AvoidUsernameAndPasswordParams rule
2 parents 050eb7a + 753cd82 commit e919621

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)