Skip to content

Commit

Permalink
Add type-aware range check for enum member values
Browse files Browse the repository at this point in the history
I'm thinking there must be an easier way of abstracting this away, but I can't think of anything
  • Loading branch information
IISResetMe committed Nov 21, 2018
1 parent c1bc80d commit f417453
Showing 1 changed file with 54 additions and 2 deletions.
56 changes: 54 additions & 2 deletions src/System.Management.Automation/engine/parser/PSType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,8 @@ internal void DefineEnum()
var enumBuilder = _moduleBuilder.DefineEnum(_typeName, Reflection.TypeAttributes.Public, underlyingType);
DefineCustomAttributes(enumBuilder, _enumDefinitionAst.Attributes, _parser, AttributeTargets.Enum);
dynamic value = 0;
ulong maxValue;
GetMaxValue(underlyingType, out maxValue);
bool valueTooBig = false;
foreach (var member in _enumDefinitionAst.Members)
{
Expand Down Expand Up @@ -1163,15 +1165,65 @@ internal void DefineEnum()

if (_enumDefinitionAst.Attributes.Any(attr => attr.TypeName.GetReflectionType() == typeof(FlagsAttribute)) && value != 0)
{
value *= 2;
if (Convert.ToUInt64(value) < maxValue / 2)
{
value *= 2;
}
else
{
valueTooBig = true;
}
}
else
{
value += 1;
if (Convert.ToUInt64(value) < maxValue)
{
value += 1;
}
else
{
valueTooBig = true;
}
}
}
_enumDefinitionAst.Type = enumBuilder.CreateTypeInfo().AsType();
}

private void GetMaxValue(Type underlyingType, out ulong maxValue)
{
if (underlyingType == typeof(byte))
{
maxValue = Convert .ToUInt64(byte.MaxValue);
}
else if (underlyingType == typeof(sbyte))
{
maxValue = Convert.ToUInt64(sbyte.MaxValue);
}
else if (underlyingType == typeof(short))
{
maxValue = Convert.ToUInt64(short.MaxValue);
}
else if (underlyingType == typeof(ushort))
{
maxValue = Convert.ToUInt64(ushort.MaxValue);
}
else if (underlyingType == typeof(int))
{
maxValue = Convert.ToUInt64(int.MaxValue);
}
else if (underlyingType == typeof(uint))
{
maxValue = Convert.ToUInt64(uint.MaxValue);
}
else if (underlyingType == typeof(long))
{
maxValue = Convert.ToUInt64(long.MaxValue);
}
else
{
maxValue = Convert.ToUInt64(ulong.MaxValue);
}
}
}

private static IEnumerable<CustomAttributeBuilder> GetAssemblyAttributeBuilders(string scriptFile)
Expand Down

0 comments on commit f417453

Please sign in to comment.