From 9f2564cbcd8fe2819d1ea3d6efb6dac7c4284e8b Mon Sep 17 00:00:00 2001 From: "Raghu Shantha [MSFT]" Date: Fri, 15 May 2015 14:35:54 -0700 Subject: [PATCH 01/29] Added Build status for BugFixes and Development branches --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 25d4aea1a..1be9e6146 100644 --- a/README.md +++ b/README.md @@ -42,12 +42,13 @@ Use Visual Studio to build "PSScriptAnalyzer.sln". Use ~/PSScriptAnalyzer/ folde **Note: If there are any build errors, please refer to Requirements section and make sure all dependencies are properly installed** + Build Status -============== +============= -| |Master Branch | +| |Master |BugFixes |Development | |---------|:------:|:------:|:-------:|:-------:| -|**Debug Version**|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/master?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/master) | +|**Debug Version**|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/master?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/master)|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/bugfixes?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/bugfixes)|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/development?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/development) | Running Tests From 506da93c56936ce727a3bab1553f9588a920f2c8 Mon Sep 17 00:00:00 2001 From: "Raghu Shantha [MSFT]" Date: Fri, 15 May 2015 14:48:38 -0700 Subject: [PATCH 02/29] Update README.md --- README.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 1be9e6146..bff7837b6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,10 @@ +|Master |BugFixes |Development | +|:------:|:------:|:-------:|:-------:| +[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/master?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/master)|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/bugfixes?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/bugfixes)|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/development?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/development) | + + + Introduction ============ @@ -42,15 +48,6 @@ Use Visual Studio to build "PSScriptAnalyzer.sln". Use ~/PSScriptAnalyzer/ folde **Note: If there are any build errors, please refer to Requirements section and make sure all dependencies are properly installed** - -Build Status -============= - -| |Master |BugFixes |Development | -|---------|:------:|:------:|:-------:|:-------:| -|**Debug Version**|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/master?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/master)|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/bugfixes?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/bugfixes)|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/development?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/development) | - - Running Tests ============= From f1b8484582941f0baaba69758344391b072d3654 Mon Sep 17 00:00:00 2001 From: "Raghu Shantha [MSFT]" Date: Fri, 15 May 2015 14:54:26 -0700 Subject: [PATCH 03/29] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index bff7837b6..efe28c450 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ - |Master |BugFixes |Development | |:------:|:------:|:-------:|:-------:| [![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/master?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/master)|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/bugfixes?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/bugfixes)|[![Build status](https://ci.appveyor.com/api/projects/status/h5mot3vqtvxw5d7l/branch/development?svg=true)](https://ci.appveyor.com/project/PowerShell/psscriptanalyzer/branch/development) | -Introduction +Introduction ============ PSScriptAnalyzer is a static code checker for Windows PowerShell modules and scripts. PSScriptAnalyzer checks the quality of Windows PowerShell code by running a set of rules. The rules are based on PowerShell best practices identified by PowerShell Team and the community. It generates DiagnosticResults (errors and warnings) to inform users about potential code defects and suggests possible solutions for improvements. From 13ce922adae21f70687cfe27dcd5c82b76c6b4aa Mon Sep 17 00:00:00 2001 From: "Raghu Shantha [MSFT]" Date: Mon, 18 May 2015 15:45:08 -0700 Subject: [PATCH 04/29] Optimize DSC interface invocations - Class interface is only called for Class based resources --- .../Commands/InvokeScriptAnalyzerCommand.cs | 94 ++++++++++--------- Engine/Helper.cs | 53 ++++++++--- 2 files changed, 90 insertions(+), 57 deletions(-) diff --git a/Engine/Commands/InvokeScriptAnalyzerCommand.cs b/Engine/Commands/InvokeScriptAnalyzerCommand.cs index 2c1e2f3f4..16c2911ff 100644 --- a/Engine/Commands/InvokeScriptAnalyzerCommand.cs +++ b/Engine/Commands/InvokeScriptAnalyzerCommand.cs @@ -129,8 +129,8 @@ public SwitchParameter SuppressedOnly #region Private Members Dictionary> validationResults = new Dictionary>(); - private ScriptBlockAst ast = null; - private IEnumerable rules = null; + private ScriptBlockAst ast = null; + private IEnumerable rules = null; #endregion @@ -163,9 +163,9 @@ protected override void BeginProcessing() } else { - validationResults.Add("InvalidPaths", new List()); + validationResults.Add("InvalidPaths", new List()); validationResults.Add("ValidModPaths", new List()); - validationResults.Add("ValidDllPaths", new List()); + validationResults.Add("ValidDllPaths", new List()); } #endregion @@ -174,7 +174,7 @@ protected override void BeginProcessing() try { - if (validationResults["ValidDllPaths"].Count == 0 && + if (validationResults["ValidDllPaths"].Count == 0 && validationResults["ValidModPaths"].Count == 0) { ScriptAnalyzer.Instance.Initialize(); @@ -185,7 +185,7 @@ protected override void BeginProcessing() } } catch (Exception ex) - { + { ThrowTerminatingError(new ErrorRecord(ex, ex.HResult.ToString("X", CultureInfo.CurrentCulture), ErrorCategory.NotSpecified, this)); } @@ -228,8 +228,8 @@ private void ProcessPath(string path) if (path == null) { - ThrowTerminatingError(new ErrorRecord(new FileNotFoundException(), - string.Format(CultureInfo.CurrentCulture, Strings.FileNotFound, path), + ThrowTerminatingError(new ErrorRecord(new FileNotFoundException(), + string.Format(CultureInfo.CurrentCulture, Strings.FileNotFound, path), ErrorCategory.InvalidArgument, this)); } @@ -315,11 +315,11 @@ private void AnalyzeFile(string filePath) else { ThrowTerminatingError(new ErrorRecord(new FileNotFoundException(), - string.Format(CultureInfo.CurrentCulture, Strings.InvalidPath, filePath), + string.Format(CultureInfo.CurrentCulture, Strings.InvalidPath, filePath), ErrorCategory.InvalidArgument, filePath)); } - if (errors != null && errors.Length > 0) + if (errors != null && errors.Length > 0) { foreach (ParseError error in errors) { @@ -362,7 +362,7 @@ private void AnalyzeFile(string filePath) #region Run ScriptRules //Trim down to the leaf element of the filePath and pass it to Diagnostic Record string fileName = System.IO.Path.GetFileName(filePath); - + if (ScriptAnalyzer.Instance.ScriptRules != null) { foreach (IScriptRule scriptRule in ScriptAnalyzer.Instance.ScriptRules) @@ -433,7 +433,7 @@ private void AnalyzeFile(string filePath) break; } } - if ((includeRule == null || includeRegexMatch) && (excludeRule == null || !excludeRegexMatch)) + if ((includeRule == null || includeRegexMatch) && (excludeRule == null || !excludeRegexMatch)) { WriteVerbose(string.Format(CultureInfo.CurrentCulture, Strings.VerboseRunningMessage, tokenRule.GetName())); @@ -448,7 +448,7 @@ private void AnalyzeFile(string filePath) catch (Exception tokenRuleException) { WriteError(new ErrorRecord(tokenRuleException, Strings.RuleErrorMessage, ErrorCategory.InvalidOperation, fileName)); - } + } } } } @@ -458,46 +458,50 @@ private void AnalyzeFile(string filePath) #region DSC Resource Rules if (ScriptAnalyzer.Instance.DSCResourceRules != null) { - // Run DSC Class rule - foreach (IDSCResourceRule dscResourceRule in ScriptAnalyzer.Instance.DSCResourceRules) + // Invoke AnalyzeDSCClass only if the ast is a class based resource + if (Helper.Instance.IsDscResourceClassBased(ast)) { - bool includeRegexMatch = false; - bool excludeRegexMatch = false; - - foreach (Regex include in includeRegexList) + // Run DSC Class rule + foreach (IDSCResourceRule dscResourceRule in ScriptAnalyzer.Instance.DSCResourceRules) { - if (include.IsMatch(dscResourceRule.GetName())) + bool includeRegexMatch = false; + bool excludeRegexMatch = false; + + foreach (Regex include in includeRegexList) { - includeRegexMatch = true; - break; + if (include.IsMatch(dscResourceRule.GetName())) + { + includeRegexMatch = true; + break; + } } - } - foreach (Regex exclude in excludeRegexList) - { - if (exclude.IsMatch(dscResourceRule.GetName())) + foreach (Regex exclude in excludeRegexList) { - excludeRegexMatch = true; - break; + if (exclude.IsMatch(dscResourceRule.GetName())) + { + excludeRegexMatch = true; + break; + } } - } - - if ((includeRule == null || includeRegexMatch) && (excludeRule == null || excludeRegexMatch)) - { - WriteVerbose(string.Format(CultureInfo.CurrentCulture, Strings.VerboseRunningMessage, dscResourceRule.GetName())); - // Ensure that any unhandled errors from Rules are converted to non-terminating errors - // We want the Engine to continue functioning even if one or more Rules throws an exception - try + if ((includeRule == null || includeRegexMatch) && (excludeRule == null || excludeRegexMatch)) { - var records = Helper.Instance.SuppressRule(dscResourceRule.GetName(), ruleSuppressions, dscResourceRule.AnalyzeDSCClass(ast, filePath).ToList()); - diagnostics.AddRange(records.Item2); - suppressed.AddRange(records.Item1); + WriteVerbose(string.Format(CultureInfo.CurrentCulture, Strings.VerboseRunningMessage, dscResourceRule.GetName())); + + // Ensure that any unhandled errors from Rules are converted to non-terminating errors + // We want the Engine to continue functioning even if one or more Rules throws an exception + try + { + var records = Helper.Instance.SuppressRule(dscResourceRule.GetName(), ruleSuppressions, dscResourceRule.AnalyzeDSCClass(ast, filePath).ToList()); + diagnostics.AddRange(records.Item2); + suppressed.AddRange(records.Item1); + } + catch (Exception dscResourceRuleException) + { + WriteError(new ErrorRecord(dscResourceRuleException, Strings.RuleErrorMessage, ErrorCategory.InvalidOperation, filePath)); + } } - catch (Exception dscResourceRuleException) - { - WriteError(new ErrorRecord(dscResourceRuleException, Strings.RuleErrorMessage, ErrorCategory.InvalidOperation, filePath)); - } } } @@ -543,7 +547,7 @@ private void AnalyzeFile(string filePath) } } - } + } } #endregion @@ -607,4 +611,4 @@ private void AnalyzeFile(string filePath) #endregion } -} +} \ No newline at end of file diff --git a/Engine/Helper.cs b/Engine/Helper.cs index c603b20ce..242ed637e 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -191,6 +191,35 @@ public bool IsDscResourceModule(string filePath) return false; } + /// + /// Given an AST, checks whether dsc resource is class based or not + /// + /// + /// + public bool IsDscResourceClassBased(ScriptBlockAst ast) + { + if (null == ast) + { + return false; + } + + List dscResourceFunctionNames = new List(new string[] { "Test", "Get", "Set" }); + + IEnumerable dscClasses = ast.FindAll(item => + item is TypeDefinitionAst + && ((item as TypeDefinitionAst).IsClass) + && (item as TypeDefinitionAst).Attributes.Any(attr => String.Equals("DSCResource", attr.TypeName.FullName, StringComparison.OrdinalIgnoreCase)), true); + + // Found one or more classes marked with DscResource attribute + // So this might be a DscResource. Further validation will be performed by the individual rules + if (null != dscClasses && 0 < dscClasses.Count()) + { + return true; + } + + return false; + } + /// /// Given a commandast, checks whether positional parameters are used or not. /// @@ -280,7 +309,7 @@ public bool PositionalParameterUsed(CommandAst cmdAst) /// /// /// - public CommandInfo GetCommandInfo(string name, CommandTypes commandType=CommandTypes.All) + public CommandInfo GetCommandInfo(string name, CommandTypes commandType = CommandTypes.All) { return Helper.Instance.MyCmdlet.InvokeCommand.GetCommand(name, commandType); } @@ -294,7 +323,7 @@ public IEnumerable DscResourceFunctions(Ast ast) { List resourceFunctionNames = new List(new string[] { "Set-TargetResource", "Get-TargetResource", "Test-TargetResource" }); return ast.FindAll(item => item is FunctionDefinitionAst - && resourceFunctionNames.Contains((item as FunctionDefinitionAst).Name, StringComparer.OrdinalIgnoreCase), true); + && resourceFunctionNames.Contains((item as FunctionDefinitionAst).Name, StringComparer.OrdinalIgnoreCase), true); } /// @@ -481,7 +510,7 @@ public bool AllCodePathReturns(Ast ast) var analysis = VariableAnalysisDictionary[ast]; return analysis.Exit._predecessors.All(block => block._returns || block._unreachable || block._throws); } - + /// /// Initialize variable analysis on the script ast /// @@ -701,7 +730,7 @@ public Dictionary> GetRuleSuppression(Ast ast) { ruleSuppressionList.AddRange(RuleSuppression.GetSuppressions(sbAst.ParamBlock.Attributes, sbAst.Extent.StartOffset, sbAst.Extent.EndOffset, sbAst)); } - + // Get rule suppression from functions IEnumerable funcAsts = ast.FindAll(item => item is FunctionDefinitionAst, true).Cast(); @@ -727,13 +756,13 @@ public Dictionary> GetRuleSuppression(Ast ast) List ruleSuppressions = new List(); results.Add(ruleSuppression.RuleName, ruleSuppressions); } - + results[ruleSuppression.RuleName].Add(ruleSuppression); } return results; } - + /// /// Returns a list of rule suppressions from the function /// @@ -943,11 +972,11 @@ public int Compare(Tuple t1, Tuple t2) } } } - + /// /// Class used to do variable analysis on the whole script /// - public class ScriptAnalysis: ICustomAstVisitor + public class ScriptAnalysis : ICustomAstVisitor { private VariableAnalysis OuterAnalysis; @@ -1148,7 +1177,7 @@ public object VisitBreakStatement(BreakStatementAst breakStatementAst) { return null; } - + /// /// Visits body /// @@ -2396,7 +2425,7 @@ public object VisitArrayExpression(ArrayExpressionAst arrayExprAst) { return typeof(System.Array).FullName; } - + /// /// Returns type of array /// @@ -2499,7 +2528,7 @@ public object VisitIndexExpression(IndexExpressionAst indexAst) return null; } - + /// /// Only returns boolean type for unary operator that returns boolean /// @@ -2540,4 +2569,4 @@ public object VisitUsingExpression(UsingExpressionAst usingExpressionAst) return null; } } -} +} \ No newline at end of file From cfbeb7b478cca0ad25055b8495a024e00c2f499a Mon Sep 17 00:00:00 2001 From: "Raghu Shantha [MSFT]" Date: Mon, 18 May 2015 15:57:46 -0700 Subject: [PATCH 05/29] Fixed parameter name in the comment section of the helper method --- Engine/Helper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/Helper.cs b/Engine/Helper.cs index 242ed637e..8864ac136 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -194,7 +194,7 @@ public bool IsDscResourceModule(string filePath) /// /// Given an AST, checks whether dsc resource is class based or not /// - /// + /// /// public bool IsDscResourceClassBased(ScriptBlockAst ast) { From f4ff1ae716914be626c9bf95dbdd6f8760f71c90 Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Tue, 19 May 2015 10:37:01 -0700 Subject: [PATCH 06/29] Add checks for XPath for AvoidUsingInternalURL --- Rules/AvoidUsingInternalURLs.cs | 21 +++++++++++++++++++ Tests/Rules/AvoidUsingInternalURLs.ps1 | 2 +- .../AvoidUsingInternalURLsNoViolations.ps1 | 4 ++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Rules/AvoidUsingInternalURLs.cs b/Rules/AvoidUsingInternalURLs.cs index 095cd5412..94a39e3a0 100644 --- a/Rules/AvoidUsingInternalURLs.cs +++ b/Rules/AvoidUsingInternalURLs.cs @@ -44,6 +44,27 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) { foreach (StringConstantExpressionAst expressionAst in expressionAsts) { + //Check if XPath is used. If XPath is used, then we don't throw warnings. + Ast parentAst = expressionAst.Parent; + IEnumerable invocation = parentAst.FindAll(test => test is InvokeMemberExpressionAst, true); + bool hasXPath = false; + if (invocation != null) + { + foreach (InvokeMemberExpressionAst ieAst in invocation) + { + if (String.Equals(ieAst.Member.ToString(), "SelectSingleNode",StringComparison.OrdinalIgnoreCase) || + String.Equals(ieAst.Member.ToString(), "SelectNodes",StringComparison.OrdinalIgnoreCase)) + { + hasXPath = true; + break; + } + } + } + if (hasXPath) + { + continue; + } + bool isPathValid = false; bool isInternalURL = false; //make sure there is no path diff --git a/Tests/Rules/AvoidUsingInternalURLs.ps1 b/Tests/Rules/AvoidUsingInternalURLs.ps1 index da001d85c..2cbd676f0 100644 --- a/Tests/Rules/AvoidUsingInternalURLs.ps1 +++ b/Tests/Rules/AvoidUsingInternalURLs.ps1 @@ -3,4 +3,4 @@ $internalSite = "//msw" $externalSite = "http:\\msw" if (-not $scratch.EndsWith("/")) { $scratch += "/"; -} \ No newline at end of file +} diff --git a/Tests/Rules/AvoidUsingInternalURLsNoViolations.ps1 b/Tests/Rules/AvoidUsingInternalURLsNoViolations.ps1 index cdd8b7cc5..337bb0832 100644 --- a/Tests/Rules/AvoidUsingInternalURLsNoViolations.ps1 +++ b/Tests/Rules/AvoidUsingInternalURLsNoViolations.ps1 @@ -1,4 +1,8 @@ $correctPath = "www.bing.com" $externalSite = "//outside.co/test" rmdir /s /q ".\Directory" +function Test +{ + $filesNode = $infoXml.SelectSingleNode("//files") +} $sd = "O:BAG:BAD:(A;;0x800;;;WD)(A;;0x120fff;;;SY)(A;;0x120fff;;;LS)(A;;0x120fff;;;NS)(A;;0x120fff;;;BA)(A;;0xee5;;;LU)(A;;LC;;;MU)(A;;0x800;;;AG)" \ No newline at end of file From 1d4f3f6b6ef696b7771dd968cc4b3d165bea6497 Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Tue, 19 May 2015 11:36:04 -0700 Subject: [PATCH 07/29] Add more checks for any methods that take XPathExpression --- Rules/AvoidUsingInternalURLs.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Rules/AvoidUsingInternalURLs.cs b/Rules/AvoidUsingInternalURLs.cs index 94a39e3a0..131d8b1c2 100644 --- a/Rules/AvoidUsingInternalURLs.cs +++ b/Rules/AvoidUsingInternalURLs.cs @@ -53,7 +53,10 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) foreach (InvokeMemberExpressionAst ieAst in invocation) { if (String.Equals(ieAst.Member.ToString(), "SelectSingleNode",StringComparison.OrdinalIgnoreCase) || - String.Equals(ieAst.Member.ToString(), "SelectNodes",StringComparison.OrdinalIgnoreCase)) + String.Equals(ieAst.Member.ToString(), "SelectNodes",StringComparison.OrdinalIgnoreCase) || + String.Equals(ieAst.Member.ToString(), "Select",StringComparison.OrdinalIgnoreCase) || + String.Equals(ieAst.Member.ToString(), "Evaluate",StringComparison.OrdinalIgnoreCase) || + String.Equals(ieAst.Member.ToString(), "Matches",StringComparison.OrdinalIgnoreCase)) { hasXPath = true; break; From 32e2f614b0c4fdbe1022b92d485b5628bbc34aee Mon Sep 17 00:00:00 2001 From: Quoc Truong Date: Tue, 19 May 2015 12:23:19 -0700 Subject: [PATCH 08/29] Fix avoiduninitializedvariable not recognizing switchparameter --- Engine/VariableAnalysis.cs | 2 +- Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Engine/VariableAnalysis.cs b/Engine/VariableAnalysis.cs index 5445df4bc..7c29c170f 100644 --- a/Engine/VariableAnalysis.cs +++ b/Engine/VariableAnalysis.cs @@ -86,7 +86,7 @@ private void ProcessParameters(IEnumerable parameters) type = paramAst.TypeName.GetReflectionType(); } - if (String.Equals(paramAst.TypeName.FullName, "switch", StringComparison.OrdinalIgnoreCase)) + if (paramAst.TypeName.GetReflectionType() == typeof(System.Management.Automation.SwitchParameter)) { isSwitchOrMandatory = true; } diff --git a/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 b/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 index 432dd1a91..ea436bb4f 100644 --- a/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 +++ b/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 @@ -31,6 +31,13 @@ $proc[0] function Test-PreferenceVariable { + Param( + [switch] + $a, + + [System.Management.Automation.SwitchParameter] + $b + ) if (-not $PSBoundParameters.ContainsKey('Verbose')) { $VerbosePreference = $PSCmdlet.GetVariableValue('VerbosePreference') -as @@ -38,4 +45,4 @@ function Test-PreferenceVariable } $VerbosePreference - } \ No newline at end of file +} \ No newline at end of file From 55db24fc57373a31e90fb40f0c8a6915b0ba0cbe Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Tue, 19 May 2015 14:09:57 -0700 Subject: [PATCH 09/29] Change to only check one ParentAst --- Rules/AvoidUsingInternalURLs.cs | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/Rules/AvoidUsingInternalURLs.cs b/Rules/AvoidUsingInternalURLs.cs index 131d8b1c2..2fb9396e2 100644 --- a/Rules/AvoidUsingInternalURLs.cs +++ b/Rules/AvoidUsingInternalURLs.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; +using System.Data.Odbc; using System.Linq; using System.Management.Automation.Language; using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; @@ -46,28 +47,24 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) { //Check if XPath is used. If XPath is used, then we don't throw warnings. Ast parentAst = expressionAst.Parent; - IEnumerable invocation = parentAst.FindAll(test => test is InvokeMemberExpressionAst, true); - bool hasXPath = false; - if (invocation != null) + if (parentAst is InvokeMemberExpressionAst) { - foreach (InvokeMemberExpressionAst ieAst in invocation) + InvokeMemberExpressionAst invocation = parentAst as InvokeMemberExpressionAst; + if (invocation != null) { - if (String.Equals(ieAst.Member.ToString(), "SelectSingleNode",StringComparison.OrdinalIgnoreCase) || - String.Equals(ieAst.Member.ToString(), "SelectNodes",StringComparison.OrdinalIgnoreCase) || - String.Equals(ieAst.Member.ToString(), "Select",StringComparison.OrdinalIgnoreCase) || - String.Equals(ieAst.Member.ToString(), "Evaluate",StringComparison.OrdinalIgnoreCase) || - String.Equals(ieAst.Member.ToString(), "Matches",StringComparison.OrdinalIgnoreCase)) + if (String.Equals(invocation.Member.ToString(), "SelectSingleNode",StringComparison.OrdinalIgnoreCase) || + String.Equals(invocation.Member.ToString(), "SelectNodes",StringComparison.OrdinalIgnoreCase) || + String.Equals(invocation.Member.ToString(), "Select", StringComparison.OrdinalIgnoreCase) || + String.Equals(invocation.Member.ToString(), "Evaluate",StringComparison.OrdinalIgnoreCase) || + String.Equals(invocation.Member.ToString(), "Matches",StringComparison.OrdinalIgnoreCase)) { - hasXPath = true; - break; + continue; } + } } - if (hasXPath) - { - continue; - } - + + bool isPathValid = false; bool isInternalURL = false; //make sure there is no path From f29e0fcde49c2bb7af93111c276cb46970fc3c50 Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Tue, 19 May 2015 14:23:21 -0700 Subject: [PATCH 10/29] Change severity level to information --- Rules/AvoidUsingInternalURLs.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Rules/AvoidUsingInternalURLs.cs b/Rules/AvoidUsingInternalURLs.cs index 2fb9396e2..42f1692f8 100644 --- a/Rules/AvoidUsingInternalURLs.cs +++ b/Rules/AvoidUsingInternalURLs.cs @@ -12,7 +12,6 @@ using System; using System.Collections.Generic; -using System.Data.Odbc; using System.Linq; using System.Management.Automation.Language; using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; @@ -149,7 +148,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) new DiagnosticRecord( String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingInternalURLsError, expressionAst.Value), expressionAst.Extent, - GetName(), DiagnosticSeverity.Warning, fileName); + GetName(), DiagnosticSeverity.Information, fileName); } } @@ -198,7 +197,7 @@ public SourceType GetSourceType() /// public RuleSeverity GetSeverity() { - return RuleSeverity.Warning; + return RuleSeverity.Information; } /// From fe6d977a08b4415dea7dfb2c5c4dac9fbbbece52 Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Tue, 19 May 2015 14:28:52 -0700 Subject: [PATCH 11/29] Update the tests --- Tests/Engine/GetScriptAnalyzerRule.tests.ps1 | 6 +++--- Tests/Engine/InvokeScriptAnalyzer.tests.ps1 | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 b/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 index 8aed2010d..9d22c9d92 100644 --- a/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 +++ b/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 @@ -118,7 +118,7 @@ Describe "TestSeverity" { It "filters rules based on multiple severity inputs"{ $rules = Get-ScriptAnalyzerRule -Severity Error,Information - $rules.Count | Should be 9 + $rules.Count | Should be 13 } It "takes lower case inputs" { @@ -130,11 +130,11 @@ Describe "TestSeverity" { Describe "TestWildCard" { It "filters rules based on the -Name wild card input" { $rules = Get-ScriptAnalyzerRule -Name PSDSC* - $rules.Count | Should be 4 + $rules.Count | Should be 6 } It "filters rules based on wild card input and severity"{ $rules = Get-ScriptAnalyzerRule -Name PSDSC* -Severity Information - $rules.Count | Should be 1 + $rules.Count | Should be 3 } } \ No newline at end of file diff --git a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 index d32ce54fe..f5303a2f4 100644 --- a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 +++ b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 @@ -141,7 +141,7 @@ Describe "Test IncludeRule" { it "includes 2 wildcardrules" { $includeWildcard = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -IncludeRule $avoidRules, $useRules - $includeWildcard.Count | Should be 7 + $includeWildcard.Count | Should be 9 } } } From f6ba095a36f4c2c2fdcd13f70b53c55649e8d873 Mon Sep 17 00:00:00 2001 From: "Yuting Chen[MSFT]" Date: Tue, 19 May 2015 15:20:55 -0700 Subject: [PATCH 12/29] Update GetScriptAnalyzerRule.tests.ps1 Fix the merging problem --- Tests/Engine/GetScriptAnalyzerRule.tests.ps1 | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 b/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 index 3b8e9ea02..fa5346b6a 100644 --- a/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 +++ b/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 @@ -118,11 +118,7 @@ Describe "TestSeverity" { It "filters rules based on multiple severity inputs"{ $rules = Get-ScriptAnalyzerRule -Severity Error,Information -<<<<<<< HEAD $rules.Count | Should be 13 -======= - $rules.Count | Should be 12 ->>>>>>> c29d7fbafdc3fd3e5a447ec2b33211a3783f3c96 } It "takes lower case inputs" { @@ -141,4 +137,4 @@ Describe "TestWildCard" { $rules = Get-ScriptAnalyzerRule -Name PSDSC* -Severity Information $rules.Count | Should be 3 } -} \ No newline at end of file +} From 2bc754d7a8050ba5491e7f6e50bad45f9ba18642 Mon Sep 17 00:00:00 2001 From: "Raghu Shantha [MSFT]" Date: Wed, 20 May 2015 12:32:55 -0700 Subject: [PATCH 13/29] Rename License.txt to LICENSE.md --- License.txt => LICENSE.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename License.txt => LICENSE.md (100%) diff --git a/License.txt b/LICENSE.md similarity index 100% rename from License.txt rename to LICENSE.md From 5f677e951797afaf5994c3075fa25873b7915270 Mon Sep 17 00:00:00 2001 From: "Raghu Shantha [MSFT]" Date: Wed, 20 May 2015 12:33:31 -0700 Subject: [PATCH 14/29] Rename LICENSE.md to LICENSE --- LICENSE.md => LICENSE | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename LICENSE.md => LICENSE (100%) diff --git a/LICENSE.md b/LICENSE similarity index 100% rename from LICENSE.md rename to LICENSE From 1e78842e0a11a56ff0b6abe282f40072d58e3b31 Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Thu, 21 May 2015 15:25:52 -0700 Subject: [PATCH 15/29] Add check for builtin variables for GlobalVar rule --- Engine/Helper.cs | 17 +++++++++++++++++ Rules/AvoidGlobalVars.cs | 2 +- Tests/Rules/AvoidGlobalOrUnitializedVars.ps1 | 5 ++++- ...AvoidGlobalOrUnitializedVarsNoViolations.ps1 | 14 +++++--------- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/Engine/Helper.cs b/Engine/Helper.cs index 8864ac136..92e8ed358 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -494,6 +494,23 @@ public bool IsVariableGlobalOrEnvironment(VariableExpressionAst varAst, Ast ast) return VariableAnalysisDictionary[ast].IsGlobalOrEnvironment(varAst); } + + /// + /// Checks whether a variable is a built-in variable. + /// + /// + /// + public bool IsVariableGlobal(VariableExpressionAst varAst) + { + if (varAst.VariablePath.IsGlobal) + { + string varName = varAst.VariablePath.UserPath.Remove(varAst.VariablePath.UserPath.IndexOf("global:", StringComparison.OrdinalIgnoreCase), "global:".Length); + return !SpecialVars.InitializedVariables.Contains(varName, StringComparer.OrdinalIgnoreCase); + } + return false; + } + + /// /// Checks whether all the code path of ast returns. /// Runs InitializeVariableAnalysis before calling this method diff --git a/Rules/AvoidGlobalVars.cs b/Rules/AvoidGlobalVars.cs index 6da1cdb91..109da5ee5 100644 --- a/Rules/AvoidGlobalVars.cs +++ b/Rules/AvoidGlobalVars.cs @@ -41,7 +41,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) { foreach (VariableExpressionAst varAst in varAsts) { - if (varAst.VariablePath.IsGlobal) + if (Helper.Instance.IsVariableGlobal(varAst)) { yield return new DiagnosticRecord( diff --git a/Tests/Rules/AvoidGlobalOrUnitializedVars.ps1 b/Tests/Rules/AvoidGlobalOrUnitializedVars.ps1 index ef6988ad9..e606404f3 100644 --- a/Tests/Rules/AvoidGlobalOrUnitializedVars.ps1 +++ b/Tests/Rules/AvoidGlobalOrUnitializedVars.ps1 @@ -1,4 +1,7 @@ -$Global:1 = "Globalization?" +$Global:1 = "globalVar“ +$Global:DebugPreference + + function NotGlobal { $localVars = "Localization?" diff --git a/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 b/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 index ea436bb4f..6a9ce8077 100644 --- a/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 +++ b/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 @@ -1,4 +1,7 @@ -function Test { +$Global:DebugPreference + + +function Test { $initialized = "Initialized" $noglobal = "local" $env:ShouldNotRaiseError @@ -31,13 +34,6 @@ $proc[0] function Test-PreferenceVariable { - Param( - [switch] - $a, - - [System.Management.Automation.SwitchParameter] - $b - ) if (-not $PSBoundParameters.ContainsKey('Verbose')) { $VerbosePreference = $PSCmdlet.GetVariableValue('VerbosePreference') -as @@ -45,4 +41,4 @@ function Test-PreferenceVariable } $VerbosePreference -} \ No newline at end of file + } \ No newline at end of file From 7a1215a6b123c1ac2c1a225703e87a064d7bcb03 Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Thu, 21 May 2015 15:54:57 -0700 Subject: [PATCH 16/29] Modify the comment --- Engine/Helper.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Engine/Helper.cs b/Engine/Helper.cs index 92e8ed358..2f334241d 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -496,12 +496,13 @@ public bool IsVariableGlobalOrEnvironment(VariableExpressionAst varAst, Ast ast) /// - /// Checks whether a variable is a built-in variable. + /// Checks whether a variable is a global variable. /// /// /// public bool IsVariableGlobal(VariableExpressionAst varAst) { + //We ignore the use of built-in variable as global variable if (varAst.VariablePath.IsGlobal) { string varName = varAst.VariablePath.UserPath.Remove(varAst.VariablePath.UserPath.IndexOf("global:", StringComparison.OrdinalIgnoreCase), "global:".Length); From 6c9b9cfadd1fa954f57026855f4a3c199947f6a6 Mon Sep 17 00:00:00 2001 From: quoctruong Date: Fri, 22 May 2015 19:17:54 -0700 Subject: [PATCH 17/29] Fix AvoidUsingPlainTextForPassword raised for types other than strings or object --- Rules/AvoidUsingPlainTextForPassword.cs | 4 ++-- Tests/Rules/AvoidUsingPlainTextForPasswordNoViolations.ps1 | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Rules/AvoidUsingPlainTextForPassword.cs b/Rules/AvoidUsingPlainTextForPassword.cs index a4f6e0d9d..9cc2e1171 100644 --- a/Rules/AvoidUsingPlainTextForPassword.cs +++ b/Rules/AvoidUsingPlainTextForPassword.cs @@ -55,8 +55,8 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) } } - if (hasPwd && (!paramType.IsArray && paramType != typeof(System.Security.SecureString) - || (paramType.IsArray && paramType.GetElementType() != typeof(System.Security.SecureString)))) + if (hasPwd && (!paramType.IsArray && (paramType == typeof(String) || paramType == typeof(object))) + || (paramType.IsArray && (paramType.GetElementType() == typeof(String) || paramType.GetElementType() == typeof(object)))) { yield return new DiagnosticRecord( String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingPlainTextForPasswordError, paramAst.Name), diff --git a/Tests/Rules/AvoidUsingPlainTextForPasswordNoViolations.ps1 b/Tests/Rules/AvoidUsingPlainTextForPasswordNoViolations.ps1 index a4e84f4b9..3203dc0f4 100644 --- a/Tests/Rules/AvoidUsingPlainTextForPasswordNoViolations.ps1 +++ b/Tests/Rules/AvoidUsingPlainTextForPasswordNoViolations.ps1 @@ -10,7 +10,8 @@ ValueFromPipelineByPropertyName=$true, Position=0)] $Param1, - + [int] + $passwordinteger, # Param2 help description [int] $Param2, From 1b15e8444ae88c23ef497bd3c993e1c76555e0d2 Mon Sep 17 00:00:00 2001 From: quoctruong Date: Fri, 22 May 2015 19:32:49 -0700 Subject: [PATCH 18/29] Fix UseDeclaredVarsMoreThanAssignment not recognizing script variables --- Rules/UseDeclaredVarsMoreThanAssignments.cs | 3 ++- Tests/Rules/UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Rules/UseDeclaredVarsMoreThanAssignments.cs b/Rules/UseDeclaredVarsMoreThanAssignments.cs index c6e346a4f..b921f4df6 100644 --- a/Rules/UseDeclaredVarsMoreThanAssignments.cs +++ b/Rules/UseDeclaredVarsMoreThanAssignments.cs @@ -54,7 +54,8 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) foreach (VariableExpressionAst assignmentVarAst in assingmentVarAsts) { //Ignore if variable is global or environment variable - if (!Helper.Instance.IsVariableGlobalOrEnvironment(assignmentVarAst, ast)) + if (!Helper.Instance.IsVariableGlobalOrEnvironment(assignmentVarAst, ast) + && !assignmentVarAst.VariablePath.IsScript) { if (!assignments.ContainsKey(assignmentVarAst.VariablePath.UserPath)) { diff --git a/Tests/Rules/UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 b/Tests/Rules/UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 index 237f66589..2884d7de1 100644 --- a/Tests/Rules/UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 +++ b/Tests/Rules/UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 @@ -1,2 +1,3 @@ $declaredVars = "Declared Vars" -Write-Ouput $declaredVars \ No newline at end of file +Write-Ouput $declaredVars +$script:thisshouldnotraiseerrors = "this should not raise errors" \ No newline at end of file From 4c45a162273f9576f9e2c1044f48d69b84b33094 Mon Sep 17 00:00:00 2001 From: quoctruong Date: Fri, 22 May 2015 19:40:06 -0700 Subject: [PATCH 19/29] Fix UseDeclaredVarsMoreThanAssignments being raised for setting properties --- Rules/UseDeclaredVarsMoreThanAssignments.cs | 7 ++++--- .../UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Rules/UseDeclaredVarsMoreThanAssignments.cs b/Rules/UseDeclaredVarsMoreThanAssignments.cs index b921f4df6..b1b893497 100644 --- a/Rules/UseDeclaredVarsMoreThanAssignments.cs +++ b/Rules/UseDeclaredVarsMoreThanAssignments.cs @@ -49,11 +49,12 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) { foreach (AssignmentStatementAst assignmentAst in assignmentAsts) { - assingmentVarAsts = assignmentAst.Left.FindAll(testAst => testAst is VariableExpressionAst, true); ; + // Only checks for the case where lhs is a variable. Ignore things like $foo.property + VariableExpressionAst assignmentVarAst = assignmentAst.Left as VariableExpressionAst; - foreach (VariableExpressionAst assignmentVarAst in assingmentVarAsts) + if (assignmentVarAst != null) { - //Ignore if variable is global or environment variable + //Ignore if variable is global or environment variable if (!Helper.Instance.IsVariableGlobalOrEnvironment(assignmentVarAst, ast) && !assignmentVarAst.VariablePath.IsScript) { diff --git a/Tests/Rules/UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 b/Tests/Rules/UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 index 2884d7de1..769c9a2e3 100644 --- a/Tests/Rules/UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 +++ b/Tests/Rules/UseDeclaredVarsMoreThanAssignmentsNoViolations.ps1 @@ -1,3 +1,4 @@ $declaredVars = "Declared Vars" Write-Ouput $declaredVars -$script:thisshouldnotraiseerrors = "this should not raise errors" \ No newline at end of file +$script:thisshouldnotraiseerrors = "this should not raise errors" +$foo.property = "This also should not raise errors" \ No newline at end of file From ef0db7ff6ca91bc885275c98090c75b6198caf34 Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Tue, 26 May 2015 15:23:55 -0700 Subject: [PATCH 20/29] Add check for both IsPlural and IsSingular for nouns --- Rules/UseSingularNouns.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rules/UseSingularNouns.cs b/Rules/UseSingularNouns.cs index 503e7162b..89d7d3095 100644 --- a/Rules/UseSingularNouns.cs +++ b/Rules/UseSingularNouns.cs @@ -49,7 +49,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) { String noun = funcNamePieces[1]; var ps = System.Data.Entity.Design.PluralizationServices.PluralizationService.CreateService(CultureInfo.GetCultureInfo("en-us")); - if (!ps.IsSingular(noun)) + if (!ps.IsSingular(noun) && ps.IsPlural(noun)) { yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.UseSingularNounsError, funcAst.Name), funcAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName); From 1e2be1eed3e9dfed93d4277bd91328b213f30cd3 Mon Sep 17 00:00:00 2001 From: "Yuting Chen[MSFT]" Date: Tue, 26 May 2015 16:17:45 -0700 Subject: [PATCH 21/29] Update ScriptRuleDocumentation.md Update PowerShell capitalization. --- ScriptRuleDocumentation.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ScriptRuleDocumentation.md b/ScriptRuleDocumentation.md index 51e58f5a1..2be261fee 100644 --- a/ScriptRuleDocumentation.md +++ b/ScriptRuleDocumentation.md @@ -20,7 +20,7 @@ This documentation serves as a basic guideline on how to define customized rules - Output type should be DiagnosticRecord: ``` -[OutputType([Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]])] +[OutputType([Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]])] ``` - Make sure each function takes either a Token or an Ast as a parameter @@ -36,7 +36,7 @@ Param - DiagnosticRecord should have four properties: Message, Extent, RuleName and Severity ``` -$result = [Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]]@{"Message" = "This is a sample rule"; +$result = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]]@{"Message" = "This is a sample rule"; "Extent" = $ast.Extent; "RuleName" = $PSCmdlet.MyInvocation.InvocationName; "Severity" = "Warning"} @@ -62,14 +62,14 @@ Export-ModuleMember -Function (FunctionName) .INPUTS [System.Management.Automation.Language.ScriptBlockAst] .OUTPUTS - [Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]] + [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]] .NOTES None #> function Measure-RequiresRunAsAdministrator { [CmdletBinding()] - [OutputType([Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord[]])] + [OutputType([Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]])] Param ( [Parameter(Mandatory = $true)] @@ -127,7 +127,7 @@ function Measure-RequiresRunAsAdministrator if ((!$ScriptBlockAst.ScriptRequirements.IsElevationRequired) -and ($methodAst.Count -ne 0) -and ($assignmentAst.Count -ne 0)) { - $result = [Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord]@{"Message" = $Messages.MeasureRequiresRunAsAdministrator; + $result = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord]@{"Message" = $Messages.MeasureRequiresRunAsAdministrator; "Extent" = $assignmentAst.Extent; "RuleName" = $PSCmdlet.MyInvocation.InvocationName; "Severity" = "Information"} @@ -138,7 +138,7 @@ function Measure-RequiresRunAsAdministrator { if (($methodAst.Count -ne 0) -and ($assignmentAst.Count -ne 0)) { - $result = [Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord]@{"Message" = $Messages.MeasureRequiresRunAsAdministrator; + $result = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord]@{"Message" = $Messages.MeasureRequiresRunAsAdministrator; "Extent" = $assignmentAst.Extent; "RuleName" = $PSCmdlet.MyInvocation.InvocationName; "Severity" = "Information"} From 0bb0143383cfd53618645c3c1a4cc799068673a5 Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Tue, 26 May 2015 16:38:11 -0700 Subject: [PATCH 22/29] Update Powershell to PowerShell Also remove AvoidTrapStatement rule and clean up all unnessary "using" headers --- .../Commands/GetScriptAnalyzerRuleCommand.cs | 5 +- .../Commands/InvokeScriptAnalyzerCommand.cs | 9 +- Engine/Generic/AvoidCmdletGeneric.cs | 6 +- Engine/Generic/AvoidParameterGeneric.cs | 5 +- Engine/Generic/DiagnosticRecord.cs | 7 +- Engine/Generic/ExternalRule.cs | 7 +- Engine/Generic/IDSCResourceRule.cs | 2 +- Engine/Generic/IExternalRule.cs | 7 +- Engine/Generic/ILogger.cs | 8 +- Engine/Generic/IRule.cs | 2 +- Engine/Generic/IScriptRule.cs | 2 +- Engine/Generic/ITokenRule.cs | 2 +- Engine/Generic/LoggerInfo.cs | 7 +- Engine/Generic/RuleInfo.cs | 7 +- Engine/Generic/RuleSeverity.cs | 2 +- Engine/Generic/RuleSuppression.cs | 2 +- Engine/Generic/SkipNamedBlock.cs | 4 +- Engine/Generic/SkipTypeDefinition.cs | 2 +- Engine/Generic/SourceType.cs | 8 +- Engine/Generic/SuppressedRecord.cs | 18 ++-- Engine/Helper.cs | 5 +- Engine/Loggers/WriteObjectsLogger.cs | 12 +-- Engine/ScriptAnalyzer.cs | 8 +- Engine/ScriptAnalyzerEngine.csproj | 4 +- Engine/SpecialVars.cs | 7 +- Engine/Strings.Designer.cs | 22 ++-- Engine/VariableAnalysis.cs | 8 +- Engine/VariableAnalysisBase.cs | 3 +- Rules/AvoidAlias.cs | 6 +- Rules/AvoidDefaultTrueValueSwitchParameter.cs | 4 +- Rules/AvoidEmptyCatchBlock.cs | 4 +- Rules/AvoidGlobalVars.cs | 4 +- Rules/AvoidInvokingEmptyMembers.cs | 4 +- Rules/AvoidPositionalParameters.cs | 4 +- Rules/AvoidReservedCharInCmdlet.cs | 5 +- Rules/AvoidReservedParams.cs | 4 +- Rules/AvoidShouldContinueWithoutForce.cs | 4 +- Rules/AvoidTrapStatement.cs | 101 ------------------ Rules/AvoidUninitializedVariable.cs | 4 +- Rules/AvoidUserNameAndPasswordParams.cs | 4 +- Rules/AvoidUsingComputerNameHardcoded.cs | 4 +- ...UsingConvertToSecureStringWithPlainText.cs | 4 +- Rules/AvoidUsingInternalURLs.cs | 4 +- Rules/AvoidUsingInvokeExpression.cs | 4 +- Rules/AvoidUsingPlainTextForPassword.cs | 4 +- Rules/AvoidUsingWMICmdlet.cs | 12 +-- Rules/AvoidUsingWriteHost.cs | 4 +- Rules/DscExamplesPresent.cs | 5 +- Rules/DscTestsPresent.cs | 5 +- Rules/MissingModuleManifestField.cs | 5 +- Rules/PossibleIncorrectComparisonWithNull.cs | 4 +- Rules/ProvideCommentHelp.cs | 4 +- Rules/ProvideVerboseMessage.cs | 4 +- Rules/ReturnCorrectTypesForDSCFunctions.cs | 4 +- Rules/ScriptAnalyzerBuiltinRules.csproj | 5 +- Rules/Strings.Designer.cs | 6 +- Rules/UseApprovedVerbs.cs | 4 +- Rules/UseCmdletCorrectly.cs | 4 +- Rules/UseDeclaredVarsMoreThanAssignments.cs | 4 +- Rules/UseIdenticalMandatoryParametersDSC.cs | 4 +- Rules/UseIdenticalParametersDSC.cs | 4 +- Rules/UseOutputTypeCorrectly.cs | 4 +- Rules/UsePSCredentialType.cs | 4 +- Rules/UseShouldProcessCorrectly.cs | 4 +- ...eShouldProcessForStateChangingFunctions.cs | 4 +- Rules/UseSingularNouns.cs | 5 +- Rules/UseStandardDSCFunctionsInResource.cs | 4 +- 67 files changed, 137 insertions(+), 315 deletions(-) delete mode 100644 Rules/AvoidTrapStatement.cs diff --git a/Engine/Commands/GetScriptAnalyzerRuleCommand.cs b/Engine/Commands/GetScriptAnalyzerRuleCommand.cs index b749bc6e9..ed4799c40 100644 --- a/Engine/Commands/GetScriptAnalyzerRuleCommand.cs +++ b/Engine/Commands/GetScriptAnalyzerRuleCommand.cs @@ -10,16 +10,15 @@ // THE SOFTWARE. // -using Microsoft.PowerShell.Commands; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Management.Automation; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Commands +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands { /// /// GetScriptAnalyzerRuleCommand: Cmdlet to list all the analyzer rule names and descriptions. diff --git a/Engine/Commands/InvokeScriptAnalyzerCommand.cs b/Engine/Commands/InvokeScriptAnalyzerCommand.cs index 16c2911ff..02ef89a75 100644 --- a/Engine/Commands/InvokeScriptAnalyzerCommand.cs +++ b/Engine/Commands/InvokeScriptAnalyzerCommand.cs @@ -11,22 +11,17 @@ // using System.Text.RegularExpressions; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; using System; using System.Collections.Generic; -using System.ComponentModel.Composition; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Management.Automation; using System.Management.Automation.Language; -using System.Resources; -using System.Threading; -using System.Reflection; using System.IO; -using System.Text; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Commands +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands { /// /// InvokeScriptAnalyzerCommand: Cmdlet to statically check PowerShell scripts. diff --git a/Engine/Generic/AvoidCmdletGeneric.cs b/Engine/Generic/AvoidCmdletGeneric.cs index 1ae87fa31..5546295bf 100644 --- a/Engine/Generic/AvoidCmdletGeneric.cs +++ b/Engine/Generic/AvoidCmdletGeneric.cs @@ -13,11 +13,9 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Management.Automation.Language; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// Represents an abstract class for rule that checks whether the script @@ -38,7 +36,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) // Finds all CommandAsts. IEnumerable commandAsts = ast.FindAll(testAst => testAst is CommandAst, true); - List cmdletNameAndAliases = Microsoft.Windows.Powershell.ScriptAnalyzer.Helper.Instance.CmdletNameAndAliases(GetCmdletName()); + List cmdletNameAndAliases = Microsoft.Windows.PowerShell.ScriptAnalyzer.Helper.Instance.CmdletNameAndAliases(GetCmdletName()); // Iterrates all CommandAsts and check the command name. foreach (CommandAst cmdAst in commandAsts) diff --git a/Engine/Generic/AvoidParameterGeneric.cs b/Engine/Generic/AvoidParameterGeneric.cs index 2c140e39c..b61835056 100644 --- a/Engine/Generic/AvoidParameterGeneric.cs +++ b/Engine/Generic/AvoidParameterGeneric.cs @@ -12,12 +12,9 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Management.Automation.Language; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// Represents an abstract class for rule that checks that diff --git a/Engine/Generic/DiagnosticRecord.cs b/Engine/Generic/DiagnosticRecord.cs index bc2ada6dd..d62a5217c 100644 --- a/Engine/Generic/DiagnosticRecord.cs +++ b/Engine/Generic/DiagnosticRecord.cs @@ -10,14 +10,9 @@ // THE SOFTWARE. // -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Management.Automation.Language; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// Represents a result from a PSScriptAnalyzer rule. diff --git a/Engine/Generic/ExternalRule.cs b/Engine/Generic/ExternalRule.cs index c73792e28..b637ce166 100644 --- a/Engine/Generic/ExternalRule.cs +++ b/Engine/Generic/ExternalRule.cs @@ -10,13 +10,8 @@ // THE SOFTWARE. // -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { internal class ExternalRule : IExternalRule { diff --git a/Engine/Generic/IDSCResourceRule.cs b/Engine/Generic/IDSCResourceRule.cs index 935179b3a..cbb645fb2 100644 --- a/Engine/Generic/IDSCResourceRule.cs +++ b/Engine/Generic/IDSCResourceRule.cs @@ -13,7 +13,7 @@ using System.Collections.Generic; using System.Management.Automation.Language; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// Represents an interface for a DSC rule that analyzes a DSC resource diff --git a/Engine/Generic/IExternalRule.cs b/Engine/Generic/IExternalRule.cs index d51f33bea..935f7fdde 100644 --- a/Engine/Generic/IExternalRule.cs +++ b/Engine/Generic/IExternalRule.cs @@ -10,13 +10,8 @@ // THE SOFTWARE. // -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// Represents an interface for an external analyzer rule. diff --git a/Engine/Generic/ILogger.cs b/Engine/Generic/ILogger.cs index 5d51378a3..9f0adac0a 100644 --- a/Engine/Generic/ILogger.cs +++ b/Engine/Generic/ILogger.cs @@ -11,13 +11,9 @@ // using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Commands; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// ILogger: An interface for a PSScriptAnalyzer logger to output the results of PSScriptAnalyzer rules. diff --git a/Engine/Generic/IRule.cs b/Engine/Generic/IRule.cs index e9ddbbf8e..4ba707d7d 100644 --- a/Engine/Generic/IRule.cs +++ b/Engine/Generic/IRule.cs @@ -10,7 +10,7 @@ // THE SOFTWARE. // -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// An interface for an analyzer rule that analyzes the Ast. diff --git a/Engine/Generic/IScriptRule.cs b/Engine/Generic/IScriptRule.cs index c9993d266..15bafbe87 100644 --- a/Engine/Generic/IScriptRule.cs +++ b/Engine/Generic/IScriptRule.cs @@ -17,7 +17,7 @@ using System.Threading.Tasks; using System.Management.Automation.Language; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// Represents an interface for an analyzer rule that analyzes the Ast. diff --git a/Engine/Generic/ITokenRule.cs b/Engine/Generic/ITokenRule.cs index 2213f8d57..e4450d9aa 100644 --- a/Engine/Generic/ITokenRule.cs +++ b/Engine/Generic/ITokenRule.cs @@ -13,7 +13,7 @@ using System.Collections.Generic; using System.Management.Automation.Language; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// Represents an interface for an analyzer rule that analyzes the tokens of a script. diff --git a/Engine/Generic/LoggerInfo.cs b/Engine/Generic/LoggerInfo.cs index ebb9d72e9..c5d32bce8 100644 --- a/Engine/Generic/LoggerInfo.cs +++ b/Engine/Generic/LoggerInfo.cs @@ -10,14 +10,9 @@ // THE SOFTWARE. // -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Diagnostics.CodeAnalysis; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// Represents an internal class to properly display the name and description of a logger. diff --git a/Engine/Generic/RuleInfo.cs b/Engine/Generic/RuleInfo.cs index 666c84afa..8c90d5e6a 100644 --- a/Engine/Generic/RuleInfo.cs +++ b/Engine/Generic/RuleInfo.cs @@ -10,14 +10,9 @@ // THE SOFTWARE. // -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Diagnostics.CodeAnalysis; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// Represents an internal class to properly display the name and description of a rule. diff --git a/Engine/Generic/RuleSeverity.cs b/Engine/Generic/RuleSeverity.cs index 75496ed43..d975aa239 100644 --- a/Engine/Generic/RuleSeverity.cs +++ b/Engine/Generic/RuleSeverity.cs @@ -10,7 +10,7 @@ // THE SOFTWARE. // -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// Represents the severity of a PSScriptAnalyzer rule diff --git a/Engine/Generic/RuleSuppression.cs b/Engine/Generic/RuleSuppression.cs index 93319a254..a90f1b88c 100644 --- a/Engine/Generic/RuleSuppression.cs +++ b/Engine/Generic/RuleSuppression.cs @@ -17,7 +17,7 @@ using System.Text.RegularExpressions; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// diff --git a/Engine/Generic/SkipNamedBlock.cs b/Engine/Generic/SkipNamedBlock.cs index 448c668f5..6de4dd094 100644 --- a/Engine/Generic/SkipNamedBlock.cs +++ b/Engine/Generic/SkipNamedBlock.cs @@ -13,11 +13,9 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Management.Automation.Language; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// This class extends AstVisitor2 and will skip any namedblockast and commandast diff --git a/Engine/Generic/SkipTypeDefinition.cs b/Engine/Generic/SkipTypeDefinition.cs index c95d772fe..4f6ad239d 100644 --- a/Engine/Generic/SkipTypeDefinition.cs +++ b/Engine/Generic/SkipTypeDefinition.cs @@ -13,7 +13,7 @@ using System.Collections.Generic; using System.Management.Automation.Language; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// This class extends AstVisitor and will skip any typedefinitionast diff --git a/Engine/Generic/SourceType.cs b/Engine/Generic/SourceType.cs index bab7cd0e3..dfff87f2a 100644 --- a/Engine/Generic/SourceType.cs +++ b/Engine/Generic/SourceType.cs @@ -10,13 +10,7 @@ // THE SOFTWARE. // -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// Represents a source name of a script analyzer rule. diff --git a/Engine/Generic/SuppressedRecord.cs b/Engine/Generic/SuppressedRecord.cs index 11fbefcfd..8a096087e 100644 --- a/Engine/Generic/SuppressedRecord.cs +++ b/Engine/Generic/SuppressedRecord.cs @@ -1,10 +1,16 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { /// /// Represents a suppressed diagnostic record diff --git a/Engine/Helper.cs b/Engine/Helper.cs index 2f334241d..94bc8b871 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -16,11 +16,10 @@ using System.Linq; using System.Management.Automation; using System.Management.Automation.Language; -using System.Management.Automation.Runspaces; using System.Globalization; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer { /// diff --git a/Engine/Loggers/WriteObjectsLogger.cs b/Engine/Loggers/WriteObjectsLogger.cs index 3b7829f3f..1ca5d7703 100644 --- a/Engine/Loggers/WriteObjectsLogger.cs +++ b/Engine/Loggers/WriteObjectsLogger.cs @@ -11,19 +11,15 @@ // using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Commands; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands; using System.ComponentModel.Composition; using System.Globalization; using System.Reflection; using System.Resources; using System.Threading; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Loggers +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Loggers { /// /// WriteObjectsLogger: Logs Diagnostics though WriteObject. @@ -34,7 +30,7 @@ public class WriteObjectsLogger : ILogger #region Private members private CultureInfo cul = Thread.CurrentThread.CurrentCulture; - private ResourceManager rm = new ResourceManager("Microsoft.Windows.Powershell.ScriptAnalyzer.Strings", + private ResourceManager rm = new ResourceManager("Microsoft.Windows.PowerShell.ScriptAnalyzer.Strings", Assembly.GetExecutingAssembly()); #endregion diff --git a/Engine/ScriptAnalyzer.cs b/Engine/ScriptAnalyzer.cs index 715575a6e..24c2d0152 100644 --- a/Engine/ScriptAnalyzer.cs +++ b/Engine/ScriptAnalyzer.cs @@ -11,8 +11,8 @@ // using System.Text.RegularExpressions; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Commands; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System; using System.Collections.Generic; using System.ComponentModel.Composition; @@ -23,11 +23,9 @@ using System.Management.Automation.Language; using System.Management.Automation.Runspaces; using System.Reflection; -using System.Resources; using System.Globalization; -using System.Threading; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer { internal class ScriptAnalyzer { diff --git a/Engine/ScriptAnalyzerEngine.csproj b/Engine/ScriptAnalyzerEngine.csproj index c259d0ea9..06f02c73e 100644 --- a/Engine/ScriptAnalyzerEngine.csproj +++ b/Engine/ScriptAnalyzerEngine.csproj @@ -6,7 +6,7 @@ {F4BDE3D0-3EEF-4157-8A3E-722DF7ADEF60} Library false - Microsoft.Windows.Powershell.ScriptAnalyzer + Microsoft.Windows.PowerShell.ScriptAnalyzer v4.5 512 @@ -31,7 +31,7 @@ false - Microsoft.Windows.Powershell.ScriptAnalyzer + Microsoft.Windows.PowerShell.ScriptAnalyzer diff --git a/Engine/SpecialVars.cs b/Engine/SpecialVars.cs index f616234cc..6c41f57fb 100644 --- a/Engine/SpecialVars.cs +++ b/Engine/SpecialVars.cs @@ -11,16 +11,11 @@ // using System; -using System.Collections; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Concurrent; using System.Linq; -using System.Reflection; -using System.Management.Automation.Language; using System.Management.Automation; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer { internal class SpecialVars { diff --git a/Engine/Strings.Designer.cs b/Engine/Strings.Designer.cs index 41b4079d7..74cebd11d 100644 --- a/Engine/Strings.Designer.cs +++ b/Engine/Strings.Designer.cs @@ -1,16 +1,14 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.35317 // -// Copyright (c) Microsoft Corporation. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ -namespace Microsoft.Windows.Powershell.ScriptAnalyzer { +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer { using System; @@ -41,7 +39,7 @@ internal Strings() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Windows.Powershell.ScriptAnalyzer.Strings", typeof(Strings).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Windows.PowerShell.ScriptAnalyzer.Strings", typeof(Strings).Assembly); resourceMan = temp; } return resourceMan; diff --git a/Engine/VariableAnalysis.cs b/Engine/VariableAnalysis.cs index 7c29c170f..314457ec3 100644 --- a/Engine/VariableAnalysis.cs +++ b/Engine/VariableAnalysis.cs @@ -11,18 +11,12 @@ // using System; -using System.Collections; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Concurrent; using System.Linq; -using System.Reflection; using System.Management.Automation.Language; -using System.Management.Automation; using System.Globalization; -using System.Text.RegularExpressions; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer { /// /// This class is used to analyze variable based on data flow diff --git a/Engine/VariableAnalysisBase.cs b/Engine/VariableAnalysisBase.cs index 17e7cc6c8..272699471 100644 --- a/Engine/VariableAnalysisBase.cs +++ b/Engine/VariableAnalysisBase.cs @@ -14,14 +14,13 @@ using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Collections.Concurrent; using System.Linq; using System.Reflection; using System.Management.Automation.Language; using System.Management.Automation; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer { /// /// Base class for variable details diff --git a/Rules/AvoidAlias.cs b/Rules/AvoidAlias.cs index dba65dfd0..5e9626923 100644 --- a/Rules/AvoidAlias.cs +++ b/Rules/AvoidAlias.cs @@ -13,11 +13,11 @@ using System; using System.Collections.Generic; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidAlias: Check if cmdlet alias is used. @@ -45,7 +45,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) // MSDN: CommandAst.GetCommandName Method if (aliasName == null) continue; - string cmdletName = Microsoft.Windows.Powershell.ScriptAnalyzer.Helper.Instance.GetCmdletNameFromAlias(aliasName); + string cmdletName = Microsoft.Windows.PowerShell.ScriptAnalyzer.Helper.Instance.GetCmdletNameFromAlias(aliasName); if (!String.IsNullOrEmpty(cmdletName)) { diff --git a/Rules/AvoidDefaultTrueValueSwitchParameter.cs b/Rules/AvoidDefaultTrueValueSwitchParameter.cs index 2572a1fb9..a2f892571 100644 --- a/Rules/AvoidDefaultTrueValueSwitchParameter.cs +++ b/Rules/AvoidDefaultTrueValueSwitchParameter.cs @@ -14,11 +14,11 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidDefaultTrueValueSwitchParameter: Check that switch parameter does not default to true. diff --git a/Rules/AvoidEmptyCatchBlock.cs b/Rules/AvoidEmptyCatchBlock.cs index 1c9c57b76..6ee312d76 100644 --- a/Rules/AvoidEmptyCatchBlock.cs +++ b/Rules/AvoidEmptyCatchBlock.cs @@ -13,11 +13,11 @@ using System; using System.Collections.Generic; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidEmptyCatchBlock: Check if any empty catch block is used. diff --git a/Rules/AvoidGlobalVars.cs b/Rules/AvoidGlobalVars.cs index 109da5ee5..4850ff5d6 100644 --- a/Rules/AvoidGlobalVars.cs +++ b/Rules/AvoidGlobalVars.cs @@ -13,11 +13,11 @@ using System; using System.Collections.Generic; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidGlobalVars: Analyzes the ast to check that global variables are not used. diff --git a/Rules/AvoidInvokingEmptyMembers.cs b/Rules/AvoidInvokingEmptyMembers.cs index 562f335fd..df30c3451 100644 --- a/Rules/AvoidInvokingEmptyMembers.cs +++ b/Rules/AvoidInvokingEmptyMembers.cs @@ -14,11 +14,11 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidAlias: Check if cmdlet alias is used. diff --git a/Rules/AvoidPositionalParameters.cs b/Rules/AvoidPositionalParameters.cs index 3a644275f..248dc4f71 100644 --- a/Rules/AvoidPositionalParameters.cs +++ b/Rules/AvoidPositionalParameters.cs @@ -13,11 +13,11 @@ using System; using System.Collections.Generic; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidPositionalParameters: Check to make sure that positional parameters are not used. diff --git a/Rules/AvoidReservedCharInCmdlet.cs b/Rules/AvoidReservedCharInCmdlet.cs index 9f4637a3a..2dddfbe3c 100644 --- a/Rules/AvoidReservedCharInCmdlet.cs +++ b/Rules/AvoidReservedCharInCmdlet.cs @@ -13,13 +13,12 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Management.Automation; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// diff --git a/Rules/AvoidReservedParams.cs b/Rules/AvoidReservedParams.cs index b0211f4f9..da1077a78 100644 --- a/Rules/AvoidReservedParams.cs +++ b/Rules/AvoidReservedParams.cs @@ -14,13 +14,13 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; using System.Management.Automation; using System.Management.Automation.Internal; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidReservedParams: Analyzes the ast to check for reserved parameters in function definitions. diff --git a/Rules/AvoidShouldContinueWithoutForce.cs b/Rules/AvoidShouldContinueWithoutForce.cs index ca91b62b0..0222200e9 100644 --- a/Rules/AvoidShouldContinueWithoutForce.cs +++ b/Rules/AvoidShouldContinueWithoutForce.cs @@ -13,11 +13,11 @@ using System; using System.Collections.Generic; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidShouldContinueWithoutForceParameter: Check that if ShouldContinue is used, diff --git a/Rules/AvoidTrapStatement.cs b/Rules/AvoidTrapStatement.cs deleted file mode 100644 index 0dc9b43b1..000000000 --- a/Rules/AvoidTrapStatement.cs +++ /dev/null @@ -1,101 +0,0 @@ -// -// Copyright (c) Microsoft Corporation. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; -using System.ComponentModel.Composition; -using System.Globalization; - -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules -{ - /// - /// AvoidTrapStatement: Analyzes the ast to check that no traps are used. - /// - [Export(typeof(IScriptRule))] - public class AvoidTrapStatement : IScriptRule - { - /// - /// AnalyzeScript: Analyzes the ast to check that no traps are used. - /// - /// The script's ast - /// The script's file name - /// A List of diagnostic results of this rule - public IEnumerable AnalyzeScript(Ast ast, string fileName) - { - if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage); - - IEnumerable trapAsts = ast.FindAll(testAst => testAst is TrapStatementAst, true); - - if (trapAsts != null) - { - foreach (Ast trapAst in trapAsts) - { - yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidTrapStatementError), trapAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName); - } - } - } - - /// - /// GetName: Retrieves the name of this rule. - /// - /// The name of this rule - public string GetName() - { - return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.AvoidTrapStatementName); - } - - /// - /// GetCommonName: Retrieves the common name of this rule. - /// - /// The common name of this rule - public string GetCommonName() - { - return string.Format(CultureInfo.CurrentCulture, Strings.AvoidTrapStatementCommonName); - } - - /// - /// GetDescription: Retrieves the description of this rule. - /// - /// The description of this rule - public string GetDescription() - { - return string.Format(CultureInfo.CurrentCulture, Strings.AvoidTrapStatementDescription); - } - - /// - /// GetSourceType: Retrieves the type of the rule: builtin, managed or module. - /// - public SourceType GetSourceType() - { - return SourceType.Builtin; - } - - /// - /// GetSeverity: Retrieves the severity of the rule: error, warning of information. - /// - /// - public RuleSeverity GetSeverity() - { - return RuleSeverity.Warning; - } - - /// - /// GetSourceName: Retrieves the module/assembly name the rule is from. - /// - public string GetSourceName() - { - return string.Format(CultureInfo.CurrentCulture, Strings.SourceName); - } - } -} diff --git a/Rules/AvoidUninitializedVariable.cs b/Rules/AvoidUninitializedVariable.cs index 2872f0e56..6c13950ca 100644 --- a/Rules/AvoidUninitializedVariable.cs +++ b/Rules/AvoidUninitializedVariable.cs @@ -14,11 +14,11 @@ using System.Linq; using System.Collections.Generic; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidUnitializedVariable: Check if any uninitialized variable is used. diff --git a/Rules/AvoidUserNameAndPasswordParams.cs b/Rules/AvoidUserNameAndPasswordParams.cs index a593b1ae7..823ca6e3c 100644 --- a/Rules/AvoidUserNameAndPasswordParams.cs +++ b/Rules/AvoidUserNameAndPasswordParams.cs @@ -14,12 +14,12 @@ using System.Collections.Generic; using System.Management.Automation; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; using System.Reflection; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidUsernameAndPasswordParams: Check that a function does not use both username and password diff --git a/Rules/AvoidUsingComputerNameHardcoded.cs b/Rules/AvoidUsingComputerNameHardcoded.cs index dab94246a..f0454d412 100644 --- a/Rules/AvoidUsingComputerNameHardcoded.cs +++ b/Rules/AvoidUsingComputerNameHardcoded.cs @@ -12,11 +12,11 @@ using System; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidUsingComputerNameHardcoded: Check that parameter ComputerName is not hardcoded. diff --git a/Rules/AvoidUsingConvertToSecureStringWithPlainText.cs b/Rules/AvoidUsingConvertToSecureStringWithPlainText.cs index 090dcb059..d9105235a 100644 --- a/Rules/AvoidUsingConvertToSecureStringWithPlainText.cs +++ b/Rules/AvoidUsingConvertToSecureStringWithPlainText.cs @@ -14,11 +14,11 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidUsingConvertToSecureStringWithPlainText: Check that convertto-securestring does not use plaintext. diff --git a/Rules/AvoidUsingInternalURLs.cs b/Rules/AvoidUsingInternalURLs.cs index 42f1692f8..99844de4f 100644 --- a/Rules/AvoidUsingInternalURLs.cs +++ b/Rules/AvoidUsingInternalURLs.cs @@ -14,12 +14,12 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; using System.IO; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidUsingInternalURLs: Check if a URL is potentially an internal URL, diff --git a/Rules/AvoidUsingInvokeExpression.cs b/Rules/AvoidUsingInvokeExpression.cs index 81db6dc7a..597383495 100644 --- a/Rules/AvoidUsingInvokeExpression.cs +++ b/Rules/AvoidUsingInvokeExpression.cs @@ -11,11 +11,11 @@ // using System; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// InvokeExpressionRule: Check to make sure that Invoke-Expression is not used. diff --git a/Rules/AvoidUsingPlainTextForPassword.cs b/Rules/AvoidUsingPlainTextForPassword.cs index 9cc2e1171..4e6366bff 100644 --- a/Rules/AvoidUsingPlainTextForPassword.cs +++ b/Rules/AvoidUsingPlainTextForPassword.cs @@ -13,12 +13,12 @@ using System; using System.Collections.Generic; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; using System.Reflection; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidUsingPlainTextForPassword: Check that parameter "password", "passphrase" do not use plaintext diff --git a/Rules/AvoidUsingWMICmdlet.cs b/Rules/AvoidUsingWMICmdlet.cs index 079f0ec14..d5104a298 100644 --- a/Rules/AvoidUsingWMICmdlet.cs +++ b/Rules/AvoidUsingWMICmdlet.cs @@ -11,21 +11,13 @@ // using System; -using System.Collections.ObjectModel; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Management.Automation; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; -using System.Resources; using System.Globalization; -using System.Threading; -using System.Reflection; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidUsingWMICmdlet: Avoid Using Get-WMIObject, Remove-WMIObject, Invoke-WmiMethod, Register-WmiEvent, Set-WmiInstance diff --git a/Rules/AvoidUsingWriteHost.cs b/Rules/AvoidUsingWriteHost.cs index fcc06a38b..e2339cb75 100644 --- a/Rules/AvoidUsingWriteHost.cs +++ b/Rules/AvoidUsingWriteHost.cs @@ -13,11 +13,11 @@ using System; using System.Collections.Generic; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// AvoidUsingWriteHost: Check that Write-Host or Console.Write are not used diff --git a/Rules/DscExamplesPresent.cs b/Rules/DscExamplesPresent.cs index 4d3129c4c..e0f9b53a1 100644 --- a/Rules/DscExamplesPresent.cs +++ b/Rules/DscExamplesPresent.cs @@ -14,13 +14,12 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; using System.IO; -using System.Management.Automation; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// DscExamplesPresent: Checks that DSC examples for given resource are present. diff --git a/Rules/DscTestsPresent.cs b/Rules/DscTestsPresent.cs index 15fbbda23..9a25ece36 100644 --- a/Rules/DscTestsPresent.cs +++ b/Rules/DscTestsPresent.cs @@ -14,13 +14,12 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; using System.IO; -using System.Management.Automation; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// DscTestsPresent: Checks that DSC tests for given resource are present. diff --git a/Rules/MissingModuleManifestField.cs b/Rules/MissingModuleManifestField.cs index 012c18069..9b0dd5954 100644 --- a/Rules/MissingModuleManifestField.cs +++ b/Rules/MissingModuleManifestField.cs @@ -12,14 +12,13 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Management.Automation.Language; using System.Management.Automation; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// MissingModuleManifestField: Run Test Module Manifest to check that none of the required fields are missing. diff --git a/Rules/PossibleIncorrectComparisonWithNull.cs b/Rules/PossibleIncorrectComparisonWithNull.cs index 507832322..da97c13f6 100644 --- a/Rules/PossibleIncorrectComparisonWithNull.cs +++ b/Rules/PossibleIncorrectComparisonWithNull.cs @@ -13,11 +13,11 @@ using System; using System.Collections.Generic; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// NullComparisonRule: Analyzes the ast to check that $null is on the left side of any equality comparisons. diff --git a/Rules/ProvideCommentHelp.cs b/Rules/ProvideCommentHelp.cs index fbb03b2b9..d98aa26aa 100644 --- a/Rules/ProvideCommentHelp.cs +++ b/Rules/ProvideCommentHelp.cs @@ -14,12 +14,12 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; using System.Management.Automation; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// ProvideCommentHelp: Analyzes ast to check that cmdlets have help. diff --git a/Rules/ProvideVerboseMessage.cs b/Rules/ProvideVerboseMessage.cs index fb4b3f15b..b3d191b56 100644 --- a/Rules/ProvideVerboseMessage.cs +++ b/Rules/ProvideVerboseMessage.cs @@ -14,12 +14,12 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; using System.Management.Automation; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// ProvideVerboseMessage: Analyzes the ast to check that Write-Verbose is called at least once in every cmdlet or script. diff --git a/Rules/ReturnCorrectTypesForDSCFunctions.cs b/Rules/ReturnCorrectTypesForDSCFunctions.cs index 90aeeeabc..127f12d6e 100644 --- a/Rules/ReturnCorrectTypesForDSCFunctions.cs +++ b/Rules/ReturnCorrectTypesForDSCFunctions.cs @@ -14,11 +14,11 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// ReturnCorrectTypeDSCFunctions: Check that DSC functions return the correct type. diff --git a/Rules/ScriptAnalyzerBuiltinRules.csproj b/Rules/ScriptAnalyzerBuiltinRules.csproj index 7401ac269..5f76f89c5 100644 --- a/Rules/ScriptAnalyzerBuiltinRules.csproj +++ b/Rules/ScriptAnalyzerBuiltinRules.csproj @@ -6,7 +6,7 @@ {C33B6B9D-E61C-45A3-9103-895FD82A5C1E} Library false - Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules + Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules v4.5 512 @@ -31,7 +31,7 @@ false - Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules + Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules @@ -58,7 +58,6 @@ - diff --git a/Rules/Strings.Designer.cs b/Rules/Strings.Designer.cs index 641440213..1ecf2b426 100644 --- a/Rules/Strings.Designer.cs +++ b/Rules/Strings.Designer.cs @@ -1,14 +1,14 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34014 +// Runtime Version:4.0.30319.35317 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules { +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { using System; @@ -39,7 +39,7 @@ internal Strings() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules.Strings", typeof(Strings).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules.Strings", typeof(Strings).Assembly); resourceMan = temp; } return resourceMan; diff --git a/Rules/UseApprovedVerbs.cs b/Rules/UseApprovedVerbs.cs index 833bf4f03..4a5ae083b 100644 --- a/Rules/UseApprovedVerbs.cs +++ b/Rules/UseApprovedVerbs.cs @@ -15,12 +15,12 @@ using System.Linq; using System.Management.Automation; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; using System.Reflection; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// UseApprovedVerbs: Analyzes scripts to check that all defined functions use approved verbs. diff --git a/Rules/UseCmdletCorrectly.cs b/Rules/UseCmdletCorrectly.cs index a5e854b0b..430e9a2d4 100644 --- a/Rules/UseCmdletCorrectly.cs +++ b/Rules/UseCmdletCorrectly.cs @@ -15,11 +15,11 @@ using System.Linq; using System.Management.Automation; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// Use CmdletCorrectly: Check that cmdlets are invoked with the correct mandatory parameter diff --git a/Rules/UseDeclaredVarsMoreThanAssignments.cs b/Rules/UseDeclaredVarsMoreThanAssignments.cs index b1b893497..1f1ecf089 100644 --- a/Rules/UseDeclaredVarsMoreThanAssignments.cs +++ b/Rules/UseDeclaredVarsMoreThanAssignments.cs @@ -13,11 +13,11 @@ using System; using System.Collections.Generic; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// ExtraVarsRule: Analyzes the ast to check that variables are used in more than just their assignment. diff --git a/Rules/UseIdenticalMandatoryParametersDSC.cs b/Rules/UseIdenticalMandatoryParametersDSC.cs index b2aaa3c16..f43c6f6c3 100644 --- a/Rules/UseIdenticalMandatoryParametersDSC.cs +++ b/Rules/UseIdenticalMandatoryParametersDSC.cs @@ -14,11 +14,11 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// UseIdenticalMandatoryParametersDSC: Check that the Get/Test/Set TargetResource diff --git a/Rules/UseIdenticalParametersDSC.cs b/Rules/UseIdenticalParametersDSC.cs index 8318c6155..99b9fac5e 100644 --- a/Rules/UseIdenticalParametersDSC.cs +++ b/Rules/UseIdenticalParametersDSC.cs @@ -14,11 +14,11 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// UseIdenticalParametersDSC: Check that the Test-TargetResource and diff --git a/Rules/UseOutputTypeCorrectly.cs b/Rules/UseOutputTypeCorrectly.cs index 5d04de225..a41c3a23c 100644 --- a/Rules/UseOutputTypeCorrectly.cs +++ b/Rules/UseOutputTypeCorrectly.cs @@ -14,12 +14,12 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; using System.Management.Automation; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// ProvideCommentHelp: Checks that objects return in a cmdlet have their types declared in OutputType Attribute diff --git a/Rules/UsePSCredentialType.cs b/Rules/UsePSCredentialType.cs index a932686d4..99ddbd70f 100644 --- a/Rules/UsePSCredentialType.cs +++ b/Rules/UsePSCredentialType.cs @@ -14,11 +14,11 @@ using System.Collections.Generic; using System.Management.Automation; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// diff --git a/Rules/UseShouldProcessCorrectly.cs b/Rules/UseShouldProcessCorrectly.cs index de40351cc..fef838fd0 100644 --- a/Rules/UseShouldProcessCorrectly.cs +++ b/Rules/UseShouldProcessCorrectly.cs @@ -13,11 +13,11 @@ using System; using System.Collections.Generic; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// UseShouldProcessCorrectly: Analyzes the ast to check that if the ShouldProcess attribute is present, the function calls ShouldProcess and vice versa. diff --git a/Rules/UseShouldProcessForStateChangingFunctions.cs b/Rules/UseShouldProcessForStateChangingFunctions.cs index 28c50aca4..c4fcf8449 100644 --- a/Rules/UseShouldProcessForStateChangingFunctions.cs +++ b/Rules/UseShouldProcessForStateChangingFunctions.cs @@ -15,11 +15,11 @@ using System.Linq; using System.Management.Automation; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules {/// /// UseShouldProcessCorrectly: Analyzes the ast to check that if the ShouldProcess attribute is present, the function calls ShouldProcess and vice versa. /// diff --git a/Rules/UseSingularNouns.cs b/Rules/UseSingularNouns.cs index 89d7d3095..78ecf16fd 100644 --- a/Rules/UseSingularNouns.cs +++ b/Rules/UseSingularNouns.cs @@ -13,13 +13,12 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Management.Automation; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// CmdletSingularNoun: Analyzes scripts to check that all defined cmdlets use singular nouns. diff --git a/Rules/UseStandardDSCFunctionsInResource.cs b/Rules/UseStandardDSCFunctionsInResource.cs index 67e9728df..d8091eacb 100644 --- a/Rules/UseStandardDSCFunctionsInResource.cs +++ b/Rules/UseStandardDSCFunctionsInResource.cs @@ -14,11 +14,11 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; using System.ComponentModel.Composition; using System.Globalization; -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules { /// /// UseStandardDSCFunctionsInResource: From f6f07e9a10b4d42269163aeffd60e6176c60e65c Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Tue, 26 May 2015 16:43:26 -0700 Subject: [PATCH 23/29] More changes to Powershell namespace --- Engine/PSScriptAnalyzer.psd1 | 2 +- Engine/ScriptAnalyzer.format.ps1xml | 6 +++--- Engine/ScriptAnalyzer.types.ps1xml | 6 +++--- Rules/Strings.Designer.cs | 2 +- Rules/Strings.resx | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Engine/PSScriptAnalyzer.psd1 b/Engine/PSScriptAnalyzer.psd1 index bfa38cf53..2057d6ca3 100644 --- a/Engine/PSScriptAnalyzer.psd1 +++ b/Engine/PSScriptAnalyzer.psd1 @@ -8,7 +8,7 @@ Author = 'Microsoft Corporation' # Script module or binary module file associated with this manifest. -RootModule = 'Microsoft.Windows.Powershell.ScriptAnalyzer.dll' +RootModule = 'Microsoft.Windows.PowerShell.ScriptAnalyzer.dll' # Version number of this module. ModuleVersion = '1.0.1' diff --git a/Engine/ScriptAnalyzer.format.ps1xml b/Engine/ScriptAnalyzer.format.ps1xml index 9839d5eac..be7ef3ab0 100644 --- a/Engine/ScriptAnalyzer.format.ps1xml +++ b/Engine/ScriptAnalyzer.format.ps1xml @@ -4,7 +4,7 @@ PSScriptAnalyzerView - Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord + Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord @@ -57,7 +57,7 @@ PSScriptAnalyzerView - Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.SuppressedRecord + Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.SuppressedRecord @@ -110,7 +110,7 @@ ScriptAnalyzerRules - Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.RuleInfo + Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.RuleInfo diff --git a/Engine/ScriptAnalyzer.types.ps1xml b/Engine/ScriptAnalyzer.types.ps1xml index ea37859ab..da989657e 100644 --- a/Engine/ScriptAnalyzer.types.ps1xml +++ b/Engine/ScriptAnalyzer.types.ps1xml @@ -1,7 +1,7 @@  - Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord + Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord Line @@ -33,7 +33,7 @@ - Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.SuppressedRecord + Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.SuppressedRecord Line @@ -71,7 +71,7 @@ - Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.RuleInfo + Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.RuleInfo PSStandardMembers diff --git a/Rules/Strings.Designer.cs b/Rules/Strings.Designer.cs index 1ecf2b426..a748b432d 100644 --- a/Rules/Strings.Designer.cs +++ b/Rules/Strings.Designer.cs @@ -331,7 +331,7 @@ internal static string AvoidUnloadableModuleCommonName { } /// - /// Looks up a localized string similar to If a script file is in a Powershell module folder, then that folder must be loadable.. + /// Looks up a localized string similar to If a script file is in a PowerShell module folder, then that folder must be loadable.. /// internal static string AvoidUnloadableModuleDescription { get { diff --git a/Rules/Strings.resx b/Rules/Strings.resx index b26e4d6fa..833279fcc 100644 --- a/Rules/Strings.resx +++ b/Rules/Strings.resx @@ -295,7 +295,7 @@ Module Manifest Fields - If a script file is in a Powershell module folder, then that folder must be loadable. + If a script file is in a PowerShell module folder, then that folder must be loadable. Cannot load the module '{0}' that file '{1}' is in. From 2aaa17e71200e4ecce32d2f073b463c60700b2ef Mon Sep 17 00:00:00 2001 From: Yuting Chen Date: Tue, 26 May 2015 16:57:37 -0700 Subject: [PATCH 24/29] Move tests of TrapStatement to DisabledRules folder --- Tests/{Rules => Disabled Rules}/AvoidTrapStatements.ps1 | 0 Tests/{Rules => Disabled Rules}/AvoidTrapStatements.tests.ps1 | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Tests/{Rules => Disabled Rules}/AvoidTrapStatements.ps1 (100%) rename Tests/{Rules => Disabled Rules}/AvoidTrapStatements.tests.ps1 (100%) diff --git a/Tests/Rules/AvoidTrapStatements.ps1 b/Tests/Disabled Rules/AvoidTrapStatements.ps1 similarity index 100% rename from Tests/Rules/AvoidTrapStatements.ps1 rename to Tests/Disabled Rules/AvoidTrapStatements.ps1 diff --git a/Tests/Rules/AvoidTrapStatements.tests.ps1 b/Tests/Disabled Rules/AvoidTrapStatements.tests.ps1 similarity index 100% rename from Tests/Rules/AvoidTrapStatements.tests.ps1 rename to Tests/Disabled Rules/AvoidTrapStatements.tests.ps1 From 8a71a974811f3ee6efb2bb26c6dbee4f3a6cd82e Mon Sep 17 00:00:00 2001 From: Quoc Truong Date: Fri, 29 May 2015 11:06:34 -0700 Subject: [PATCH 25/29] Fix parameters missing in a conditional statement of the rule --- Rules/AvoidUsingPlainTextForPassword.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Rules/AvoidUsingPlainTextForPassword.cs b/Rules/AvoidUsingPlainTextForPassword.cs index 4e6366bff..4a69c6812 100644 --- a/Rules/AvoidUsingPlainTextForPassword.cs +++ b/Rules/AvoidUsingPlainTextForPassword.cs @@ -55,8 +55,8 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) } } - if (hasPwd && (!paramType.IsArray && (paramType == typeof(String) || paramType == typeof(object))) - || (paramType.IsArray && (paramType.GetElementType() == typeof(String) || paramType.GetElementType() == typeof(object)))) + if (hasPwd && ((!paramType.IsArray && (paramType == typeof(String) || paramType == typeof(object))) + || (paramType.IsArray && (paramType.GetElementType() == typeof(String) || paramType.GetElementType() == typeof(object))))) { yield return new DiagnosticRecord( String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingPlainTextForPasswordError, paramAst.Name), From 5a5846440f3df2396be85e6ca5200aa15b787e11 Mon Sep 17 00:00:00 2001 From: Quoc Truong Date: Fri, 29 May 2015 11:32:05 -0700 Subject: [PATCH 26/29] Add test --- Tests/Rules/AvoidUsingPlainTextForPasswordNoViolations.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Tests/Rules/AvoidUsingPlainTextForPasswordNoViolations.ps1 b/Tests/Rules/AvoidUsingPlainTextForPasswordNoViolations.ps1 index 3203dc0f4..0de5015ac 100644 --- a/Tests/Rules/AvoidUsingPlainTextForPasswordNoViolations.ps1 +++ b/Tests/Rules/AvoidUsingPlainTextForPasswordNoViolations.ps1 @@ -26,7 +26,9 @@ [securestring] $passwordparam, [string] - $PassThru + $PassThru, + [string[]] + $shouldnotraiseerror ) Begin From 24d451557fca1cc215a3a4950ba098bf10528008 Mon Sep 17 00:00:00 2001 From: Quoc Truong Date: Fri, 29 May 2015 13:27:57 -0700 Subject: [PATCH 27/29] Fix a bug in the flow graphs for throw statements --- Engine/VariableAnalysisBase.cs | 127 +++++++++++++----- ...oidGlobalOrUnitializedVarsNoViolations.ps1 | 19 ++- 2 files changed, 110 insertions(+), 36 deletions(-) diff --git a/Engine/VariableAnalysisBase.cs b/Engine/VariableAnalysisBase.cs index 272699471..f1d40ca66 100644 --- a/Engine/VariableAnalysisBase.cs +++ b/Engine/VariableAnalysisBase.cs @@ -405,15 +405,36 @@ public class Block internal bool _returns; internal bool _unreachable; + // Only Entry block, that can be constructed via NewEntryBlock() is reachable initially. + // all other blocks are unreachable. + // reachability of block should be proved with FlowsTo() calls. + public Block() + { + this._unreachable = true; + } + + public static Block NewEntryBlock() + { + return new Block(unreachable: false); + } + + private Block(bool unreachable) + { + this._unreachable = unreachable; + } + + /// + /// Tell flow analysis that this block can flow to next block. + /// + /// internal void FlowsTo(Block next) { if (_successors.IndexOf(next) < 0) { - if (_unreachable) + if (!_unreachable) { - next._unreachable = true; + next._unreachable = false; } - _successors.Add(next); next._predecessors.Add(this); } @@ -725,6 +746,25 @@ internal static void RenameVariables(Block block) internal static void InitializeSSA(Dictionary VariableAnalysis, Block Entry, List Blocks) { VariablesDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach (var block in Blocks) + { + List _unreachables = new List(); + foreach (var pred in block._predecessors) + { + if (pred._unreachable) + { + _unreachables.Add(pred); + pred._successors.Remove(block); + } + } + + foreach (var pred in _unreachables) + { + block._predecessors.Remove(pred); + } + } + InternalVariablesDictionary.Clear(); SSADictionary.Clear(); Counters.Clear(); @@ -1877,7 +1917,7 @@ public Block Exit /// public void Init() { - _entryBlock = new Block(); + _entryBlock = Block.NewEntryBlock(); _exitBlock = new Block(); } @@ -2057,6 +2097,13 @@ public object VisitIfStatement(IfStatementAst ifStmtAst) if (ifStmtAst == null) return null; Block afterStmt = new Block(); + + if (ifStmtAst.ElseClause == null) + { + // There is no else, flow can go straight to afterStmt. + _currentBlock.FlowsTo(afterStmt); + } + int clauseCount = ifStmtAst.Clauses.Count; for (int i = 0; i < clauseCount; i++) { @@ -2403,52 +2450,62 @@ public object VisitTryStatement(TryStatementAst tryStatementAst) tryStatementAst.Body.Visit(this.Decorator); - // This is either the first block in the finally, or the first block after all the catches if there is no finally. - // For return analysis, we start off assuming this block is reachable only if the end of the try body - // is reachable, but that can change if we find a catch that falls through. - var afterTry = new Block { _unreachable = _currentBlock._unreachable }; + Block lastBlockInTry = _currentBlock; + var finallyFirstBlock = tryStatementAst.Finally == null ? null : new Block(); + Block finallyLastBlock = null; + + // This is the first block after all the catches and finally (if present). + var afterTry = new Block(); + + bool isCatchAllPresent = false; foreach (var catchAst in tryStatementAst.CatchClauses) { + if (catchAst.IsCatchAll) + { + isCatchAllPresent = true; + } + // Any statement in the try block could throw and reach the catch, so assume the worst (from a data // flow perspective) and make the predecessor to the catch the block before entering the try. _currentBlock = new Block(); blockBeforeTry.FlowsTo(_currentBlock); - catchAst.Visit(this.Decorator); - - if (!_currentBlock._unreachable) - { - // The last block of the catch falls through, so we can get reach blocks after the try. - afterTry._unreachable = false; - } + _currentBlock.FlowsTo(finallyFirstBlock ?? afterTry); } - // Assume nothing in the try was executed, so flow comes from before the try. We could have the catch blocks - // also flow to this block, but that won't improve the analysis any, so skip that. - _currentBlock = afterTry; - blockBeforeTry.FlowsTo(_currentBlock); - - if (tryStatementAst.Finally != null) + if (finallyFirstBlock != null) { + lastBlockInTry.FlowsTo(finallyFirstBlock); + + _currentBlock = finallyFirstBlock; tryStatementAst.Finally.Visit(this.Decorator); + _currentBlock.FlowsTo(afterTry); + + finallyLastBlock = _currentBlock; - if (!_currentBlock._unreachable) + // For finally block, there are 2 cases: when try-body throw and when it doesn't. + // For these two cases value of 'finallyLastBlock._throws' would be different. + if (!isCatchAllPresent) { - // If the finally throws (it can't have other flow like return, break, or continue) - // then after the try/catch/finally is unreachable, otherwise it is reachable. - afterTry._unreachable = false; + // This flow exist only, if there is no catch for all exceptions. + blockBeforeTry.FlowsTo(finallyFirstBlock); + + var rethrowAfterFinallyBlock = new Block(); + finallyLastBlock.FlowsTo(rethrowAfterFinallyBlock); + rethrowAfterFinallyBlock._throws = true; + rethrowAfterFinallyBlock.FlowsTo(_exitBlock); } - // We can assume that flow from the finally reaches the code following the finally. Of course, if an exception occurs, - // then the code can't be reached, but our conservative data flow modeling assures us correctness, the exception will - // either leave the current function (meaning it doesn't matter that we assumed flow reached after the finally), or - // it will be caught and handled by a containing catch, and our conversative data flow ensures the correctness of the - // generated code. - var newBlock = new Block(); - _currentBlock.FlowsTo(newBlock); - _currentBlock = newBlock; + // This flow always exists. + finallyLastBlock.FlowsTo(afterTry); } + else + { + lastBlockInTry.FlowsTo(afterTry); + } + + _currentBlock = afterTry; return null; } @@ -2486,7 +2543,7 @@ where t.Label.Equals(labelStrAst.Value, StringComparison.OrdinalIgnoreCase) } // The next block is unreachable, but is necessary to keep the flow graph correct. - _currentBlock = new Block { _unreachable = true }; + _currentBlock = new Block(); } /// @@ -2525,7 +2582,7 @@ internal Block ControlFlowStatement(PipelineBaseAst pipelineAst) var lastBlockInStatement = _currentBlock; // The next block is unreachable, but is necessary to keep the flow graph correct. - _currentBlock = new Block { _unreachable = true }; + _currentBlock = new Block(); return lastBlockInStatement; } diff --git a/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 b/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 index 6a9ce8077..42c137872 100644 --- a/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 +++ b/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 @@ -41,4 +41,21 @@ function Test-PreferenceVariable } $VerbosePreference - } \ No newline at end of file +} + +function Test-Throw +{ + if ($true) + { + throw "First time" + } + + $a = 4 + + if ($false) + { + throw "Second time" + } + + $a +} \ No newline at end of file From 8b973b9a8d00edbb3b8ed63c9bdf10766c27151a Mon Sep 17 00:00:00 2001 From: Quoc Truong Date: Fri, 29 May 2015 14:59:27 -0700 Subject: [PATCH 28/29] Simplifies logic of suppressing rule and fix a bug where rule suppression does not work for more than one variable --- Engine/Helper.cs | 108 ++++++++++--------------------- Tests/Engine/RuleSuppression.ps1 | 9 +++ 2 files changed, 44 insertions(+), 73 deletions(-) diff --git a/Engine/Helper.cs b/Engine/Helper.cs index 94bc8b871..373f4bd58 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -859,102 +859,64 @@ public Tuple, List> SuppressRule(string List ruleSuppressions = ruleSuppressionsDict[ruleName]; int recordIndex = 0; - int ruleSuppressionIndex = 0; - DiagnosticRecord record = diagnostics.First(); - RuleSuppression ruleSuppression = ruleSuppressions.First(); - int suppressionCount = 0; + int startRecord = 0; + bool[] suppressed = new bool[diagnostics.Count]; - while (recordIndex < diagnostics.Count) + foreach (RuleSuppression ruleSuppression in ruleSuppressions) { - if (!String.IsNullOrWhiteSpace(ruleSuppression.Error)) + int suppressionCount = 0; + while (startRecord < diagnostics.Count && diagnostics[startRecord].Extent.StartOffset < ruleSuppression.StartOffset) { - ruleSuppressionIndex += 1; + startRecord += 1; + } + + // at this point, start offset of startRecord is greater or equals to rulesuppression.startoffset + recordIndex = startRecord; + + while (recordIndex < diagnostics.Count) + { + DiagnosticRecord record = diagnostics[recordIndex]; - if (ruleSuppressionIndex == ruleSuppressions.Count) + if (record.Extent.EndOffset > ruleSuppression.EndOffset) { break; } - ruleSuppression = ruleSuppressions[ruleSuppressionIndex]; - suppressionCount = 0; - - continue; - } - - // if the record precedes the rule suppression then we don't apply the suppression - // so we check that start of record is greater than start of suppression - if (record.Extent.StartOffset >= ruleSuppression.StartOffset) - { - // end of the rule suppression is less than the record start offset so move on to next rule suppression - if (ruleSuppression.EndOffset < record.Extent.StartOffset) + if (string.IsNullOrWhiteSpace(ruleSuppression.RuleSuppressionID)) { - ruleSuppressionIndex += 1; - - // If we cannot found any error but the rulesuppression has a rulesuppressionid then it must be used wrongly - if (!String.IsNullOrWhiteSpace(ruleSuppression.RuleSuppressionID) && suppressionCount == 0) - { - ruleSuppression.Error = String.Format(CultureInfo.CurrentCulture, Strings.RuleSuppressionErrorFormat, ruleSuppression.StartAttributeLine, - System.IO.Path.GetFileName(record.Extent.File), String.Format(Strings.RuleSuppressionIDError, ruleSuppression.RuleSuppressionID)); - Helper.Instance.MyCmdlet.WriteError(new ErrorRecord(new ArgumentException(ruleSuppression.Error), ruleSuppression.Error, ErrorCategory.InvalidArgument, ruleSuppression)); - } - - if (ruleSuppressionIndex == ruleSuppressions.Count) - { - break; - } - - ruleSuppression = ruleSuppressions[ruleSuppressionIndex]; - suppressionCount = 0; - - continue; + suppressed[recordIndex] = true; + suppressionCount += 1; } - // at this point, the record is inside the interval else { - // if the rule suppression id from the rule suppression is not null and the one from diagnostic record is not null - // and they are they are not the same then we cannot ignore the record - if (!string.IsNullOrWhiteSpace(ruleSuppression.RuleSuppressionID) && !string.IsNullOrWhiteSpace(record.RuleSuppressionID) - && !string.Equals(ruleSuppression.RuleSuppressionID, record.RuleSuppressionID, StringComparison.OrdinalIgnoreCase)) - { - suppressionCount -= 1; - unSuppressedRecords.Add(record); - } - // otherwise, we suppress the record, move on to the next. - else + //if there is a rule suppression id, we only suppressed if it matches + if (!String.IsNullOrWhiteSpace(record.RuleSuppressionID) && + string.Equals(ruleSuppression.RuleSuppressionID, record.RuleSuppressionID, StringComparison.OrdinalIgnoreCase)) { + suppressed[recordIndex] = true; suppressedRecords.Add(new SuppressedRecord(record, ruleSuppression)); + suppressionCount += 1; } } - } - else - { - unSuppressedRecords.Add(record); - } - // important assumption: this point is reached only if we want to move to the next record - recordIndex += 1; - suppressionCount += 1; + recordIndex += 1; + } - if (recordIndex == diagnostics.Count) + // If we cannot found any error but the rulesuppression has a rulesuppressionid then it must be used wrongly + if (!String.IsNullOrWhiteSpace(ruleSuppression.RuleSuppressionID) && suppressionCount == 0) { - // If we cannot found any error but the rulesuppression has a rulesuppressionid then it must be used wrongly - if (!String.IsNullOrWhiteSpace(ruleSuppression.RuleSuppressionID) && suppressionCount == 0) - { - ruleSuppression.Error = String.Format(CultureInfo.CurrentCulture, Strings.RuleSuppressionErrorFormat, ruleSuppression.StartAttributeLine, - System.IO.Path.GetFileName(record.Extent.File), String.Format(Strings.RuleSuppressionIDError, ruleSuppression.RuleSuppressionID)); - Helper.Instance.MyCmdlet.WriteError(new ErrorRecord(new ArgumentException(ruleSuppression.Error), ruleSuppression.Error, ErrorCategory.InvalidArgument, ruleSuppression)); - } - - break; + ruleSuppression.Error = String.Format(CultureInfo.CurrentCulture, Strings.RuleSuppressionErrorFormat, ruleSuppression.StartAttributeLine, + System.IO.Path.GetFileName(diagnostics.First().Extent.File), String.Format(Strings.RuleSuppressionIDError, ruleSuppression.RuleSuppressionID)); + Helper.Instance.MyCmdlet.WriteError(new ErrorRecord(new ArgumentException(ruleSuppression.Error), ruleSuppression.Error, ErrorCategory.InvalidArgument, ruleSuppression)); } - - record = diagnostics[recordIndex]; } - while (recordIndex < diagnostics.Count) + for (int i = 0; i < suppressed.Length; i += 1) { - unSuppressedRecords.Add(diagnostics[recordIndex]); - recordIndex += 1; + if (!suppressed[i]) + { + unSuppressedRecords.Add(diagnostics[i]); + } } return result; diff --git a/Tests/Engine/RuleSuppression.ps1 b/Tests/Engine/RuleSuppression.ps1 index 45ae97bd3..d2fc8e485 100644 --- a/Tests/Engine/RuleSuppression.ps1 +++ b/Tests/Engine/RuleSuppression.ps1 @@ -14,6 +14,15 @@ function SuppressMe () } +function SuppressTwoVariables() +{ + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUninitializedVariable", "b")] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUninitializedVariable", "a")] + Param([string]$a, [int]$b) + { + } +} + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "", Scope="Class")] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("pSAvoidUsingInvokeExpression", "")] class TestClass From 76200c9dcb119f8c886ee230ed34c261a86b047b Mon Sep 17 00:00:00 2001 From: "Raghu Shantha [MSFT]" Date: Tue, 2 Jun 2015 10:58:28 -0700 Subject: [PATCH 29/29] Fix for failing RuleSuppressionID tests --- Tests/Engine/RuleSuppression.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/Engine/RuleSuppression.ps1 b/Tests/Engine/RuleSuppression.ps1 index 23b095793..d5cd4e055 100644 --- a/Tests/Engine/RuleSuppression.ps1 +++ b/Tests/Engine/RuleSuppression.ps1 @@ -16,8 +16,8 @@ function SuppressMe () function SuppressTwoVariables() { - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUninitializedVariable", "b")] - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUninitializedVariable", "a")] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSProvideDefaultParameterValue", "b")] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSProvideDefaultParameterValue", "a")] Param([string]$a, [int]$b) { }