Fix string parameter binding for BigInteger numeric literals (#11634)

This commit is contained in:
Joel Sallow (/u/ta11ow)
2020-05-12 16:31:37 -07:00
committed by GitHub
parent e74fc33b5f
commit 7bc2617fe3
4 changed files with 55 additions and 3 deletions
@@ -14,6 +14,7 @@ using System.Linq.Expressions;
using System.Management.Automation.Internal;
using System.Management.Automation.Language;
using System.Management.Automation.Runspaces;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
@@ -3307,6 +3308,11 @@ namespace System.Management.Automation
return sgl.ToString(SinglePrecision, numberFormat);
}
if (valueToConvert is BigInteger b)
{
return b.ToString(numberFormat);
}
return (string)Convert.ChangeType(valueToConvert, resultType, CultureInfo.InvariantCulture.NumberFormat);
}
catch (Exception e)
@@ -4380,7 +4386,8 @@ namespace System.Management.Automation
typeof(Int16), typeof(Int32), typeof(Int64),
typeof(UInt16), typeof(UInt32), typeof(UInt64),
typeof(sbyte), typeof(byte),
typeof(Single), typeof(double), typeof(decimal)
typeof(Single), typeof(double), typeof(decimal),
typeof(BigInteger)
};
private static Type[] s_integerTypes = new Type[] {
@@ -4171,7 +4171,9 @@ namespace System.Management.Automation.Language
private Expression GetCommandArgumentExpression(CommandElementAst element)
{
var constElement = element as ConstantExpressionAst;
if (constElement != null && LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constElement.StaticType)))
if (constElement != null
&& (LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constElement.StaticType))
|| constElement.StaticType == typeof(System.Numerics.BigInteger)))
{
var commandArgumentText = constElement.Extent.Text;
if (!commandArgumentText.Equals(constElement.Value.ToString(), StringComparison.Ordinal))
@@ -643,7 +643,9 @@ namespace System.Management.Automation
{
var constantExprAst = ast as ConstantExpressionAst;
object argument;
if (constantExprAst != null && LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constantExprAst.StaticType)))
if (constantExprAst != null
&& (LanguagePrimitives.IsNumeric(LanguagePrimitives.GetTypeCode(constantExprAst.StaticType))
|| constantExprAst.StaticType == typeof(System.Numerics.BigInteger)))
{
var commandArgumentText = constantExprAst.Extent.Text;
argument = constantExprAst.Value;
@@ -425,3 +425,44 @@ Describe "Custom type conversion in parameter binding" -Tags 'Feature' {
}
}
}
Describe 'Roundtrippable Conversions for Bare-string Numeric Literals passed to [string] Parameters' -Tags CI {
BeforeAll {
$TestValues = @(
@{ Argument = "34uy" }
@{ Argument = "48y" }
@{ Argument = "8s" }
@{ Argument = "49us" }
@{ Argument = "26" }
@{ Argument = "28u" }
@{ Argument = "24l" }
@{ Argument = "32ul" }
@{ Argument = "20d" }
@{ Argument = "6n" }
)
function Test-SimpleStringValue([string] $Value) { $Value }
function Test-AdvancedStringValue {
[CmdletBinding()]
param(
[string]
$Value
)
$Value
}
}
It 'should correctly convert <Argument> back to string in simple functions' -TestCases $TestValues {
param($Argument)
Invoke-Expression "Test-SimpleStringValue -Value $Argument" | Should -BeExactly $Argument
}
It 'should correctly convert <Argument> back to string in advanced functions' -TestCases $TestValues {
param($Argument)
Invoke-Expression "Test-AdvancedStringValue -Value $Argument" | Should -BeExactly $Argument
}
}