diff --git a/src/System.Management.Automation/engine/LanguagePrimitives.cs b/src/System.Management.Automation/engine/LanguagePrimitives.cs index 4a2b1608e6..43c21f512c 100644 --- a/src/System.Management.Automation/engine/LanguagePrimitives.cs +++ b/src/System.Management.Automation/engine/LanguagePrimitives.cs @@ -1506,47 +1506,38 @@ namespace System.Management.Automation private static object NewConverterInstance(string assemblyQualifiedTypeName) { - int typeSeparator = assemblyQualifiedTypeName.IndexOf(','); - if (typeSeparator == -1) + if (assemblyQualifiedTypeName.IndexOf(',') == -1) { typeConversion.WriteLine("Type name \"{0}\" should be assembly qualified.", assemblyQualifiedTypeName); return null; } - string assemblyName = assemblyQualifiedTypeName.Substring(typeSeparator + 2); - string typeName = assemblyQualifiedTypeName.Substring(0, typeSeparator); - - foreach (Assembly assembly in ClrFacade.GetAssemblies(typeName)) + Type converterType; + try { - if (assembly.FullName == assemblyName) - { - Type converterType = null; - try - { - converterType = assembly.GetType(typeName, false, false); - } - catch (ArgumentException e) - { - typeConversion.WriteLine("Assembly \"{0}\" threw an exception when retrieving the type \"{1}\": \"{2}\".", assemblyName, typeName, e.Message); - return null; - } - - try - { - return Activator.CreateInstance(converterType); - } - catch (Exception e) - { - TargetInvocationException inner = e as TargetInvocationException; - string message = (inner == null) || (inner.InnerException == null) ? e.Message : inner.InnerException.Message; - typeConversion.WriteLine("Creating an instance of type \"{0}\" caused an exception to be thrown: \"{1}\"", assemblyQualifiedTypeName, message); - return null; - } - } + // Type.GetType() can load an assembly. + // PowerShell is allowed to load only TPA. + // Since a type is already loaded we trust to an attribute assigned to the type + // and can use Type.GetType() without additional checks. + converterType = Type.GetType(assemblyQualifiedTypeName, throwOnError: true, ignoreCase: false); + } + catch (Exception e) + { + typeConversion.WriteLine("Threw an exception when retrieving the type \"{1}\": \"{2}\".", assemblyQualifiedTypeName, e.Message); + return null; } - typeConversion.WriteLine("Could not create an instance of type \"{0}\".", assemblyQualifiedTypeName); - return null; + try + { + return Activator.CreateInstance(converterType); + } + catch (Exception e) + { + TargetInvocationException inner = e as TargetInvocationException; + string message = (inner == null) || (inner.InnerException == null) ? e.Message : inner.InnerException.Message; + typeConversion.WriteLine("Creating an instance of type \"{0}\" caused an exception to be thrown: \"{1}\"", assemblyQualifiedTypeName, message); + return null; + } } /// diff --git a/test/powershell/engine/Api/LanguagePrimitive.Tests.ps1 b/test/powershell/engine/Api/LanguagePrimitive.Tests.ps1 index e987d3314c..bc9d812afe 100644 --- a/test/powershell/engine/Api/LanguagePrimitive.Tests.ps1 +++ b/test/powershell/engine/Api/LanguagePrimitive.Tests.ps1 @@ -28,6 +28,39 @@ Describe "Language Primitive Tests" -Tags "CI" { $ObjArray.Length | Should -Be $col.Count } + It "Test convertion with .Net Core intrinsic type convertor" { + $result = [System.Management.Automation.LanguagePrimitives]::ConvertTo('2,3', [System.Drawing.Point]) + $result | Should -BeOfType System.Drawing.Point + $result.X | Should -Be 2 + $result.Y | Should -Be 3 + + $result = [System.Management.Automation.LanguagePrimitives]::ConvertTo([PSObject]'2,3', [System.Drawing.Point]) + $result | Should -BeOfType System.Drawing.Point + $result.X | Should -Be 2 + $result.Y | Should -Be 3 + + $result = [System.Management.Automation.LanguagePrimitives]::ConvertTo('http://test.site.com', [System.Uri]) + $result | Should -BeOfType System.Uri + $result.AbsoluteUri | Should -BeExactly 'http://test.site.com/' + + # accept relative URI path + $result = [System.Management.Automation.LanguagePrimitives]::ConvertTo('..\foo', [System.Uri]) + $result | Should -BeOfType System.Uri + $result.OriginalString | Should -BeExactly '..\foo' + } + + It "Test convertion with .Net Core intrinsic type convertor (Windows only types)" -Skip:(-not $IsWindows) { + $result = [System.Management.Automation.LanguagePrimitives]::ConvertTo('Microsoft Sans Serif,10', [System.Drawing.Font]) + $result | Should -BeOfType System.Drawing.Font + $result.Size | Should -Be 10 + $result.Name | Should -BeExactly 'Microsoft Sans Serif' + + $result = [System.Management.Automation.LanguagePrimitives]::ConvertTo([PSObject]'Microsoft Sans Serif,10', [System.Drawing.Font]) + $result | Should -BeOfType System.Drawing.Font + $result.Size | Should -Be 10 + $result.Name | Should -BeExactly 'Microsoft Sans Serif' + } + It "Casting recursive array to bool should not cause crash" { $a[0] = $a = [PSObject](, 1) [System.Management.Automation.LanguagePrimitives]::IsTrue($a) | Should -BeTrue