diff --git a/DeprecatedRules/AvoidUninitializedVariable.cs b/DeprecatedRules/AvoidUninitializedVariable.cs deleted file mode 100644 index accbbcc3d..000000000 --- a/DeprecatedRules/AvoidUninitializedVariable.cs +++ /dev/null @@ -1,156 +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.Linq; -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 -{ - /// - /// AvoidUnitializedVariable: Check if any uninitialized variable is used. - /// - [Export(typeof(IScriptRule))] - public class AvoidUnitializedVariable : IScriptRule - { - /// - /// AnalyzeScript: Check if any uninitialized variable is used. - /// - public IEnumerable AnalyzeScript(Ast ast, string fileName) - { - // TODO : We need to find another way for using S.M.A.L.Compiler.GetExpressionValue. - // Following code are not working for certain scenarios;, like: - // for ($i=1; $i -le 10; $i++){Write-Host $i} - - if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage); - - // Finds all VariableExpressionAst - IEnumerable foundAsts = ast.FindAll(testAst => testAst is VariableExpressionAst, true); - - // Iterates all VariableExpressionAst and check the command name. - foreach (VariableExpressionAst varAst in foundAsts) - { - if (Helper.Instance.IsUninitialized(varAst, ast)) - { - yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableError, varAst.VariablePath.UserPath), - varAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, varAst.VariablePath.UserPath); - } - } - - IEnumerable funcAsts = ast.FindAll(item => item is FunctionDefinitionAst, true); - IEnumerable funcMemberAsts = ast.FindAll(item => item is FunctionMemberAst, true); - - foreach (FunctionDefinitionAst funcAst in funcAsts) - { - // Finds all VariableExpressionAst. - IEnumerable varAsts = funcAst.FindAll(testAst => testAst is VariableExpressionAst, true); - - HashSet paramVariables = new HashSet(); - - // don't raise the rules for variables in the param block. - if (funcAst.Body != null && funcAst.Body.ParamBlock != null && funcAst.Body.ParamBlock.Parameters != null) - { - paramVariables.UnionWith(funcAst.Body.ParamBlock.Parameters.Select(paramAst => paramAst.Name.VariablePath.UserPath)); - } - - //don't raise the rules for parameters outside the param block - if(funcAst.Parameters != null) - { - paramVariables.UnionWith(funcAst.Parameters.Select(paramAst => paramAst.Name.VariablePath.UserPath)); - } - - // Iterates all VariableExpressionAst and check the command name. - foreach (VariableExpressionAst varAst in varAsts) - { - if (Helper.Instance.IsUninitialized(varAst, funcAst) && !paramVariables.Contains(varAst.VariablePath.UserPath)) - { - yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableError, varAst.VariablePath.UserPath), - varAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, varAst.VariablePath.UserPath); - } - } - } - - foreach (FunctionMemberAst funcMemAst in funcMemberAsts) - { - // Finds all VariableExpressionAst. - IEnumerable varAsts = funcMemAst.FindAll(testAst => testAst is VariableExpressionAst, true); - - // Iterates all VariableExpressionAst and check the command name. - foreach (VariableExpressionAst varAst in varAsts) - { - if (Helper.Instance.IsUninitialized(varAst, funcMemAst)) - { - yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableError, varAst.VariablePath.UserPath), - varAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, varAst.VariablePath.UserPath); - } - } - - } - } - - /// - /// GetName: Retrieves the name of this rule. - /// - /// The name of this rule - public string GetName() - { - return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.AvoidUninitializedVariableName); - } - - /// - /// GetCommonName: Retrieves the common name of this rule. - /// - /// The common name of this rule - public string GetCommonName() - { - return string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableCommonName); - } - - /// - /// GetDescription: Retrieves the description of this rule. - /// - /// The description of this rule - public string GetDescription() - { - return string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableDescription); - } - - /// - /// Method: 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; - } - - /// - /// Method: Retrieves the module/assembly name the rule is from. - /// - public string GetSourceName() - { - return string.Format(CultureInfo.CurrentCulture, Strings.SourceName); - } - } -} diff --git a/DeprecatedRules/AvoidUnloadableModule.cs b/DeprecatedRules/AvoidUnloadableModule.cs deleted file mode 100644 index 5e21ee989..000000000 --- a/DeprecatedRules/AvoidUnloadableModule.cs +++ /dev/null @@ -1,131 +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.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Management.Automation; -using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; -using System.ComponentModel.Composition; -using System.Resources; -using System.Globalization; -using System.Threading; -using System.Reflection; -using System.IO; - -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules -{ - /// - /// AvoidUnloadableModule: Run Import-Module on parent folder to check whether the module is loaded. - /// - [Export(typeof (IScriptRule))] - public class AvoidUnloadableModule : IScriptRule - { - /// - /// AnalyzeScript: Run Import-Module on parent folder to check whether the module is loaded. From the IScriptRule interface. - /// - /// 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); - - DirectoryInfo moduleFolder = Directory.GetParent(fileName); - - if (!String.Equals(moduleFolder.FullName, Path.GetPathRoot(fileName))) - { - Regex reg = new Regex(String.Format(CultureInfo.CurrentCulture, "{0}\\.(dll|psm1|psd1|cdxml|xaml)", - Regex.Escape(Path.Combine(moduleFolder.FullName, moduleFolder.Name)))); - var moduleFiles = moduleFolder.GetFiles().Where(file => reg.Match(file.FullName).Success).ToList(); - - if (moduleFiles != null && moduleFiles.Count > 0) - { - bool moduleValid = true; - using (var ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace)) - { - try - { - ps.AddCommand("Import-Module"); - ps.AddParameter("Name", moduleFolder.FullName); - ps.Invoke(); - - if (ps != null && ps.HadErrors) - { - moduleValid = false; - } - } - catch (Exception) - { - //Catch the exception thrown by ps.Invoke(); - moduleValid = false; - } - - if (!moduleValid) - { - yield return new DiagnosticRecord(String.Format(CultureInfo.CurrentCulture, - Strings.AvoidUnloadableModuleError, moduleFolder.Name, Path.GetFileName(fileName)), - ast.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.AvoidUnloadableModuleName); - } - - /// - /// GetCommonName: Retrieves the common name of this rule. - /// - /// The common name of this rule - public string GetCommonName() - { - return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUnloadableModuleCommonName); - } - - /// - /// GetDescription: Retrieves the description of this rule. - /// - /// The description of this rule - public string GetDescription() - { - return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUnloadableModuleDescription); - } - - /// - /// Method: Retrieves the type of the rule: builtin, managed or module. - /// - public SourceType GetSourceType() - { - return SourceType.Builtin; - } - - /// - /// Method: Retrieves the module/assembly name the rule is from. - /// - public string GetSourceName() - { - return string.Format(CultureInfo.CurrentCulture, Strings.SourceName); - } - } -} diff --git a/DeprecatedRules/AvoidUsingFilePaths.cs b/DeprecatedRules/AvoidUsingFilePaths.cs deleted file mode 100644 index cc9a9b256..000000000 --- a/DeprecatedRules/AvoidUsingFilePaths.cs +++ /dev/null @@ -1,127 +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.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Management.Automation.Language; -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; -using System.ComponentModel.Composition; -using System.Resources; -using System.Globalization; -using System.Threading; -using System.Reflection; -using System.IO; - -namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules -{ - /// - /// AvoidUsingFilePaths: Check that rooted file paths are not used. - /// Examples of rooted file paths are C:\Users or \\windows\powershell - /// - [Export(typeof (IScriptRule))] - public class AvoidUsingFilePaths : IScriptRule - { - /// - /// AnalyzeScript: Analyzes the ast to check that rooted file paths are not used. From the ILintScriptRule interface. - /// - /// 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 expressionAsts = ast.FindAll(testAst => testAst is StringConstantExpressionAst, true); - - if (expressionAsts != null) - { - foreach (StringConstantExpressionAst expressionAst in expressionAsts) - { - bool isPathValid = false; - bool isRootedPath = false; - //make sure there is no path - char[] invalidPathChars = Path.GetInvalidPathChars(); - if (expressionAst.Value.IndexOfAny(invalidPathChars) < 0) - { - isPathValid = true; - } - - if (isPathValid) - { - if (Path.IsPathRooted(expressionAst.Value)) - { - isRootedPath = true; - } - } - - if (!String.IsNullOrWhiteSpace(expressionAst.Value) && isRootedPath) - { - //Exclude the case where there are only slashes in the expressions - char[] varToTrim = { '/', '\\' }; - if (!String.IsNullOrEmpty(expressionAst.Value.Trim(varToTrim))) - { - yield return new DiagnosticRecord(String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingFilePathError, - expressionAst.Value, Path.GetFileName(fileName)), expressionAst.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.AvoidUsingFilePathName); - } - - /// - /// GetCommonName: Retrieves the common name of this rule. - /// - /// The common name of this rule - public string GetCommonName() - { - return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingFilePathCommonName); - } - - /// - /// GetDescription: Retrieves the description of this rule. - /// - /// The description of this rule - public string GetDescription() - { - return string.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingFilePathDescription); - } - - /// - /// Method: Retrieves the type of the rule: builtin, managed or module. - /// - public SourceType GetSourceType() - { - return SourceType.Builtin; - } - - /// - /// Method: Retrieves the module/assembly name the rule is from. - /// - public string GetSourceName() - { - return string.Format(CultureInfo.CurrentCulture, Strings.SourceName); - } - } -} diff --git a/DeprecatedRules/AvoidUsingInternalURLs.cs b/DeprecatedRules/AvoidUsingInternalURLs.cs deleted file mode 100644 index 90c880909..000000000 --- a/DeprecatedRules/AvoidUsingInternalURLs.cs +++ /dev/null @@ -1,226 +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; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Management.Automation.Language; -using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic; -using System.ComponentModel.Composition; -using System.Globalization; -using System.IO; - -namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules -{ - /// - /// AvoidUsingInternalURLs: Check if a URL is potentially an internal URL, - /// eg://msw, //scratch2/scratch - /// - [Export(typeof (IScriptRule))] - public class AvoidUsingInternalURLs : IScriptRule - { - /// - /// AnalyzeScript: Analyzes the ast to check if any internal URL is 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 expressionAsts = ast.FindAll(testAst => testAst is StringConstantExpressionAst, true); - - if (expressionAsts != null) - { - foreach (StringConstantExpressionAst expressionAst in expressionAsts) - { - - Ast parentAst = expressionAst.Parent; - //Check if -replace is used, if it is string replace, we don't throw warnings. - Ast grandParentAst = parentAst.Parent; - if (grandParentAst is BinaryExpressionAst) - { - if ((grandParentAst as BinaryExpressionAst).Operator.Equals(TokenKind.Ireplace)) - { - continue; - } - } - - //Check if XPath is used. If XPath is used, then we don't throw warnings. - if (parentAst is InvokeMemberExpressionAst) - { - InvokeMemberExpressionAst invocation = parentAst as InvokeMemberExpressionAst; - if (invocation != null) - { - 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) || - String.Equals(invocation.Expression.ToString(), "[System.String]",StringComparison.OrdinalIgnoreCase) || - String.Equals(invocation.Expression.ToString(), "[String]", StringComparison.OrdinalIgnoreCase)) - { - continue; - } - - } - } - - - bool isPathValid = false; - bool isInternalURL = false; - //make sure there is no path - char[] invalidPathChars = Path.GetInvalidPathChars(); - if (expressionAst.Value.IndexOfAny(invalidPathChars) < 0) - { - isPathValid = true; - } - - //Check if path is UNC or begins with "http:" or "www" - if (isPathValid && ((!String.IsNullOrWhiteSpace(expressionAst.Value))) && - (Path.IsPathRooted(expressionAst.Value) || - expressionAst.Value.StartsWith("http:", StringComparison.CurrentCultureIgnoreCase)) || - (expressionAst.Value.StartsWith("www", StringComparison.CurrentCultureIgnoreCase))) - { - //Exclude the case where there are only slashes in the expressions - char[] varToTrim = {'/','\\'}; - string noSlash = expressionAst.Value.Trim(varToTrim); - if (!String.IsNullOrEmpty(noSlash) && noSlash.Trim().Length > 1) - { - //Check if the string contains two back or forward slashes, such as: \\scratch2\scratch or http:\\www.google.com - bool backSlash = expressionAst.Value.Contains(@"\\"); - bool forwardSlash = expressionAst.Value.Contains(@"//"); - string firstPartURL = ""; - if (backSlash) - { - //Get the first part of the URL before the first back slash, eg: \\scratch2\scratch we check only scratch2 as the first part - string trimmedAddress = - expressionAst.Value.Substring(expressionAst.Value.IndexOf(@"\\") + 2); - if (trimmedAddress.Contains(@"\")) - { - firstPartURL = trimmedAddress.Substring(0, trimmedAddress.IndexOf(@"\")); - } - else - { - firstPartURL = trimmedAddress; - } - } - else if (forwardSlash) - { - //Get the first part of the URL before the first forward slash - string trimmedAddress = - expressionAst.Value.Substring(expressionAst.Value.IndexOf(@"//") + 2); - if (trimmedAddress.Contains(@"/")) - { - firstPartURL = trimmedAddress.Substring(0, trimmedAddress.IndexOf(@"/")); - } - else - { - firstPartURL = trimmedAddress; - } - } - else - { - if (expressionAst.Value.Contains(@"\")) - { - firstPartURL = expressionAst.Value.Substring(0, expressionAst.Value.IndexOf(@"\")); - } - else if (expressionAst.Value.Contains(@"/")) - { - firstPartURL = expressionAst.Value.Substring(0, expressionAst.Value.IndexOf(@"/")); - } - else - { - firstPartURL = expressionAst.Value; - } - } - if (!firstPartURL.Contains(".")) - { - isInternalURL = true; - //Add a check to exclude potential SDDL format. Check if a string have four components separated by ":" - var count = firstPartURL.Count(x => x == ':'); - if (count == 3 || count == 4 ) - { - isInternalURL = false; - } - } - } - if (isInternalURL) - { - yield return - new DiagnosticRecord( - String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingInternalURLsError, - expressionAst.Value), expressionAst.Extent, - GetName(), DiagnosticSeverity.Information, 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.AvoidUsingInternalURLsName); - } - - /// - /// GetCommonName: Retrieves the common name of this rule. - /// - /// The common name of this rule - public string GetCommonName() - { - return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingInternalURLsCommonName); - } - - /// - /// GetDescription: Retrieves the description of this rule. - /// - /// The description of this rule - public string GetDescription() - { - return string.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingInternalURLsDescription); - } - - /// - /// Method: 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.Information; - } - - /// - /// Method: Retrieves the module/assembly name the rule is from. - /// - public string GetSourceName() - { - return string.Format(CultureInfo.CurrentCulture, Strings.SourceName); - } - } -}