diff --git a/CHANGELOG.MD b/CHANGELOG.MD index df79caa88..968541a7d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -499,7 +499,7 @@ Many thanks to @rkeithhill for contributing the _Stroustrup_ style code formatti ## [1.11.1](https://github.com/PowerShell/PSScriptAnalyzer/tree/1.11.1) - 2017-04-04 ### Fixed - CodeFormatting settings file (#727, #728). -- Whitelisted aliases comparison in AvoidUsingCmdletAliases rule (#739). +- Allowlist aliases comparison in AvoidUsingCmdletAliases rule (#739). - PlaceCloseBrace rule behavior for NewLineAfter option (#741). - UseConsistentIndentation rule to ignore open brace in magic methods (#744). @@ -596,7 +596,7 @@ Here are some improvements since the last release. - Fix `SaveDscDependency` switch implementation, which use fail if more than one parameter is given to `Import-DSCResource` dynamic keyword. - Add support for external AST based rule suppression - Fix rule suppression caused by inavlid offsets -- Whitelist `Data` in `PSUseSingularNoun` rule +- Allowlist `Data` in `PSUseSingularNoun` rule - Fix rule documentation of `PSDSCExamplesPresent` - Fix false positives caused by PSD1 files which are not module manifests - affects `PSUseToExportFieldsInManifest`, `PSMissingModuleManifestField` and `PSAvoidUsingDeprecatedManifestFields` rules diff --git a/RuleDocumentation/AvoidOverwritingBuiltInCmdlets.md b/RuleDocumentation/AvoidOverwritingBuiltInCmdlets.md index 03d6d1ca7..1a4610eb7 100644 --- a/RuleDocumentation/AvoidOverwritingBuiltInCmdlets.md +++ b/RuleDocumentation/AvoidOverwritingBuiltInCmdlets.md @@ -4,7 +4,7 @@ ## Description -This rule flags cmdlets that are available in a given edition/version of PowerShell on a given operating system which are overwritten by a function declaration. It works by comparing function declarations against a set of whitelists which ship with PSScriptAnalyzer. These whitelist files are used by other PSScriptAnalyzer rules. More information can be found in the documentation for the [UseCompatibleCmdlets](./UseCompatibleCmdlets.md) rule. +This rule flags cmdlets that are available in a given edition/version of PowerShell on a given operating system which are overwritten by a function declaration. It works by comparing function declarations against a set of allowlists which ship with PSScriptAnalyzer. These allowlist files are used by other PSScriptAnalyzer rules. More information can be found in the documentation for the [UseCompatibleCmdlets](./UseCompatibleCmdlets.md) rule. ## Configuration @@ -25,7 +25,7 @@ To enable the rule to check if your script is compatible on PowerShell Core on W #### PowerShellVersion -The parameter `PowerShellVersion` is a list of whitelists that ship with PSScriptAnalyzer. +The parameter `PowerShellVersion` is a list of allowlists that ship with PSScriptAnalyzer. **Note**: The default value for `PowerShellVersion` is `"core-6.1.0-windows"` if PowerShell 6 or later is installed, and `"desktop-5.1.14393.206-windows"` if it is not. diff --git a/RuleDocumentation/AvoidUsingCmdletAliases.md b/RuleDocumentation/AvoidUsingCmdletAliases.md index 39d7437d0..230772a22 100644 --- a/RuleDocumentation/AvoidUsingCmdletAliases.md +++ b/RuleDocumentation/AvoidUsingCmdletAliases.md @@ -18,9 +18,9 @@ The use of full command names also allows for syntax highlighting in sites and a Use the full cmdlet name and not an alias. -## Alias Whitelist +## Alias Allowlist -To prevent `PSScriptAnalyzer` from flagging your preferred aliases, create a whitelist of the aliases in your settings file and point `PSScriptAnalyzer` to use the settings file. For example, to disable `PSScriptAnalyzer` from flagging `cd`, which is an alias of `Set-Location`, set the settings file content to the following. +To prevent `PSScriptAnalyzer` from flagging your preferred aliases, create an allowlist of the aliases in your settings file and point `PSScriptAnalyzer` to use the settings file. For example, to disable `PSScriptAnalyzer` from flagging `cd`, which is an alias of `Set-Location`, set the settings file content to the following. ```PowerShell # PSScriptAnalyzerSettings.psd1 diff --git a/RuleDocumentation/UseCompatibleCmdlets.md b/RuleDocumentation/UseCompatibleCmdlets.md index 5eb25198e..75cae8e67 100644 --- a/RuleDocumentation/UseCompatibleCmdlets.md +++ b/RuleDocumentation/UseCompatibleCmdlets.md @@ -4,7 +4,7 @@ ## Description -This rule flags cmdlets that are not available in a given Edition/Version of PowerShell on a given Operating System. It works by comparing a cmdlet against a set of whitelists which ship with PSScriptAnalyzer. They can be found at `/path/to/PSScriptAnalyzerModule/Settings`. These files are of the form, `PSEDITION-PSVERSION-OS.json` where `PSEDITION` can be either `Core` or `Desktop`, `OS` can be either `Windows`, `Linux` or `MacOS`, and `Version` is the PowerShell version. To enable the rule to check if your script is compatible on PowerShell Core on windows, put the following your settings file: +This rule flags cmdlets that are not available in a given Edition/Version of PowerShell on a given Operating System. It works by comparing a cmdlet against a set of allowlists which ship with PSScriptAnalyzer. They can be found at `/path/to/PSScriptAnalyzerModule/Settings`. These files are of the form, `PSEDITION-PSVERSION-OS.json` where `PSEDITION` can be either `Core` or `Desktop`, `OS` can be either `Windows`, `Linux` or `MacOS`, and `Version` is the PowerShell version. To enable the rule to check if your script is compatible on PowerShell Core on windows, put the following your settings file: ```PowerShell @{ diff --git a/Rules/AvoidAlias.cs b/Rules/AvoidAlias.cs index c30de8db2..232a01817 100644 --- a/Rules/AvoidAlias.cs +++ b/Rules/AvoidAlias.cs @@ -22,13 +22,11 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules #endif public class AvoidAlias : IScriptRule { - private readonly string whiteListArgName = "whitelist"; + private readonly string allowListArgName = "allowlist"; + // keep legacy argument name for next version to allow customers to transition but remove later + private readonly string allowListLegacyArgName = "whitelist"; private bool isPropertiesSet; - private List whiteList; - public List WhiteList - { - get { return whiteList; } - } + public List AllowList { get; private set; } public AvoidAlias() { @@ -38,22 +36,27 @@ public AvoidAlias() /// /// Configure the rule. /// - /// Sets the whitelist of this rule + /// Sets the allowlist of this rule /// private void SetProperties() { - whiteList = new List(); + AllowList = new List(); isPropertiesSet = true; Dictionary ruleArgs = Helper.Instance.GetRuleArguments(GetName()); if (ruleArgs == null) { return; } - object obj; - if (!ruleArgs.TryGetValue(whiteListArgName, out obj)) + object objLegacy = null; + if (!ruleArgs.TryGetValue(allowListArgName, out object obj) && + !ruleArgs.TryGetValue(allowListLegacyArgName, out objLegacy)) { return; } + // Fallback for object from legacy allowlist argument name + if (obj == null) { + obj = objLegacy; + } IEnumerable aliases = obj as IEnumerable; if (aliases == null) { @@ -72,13 +75,13 @@ private void SetProperties() } else { - whiteList.Add(y); + AllowList.Add(y); } } } else { - whiteList.AddRange(aliases); + AllowList.AddRange(aliases); } } @@ -110,7 +113,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) // You can also review the remark section in following document, // MSDN: CommandAst.GetCommandName Method if (commandName == null - || whiteList.Contains(commandName, StringComparer.OrdinalIgnoreCase)) + || AllowList.Contains(commandName, StringComparer.OrdinalIgnoreCase)) { continue; } diff --git a/Rules/AvoidUserNameAndPasswordParams.cs b/Rules/AvoidUserNameAndPasswordParams.cs index 9429e2aa4..0609505fd 100644 --- a/Rules/AvoidUserNameAndPasswordParams.cs +++ b/Rules/AvoidUserNameAndPasswordParams.cs @@ -36,7 +36,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) List passwords = new List() {"Password", "Passphrase"}; List usernames = new List() { "Username", "User"}; - Type[] typeWhiteList = {typeof(CredentialAttribute), + Type[] typeAllowList = {typeof(CredentialAttribute), typeof(PSCredential), typeof(System.Security.SecureString), typeof(SwitchParameter), @@ -54,7 +54,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) // Iterates all ParamAsts and check if their names are on the list. foreach (ParameterAst paramAst in paramAsts) { - var attributes = typeWhiteList.Select(x => GetAttributeOfType(paramAst.Attributes, x)); + var attributes = typeAllowList.Select(x => GetAttributeOfType(paramAst.Attributes, x)); String paramName = paramAst.Name.VariablePath.ToString(); foreach (String password in passwords) { diff --git a/Rules/ProvideCommentHelp.cs b/Rules/ProvideCommentHelp.cs index 63e8d6438..3a46f0ada 100644 --- a/Rules/ProvideCommentHelp.cs +++ b/Rules/ProvideCommentHelp.cs @@ -264,13 +264,13 @@ private void GetCorrectionPosition( private class ViolationFinder : AstVisitor { - private HashSet functionWhitelist; + private HashSet functionAllowList; private List functionDefinitionAsts; - private bool useFunctionWhitelist; + private bool useFunctionAllowList; public ViolationFinder() { - functionWhitelist = new HashSet(); + functionAllowList = new HashSet(); functionDefinitionAsts = new List(); } @@ -281,12 +281,12 @@ public ViolationFinder(HashSet exportedFunctions) : this() throw new ArgumentNullException(nameof(exportedFunctions)); } - this.functionWhitelist = exportedFunctions; + this.functionAllowList = exportedFunctions; } public ViolationFinder(HashSet exportedFunctions, bool exportedOnly) : this(exportedFunctions) { - this.useFunctionWhitelist = exportedOnly; + this.useFunctionAllowList = exportedOnly; } public IEnumerable FunctionDefinitionAsts @@ -299,7 +299,7 @@ public IEnumerable FunctionDefinitionAsts public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst funcAst) { - if ((!useFunctionWhitelist || functionWhitelist.Contains(funcAst.Name)) + if ((!useFunctionAllowList || functionAllowList.Contains(funcAst.Name)) && funcAst.GetHelpContent() == null) { functionDefinitionAsts.Add(funcAst); diff --git a/Rules/UseCompatibleCmdlets.cs b/Rules/UseCompatibleCmdlets.cs index ffa2e40ee..c74665e95 100644 --- a/Rules/UseCompatibleCmdlets.cs +++ b/Rules/UseCompatibleCmdlets.cs @@ -498,7 +498,7 @@ private bool RuleParamsValid(Dictionary ruleArgs) } /// - /// Check if current command is present in the whitelists + /// Check if current command is present in the allowlists /// If not, flag the corresponding value in curCmdletCompatibilityMap /// private void CheckCompatibility() diff --git a/Rules/UseConsistentWhitespace.cs b/Rules/UseConsistentWhitespace.cs index aad4d3f46..364e94495 100644 --- a/Rules/UseConsistentWhitespace.cs +++ b/Rules/UseConsistentWhitespace.cs @@ -26,7 +26,7 @@ private enum ErrorKind { BeforeOpeningBrace, Paren, Operator, SeparatorComma, Se AfterOpeningBrace, BeforeClosingBrace, BeforePipe, AfterPipe, BetweenParameter }; private const int whiteSpaceSize = 1; private const string whiteSpace = " "; - private readonly SortedSet openParenKeywordWhitelist = new SortedSet() + private readonly SortedSet openParenKeywordAllowList = new SortedSet() { TokenKind.If, TokenKind.ElseIf, @@ -474,7 +474,7 @@ private DiagnosticRecord getDiagnosticRecord( private bool IsKeyword(Token token) { - return openParenKeywordWhitelist.Contains(token.Kind); + return openParenKeywordAllowList.Contains(token.Kind); } private static bool IsPreviousTokenApartByWhitespace(LinkedListNode tokenNode) diff --git a/Rules/UseSingularNouns.cs b/Rules/UseSingularNouns.cs index 9f64cc46c..2a6fdd9d5 100644 --- a/Rules/UseSingularNouns.cs +++ b/Rules/UseSingularNouns.cs @@ -28,7 +28,7 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules [Export(typeof(IScriptRule))] public class CmdletSingularNoun : IScriptRule { - private readonly string[] nounWhiteList = + private readonly string[] nounAllowList = { "Data" }; @@ -68,7 +68,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) { if (!ps.IsSingular(noun) && ps.IsPlural(noun)) { IScriptExtent extent = Helper.Instance.GetScriptExtentForFunctionName(funcAst); - if (nounWhiteList.Contains(noun, StringComparer.OrdinalIgnoreCase)) + if (nounAllowList.Contains(noun, StringComparer.OrdinalIgnoreCase)) { continue; } diff --git a/Tests/Engine/ModuleHelp.Tests.ps1 b/Tests/Engine/ModuleHelp.Tests.ps1 index 428909b59..9fc2e2e0a 100644 --- a/Tests/Engine/ModuleHelp.Tests.ps1 +++ b/Tests/Engine/ModuleHelp.Tests.ps1 @@ -58,7 +58,7 @@ $RequiredVersion = (Get-Command Invoke-ScriptAnalyzer).Module.Version $ms = $null $commands = $null -$paramBlackList = @( +$paramBlockList = @( 'AttachAndDebug' # Reason: When building with DEGUG configuration, an additional parameter 'AttachAndDebug' will be added to Invoke-ScriptAnalyzer and Invoke-Formatter, but there is no Help for those, as they are not intended for production usage. ) [string] $ModuleName = 'PSScriptAnalyzer' @@ -89,11 +89,11 @@ $testCases = $commands.ForEach{ BeforeAll { - $paramBlackList = @( + $paramBlockList = @( 'AttachAndDebug' # Reason: When building with DEGUG configuration, an additional parameter 'AttachAndDebug' will be added to Invoke-ScriptAnalyzer and Invoke-Formatter, but there is no Help for those, as they are not intended for production usage. ) if ($PSVersionTable.PSVersion -lt '5.0') { - $paramBlackList += 'SaveDscDependency' + $paramBlockList += 'SaveDscDependency' } } @@ -217,7 +217,7 @@ Describe 'Cmdlet parameter help' { $HelpParameterNames = $Help.Parameters.Parameter.Name | Sort-Object -Unique foreach ($parameter in $parameters) { - if ($parameter.Name -in $paramBlackList) { + if ($parameter.Name -in $paramBlockList) { continue } $parameterName = $parameter.Name @@ -242,7 +242,7 @@ Describe 'Cmdlet parameter help' { } foreach ($helpParam in $HelpParameterNames) { - if ($helpParam -in $paramBlackList) { + if ($helpParam -in $paramBlockList) { continue } $helpParam -in $parameterNames | Should -BeTrue -Because "There should be no extra parameters in help. '$helpParam' was not in '$parameterNames'" diff --git a/Tests/Engine/Settings.tests.ps1 b/Tests/Engine/Settings.tests.ps1 index 19ba67a50..e0845425c 100644 --- a/Tests/Engine/Settings.tests.ps1 +++ b/Tests/Engine/Settings.tests.ps1 @@ -79,7 +79,32 @@ Describe "Settings Class" { } } - Context "When rule arguments are provided in a hashtable" { + Context 'When rule arguments are provided in a hashtable' { + BeforeAll { + $settingsHashtable = @{ + Rules = @{ + PSAvoidUsingCmdletAliases = @{ + AllowList = @('cd', 'cp') + } + } + } + $settings = New-Object -TypeName $settingsTypeName -ArgumentList $settingsHashtable + } + + It 'Should return the rule arguments' { + $settings.RuleArguments['PSAvoidUsingCmdletAliases']['AllowList'].Count | Should -Be 2 + $settings.RuleArguments['PSAvoidUsingCmdletAliases']['AllowList'][0] | Should -Be 'cd' + $settings.RuleArguments['PSAvoidUsingCmdletAliases']['AllowList'][1] | Should -Be 'cp' + } + + It 'Should Be case insensitive' { + $settings.RuleArguments['psAvoidUsingCmdletAliases']['AllowList'].Count | Should -Be 2 + $settings.RuleArguments['psAvoidUsingCmdletAliases']['AllowList'][0] | Should -Be 'cd' + $settings.RuleArguments['psAvoidUsingCmdletAliases']['AllowList'][1] | Should -Be 'cp' + } + } + + Context 'When rule arguments are provided in a hashtable (legacy argument name)' { BeforeAll { $settingsHashtable = @{ Rules = @{ diff --git a/Tests/Engine/SettingsTest/Issue828/PSScriptAnalyzerSettings.psd1 b/Tests/Engine/SettingsTest/Issue828/PSScriptAnalyzerSettings.psd1 index 9ac432ef9..0fd0abff9 100644 --- a/Tests/Engine/SettingsTest/Issue828/PSScriptAnalyzerSettings.psd1 +++ b/Tests/Engine/SettingsTest/Issue828/PSScriptAnalyzerSettings.psd1 @@ -1,7 +1,7 @@ @{ Severity = @( - 'Error', - 'Warning', + 'Error', + 'Warning', 'Information' ) ExcludeRules = @( @@ -14,7 +14,7 @@ CheckHashtable = $true } PSAvoidUsingCmdletAliases = @{ - # only whitelist verbs from *-Object cmdlets + # only allowlist verbs from *-Object cmdlets Whitelist = @( '%', '?', diff --git a/Tests/Rules/AvoidUsingAlias.tests.ps1 b/Tests/Rules/AvoidUsingAlias.tests.ps1 index bd691f745..ca16cf6a8 100644 --- a/Tests/Rules/AvoidUsingAlias.tests.ps1 +++ b/Tests/Rules/AvoidUsingAlias.tests.ps1 @@ -67,9 +67,9 @@ Configuration MyDscConfiguration { } } - Context "Settings file provides whitelist" { + Context "Settings file provides allowlist" { BeforeAll { - $whiteListTestScriptDef = 'gci; cd;' + $allowListTestScriptDef = 'gci; cd;' $settings = @{ 'Rules' = @{ 'PSAvoidUsingCmdletAliases' = @{ @@ -79,7 +79,7 @@ Configuration MyDscConfiguration { } } - It "honors the whitelist provided as hashtable" { + It "honors the allowlist provided as hashtable" { $settings = @{ 'Rules' = @{ 'PSAvoidUsingCmdletAliases' = @{ @@ -87,18 +87,18 @@ Configuration MyDscConfiguration { } } } - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $whiteListTestScriptDef -Settings $settings -IncludeRule $violationName + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $allowListTestScriptDef -Settings $settings -IncludeRule $violationName $violations.Count | Should -Be 1 } - It "honors the whitelist provided through settings file" { + It "honors the allowlist provided through settings file" { # even though join-path returns string, if we do not use tostring, then invoke-scriptanalyzer cannot cast it to string type $settingsFilePath = (Join-Path $PSScriptRoot (Join-Path 'TestSettings' 'AvoidAliasSettings.psd1')).ToString() - $violations = Invoke-ScriptAnalyzer -ScriptDefinition $whiteListTestScriptDef -Settings $settingsFilePath -IncludeRule $violationName + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $allowListTestScriptDef -Settings $settingsFilePath -IncludeRule $violationName $violations.Count | Should -Be 1 } - It "honors the whitelist in a case-insensitive manner" { + It "honors the allowlist in a case-insensitive manner" { $violations = Invoke-ScriptAnalyzer -ScriptDefinition "CD" -Settings $settings -IncludeRule $violationName $violations.Count | Should -Be 0 } diff --git a/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 b/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 index 1a3f2430d..b712bc6c0 100644 --- a/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 +++ b/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 @@ -30,7 +30,7 @@ Describe "UseSingularNouns" -Skip:$IsCoreCLR { } } - Context "When function names have nouns from whitelist" { + Context "When function names have nouns from allowlist" { It "ignores function name ending with Data" { $nounViolationScript = @'