diff --git a/Rules/AvoidValidateRangeTypeMismatch.cs b/Rules/AvoidValidateRangeTypeMismatch.cs index f288b5ba5..319a865ba 100644 --- a/Rules/AvoidValidateRangeTypeMismatch.cs +++ b/Rules/AvoidValidateRangeTypeMismatch.cs @@ -21,23 +21,23 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules #endif public sealed class AvoidValidateRangeTypeMismatch : IScriptRule { - private static readonly HashSet FloatingPointAndDecimalTypes = new HashSet(StringComparer.OrdinalIgnoreCase) + private static readonly HashSet FloatingPointAndDecimalTypes = new HashSet { - "double", "System.Double", - "single", "float", "System.Single", - "decimal", "System.Decimal" + typeof(double), + typeof(float), + typeof(decimal) }; - private static readonly HashSet IntegralTypes = new HashSet(StringComparer.OrdinalIgnoreCase) + private static readonly HashSet IntegralTypes = new HashSet { - "byte", "System.Byte", - "sbyte", "System.SByte", - "short", "System.Int16", - "ushort", "System.UInt16", - "int", "System.Int32", - "uint", "System.UInt32", - "long", "System.Int64", - "ulong", "System.UInt64" + typeof(byte), + typeof(sbyte), + typeof(short), + typeof(ushort), + typeof(int), + typeof(uint), + typeof(long), + typeof(ulong) }; public IEnumerable AnalyzeScript(Ast ast, string fileName) @@ -51,7 +51,23 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) foreach (ParameterAst parameterAst in parameterAsts) { TypeConstraintAst typeConstraint = parameterAst.Attributes.OfType().FirstOrDefault(); - if (typeConstraint == null || !FloatingPointAndDecimalTypes.Contains(typeConstraint.TypeName.FullName)) + if (typeConstraint == null) + { + continue; + } + + Type parameterType = typeConstraint.TypeName.GetReflectionType(); + if (parameterType == null) + { + continue; + } + + if (parameterType.IsArray) + { + parameterType = parameterType.GetElementType(); + } + + if (!FloatingPointAndDecimalTypes.Contains(parameterType)) { continue; } @@ -60,7 +76,7 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) { if (!IsValidateRangeAttribute(attributeAst) || attributeAst.PositionalArguments.Count < 2 - || !attributeAst.PositionalArguments.Take(2).Any(IsIntegralBoundary)) + || !attributeAst.PositionalArguments.Take(2).All(IsIntegralBoundary)) { continue; } @@ -79,14 +95,12 @@ private static bool IsIntegralBoundary(ExpressionAst expressionAst) { if (expressionAst is ConstantExpressionAst constantExpressionAst) { - return constantExpressionAst.Value != null - && IntegralTypes.Contains(constantExpressionAst.Value.GetType().FullName); + return constantExpressionAst.Value != null && IntegralTypes.Contains(constantExpressionAst.Value.GetType()); } if (expressionAst is ConvertExpressionAst convertExpressionAst) { - return IntegralTypes.Contains(convertExpressionAst.Type.TypeName.FullName) - && IsIntegralBoundary(convertExpressionAst.Child); + return IntegralTypes.Contains(convertExpressionAst.Type.TypeName.GetReflectionType()); } if (expressionAst is UnaryExpressionAst unaryExpressionAst diff --git a/Tests/Rules/AvoidValidateRangeTypeMismatch.tests.ps1 b/Tests/Rules/AvoidValidateRangeTypeMismatch.tests.ps1 index 0a307a2ee..bc3915240 100644 --- a/Tests/Rules/AvoidValidateRangeTypeMismatch.tests.ps1 +++ b/Tests/Rules/AvoidValidateRangeTypeMismatch.tests.ps1 @@ -10,8 +10,11 @@ Describe 'AvoidValidateRangeTypeMismatch' { $scripts = @( 'function Test { param([double][ValidateRange(1, 2)]$Value) }' 'function Test { param([single][ValidateRange(-1, 2)]$Value) }' - 'function Test { param([decimal][ValidateRange(1, 2.0)]$Value) }' + 'function Test { param([decimal][ValidateRange(1, 2)]$Value) }' + 'function Test { param([double[]][ValidateRange(1, 2)]$Values) }' 'function Test { param([double][System.Management.Automation.ValidateRangeAttribute(1, 2)]$Value) }' + 'function Test { param([double][ValidateRange([int]0.0, [int]100.0)]$Value) }' + 'function Test { param([double][ValidateRange([int32]0.0, [int32]100.0)]$Value) }' ) foreach ($scriptDefinition in $scripts) { @@ -26,6 +29,7 @@ Describe 'AvoidValidateRangeTypeMismatch' { 'function Test { param([double][ValidateRange(1.0, 2.0)]$Value) }' 'function Test { param([single][ValidateRange(1.0, 2.0)]$Value) }' 'function Test { param([decimal][ValidateRange(1.0, 2.0)]$Value) }' + 'function Test { param([double][ValidateRange(1, 2.0)]$Value) }' 'function Test { param([int][ValidateRange(1, 2)]$Value) }' )