Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
ArgumentTypeConverterAttribute.cs209 linesDownload Raw Back to engine
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections;5using System.Globalization;6using System.Linq;7using System.Reflection;8 9using Dbg = System.Management.Automation.Diagnostics;10 11namespace System.Management.Automation12{13    /// <summary>14    /// This is used for automatic conversions to be performed in shell variables.15    /// </summary>16    internal sealed class ArgumentTypeConverterAttribute : ArgumentTransformationAttribute17    {18        /// <summary>19        /// This ctor form is used to initialize shell variables20        /// whose type is not permitted to change.21        /// </summary>22        /// <param name="types"></param>23        internal ArgumentTypeConverterAttribute(params Type[] types)24        {25            _convertTypes = types;26        }27 28        private readonly Type[] _convertTypes;29 30        internal Type TargetType31        {32            get33            {34                return _convertTypes?.LastOrDefault();35            }36        }37 38        public override object Transform(EngineIntrinsics engineIntrinsics, object inputData)39        {40            return Transform(engineIntrinsics, inputData, false, false);41        }42 43        internal object Transform(EngineIntrinsics engineIntrinsics, object inputData, bool bindingParameters, bool bindingScriptCmdlet)44        {45            if (_convertTypes == null)46                return inputData;47 48            object result = inputData;49 50            try51            {52                for (int i = 0; i < _convertTypes.Length; i++)53                {54                    if (bindingParameters)55                    {56                        // We should not be doing a conversion here if [ref] is the last type.57                        // When [ref] appears in an argument list, it is used for checking only.58                        // No Conversion should be done.59                        if (_convertTypes[i].Equals(typeof(System.Management.Automation.PSReference)))60                        {61                            object temp;62                            PSObject mshObject = result as PSObject;63                            if (mshObject != null)64                                temp = mshObject.BaseObject;65                            else66                                temp = result;67 68                            if (temp is not PSReference reference)69                            {70                                throw new PSInvalidCastException("InvalidCastExceptionReferenceTypeExpected", null,71                                                                   ExtendedTypeSystem.ReferenceTypeExpected);72                            }73                        }74                        else75                        {76                            object temp;77                            PSObject mshObject = result as PSObject;78                            if (mshObject != null)79                                temp = mshObject.BaseObject;80                            else81                                temp = result;82 83                            // If a non-ref type is expected but currently passed in is a ref, do an implicit dereference.84                            PSReference reference = temp as PSReference;85 86                            if (reference != null)87                            {88                                result = reference.Value;89                            }90 91                            if (bindingScriptCmdlet && _convertTypes[i] == typeof(string))92                            {93                                // Don't allow conversion from array to string in script w/ cmdlet binding.  Allow94                                // the conversion for ordinary script parameter binding for V1 compatibility.95                                temp = PSObject.Base(result);96                                if (temp != null && temp.GetType().IsArray)97                                {98                                    throw new PSInvalidCastException("InvalidCastFromAnyTypeToString", null,99                                        ExtendedTypeSystem.InvalidCastCannotRetrieveString);100                                }101                            }102                        }103                    }104 105                    // BUGBUG106                    // NTRAID#Windows Out of Band Releases - 930116 - 03/14/06107                    // handling special case for boolean, switchparameter and Nullable<bool>108                    // These parameter types will not be converted if the incoming value types are not109                    // one of the accepted categories - $true/$false or numbers (0 or otherwise)110                    if (LanguagePrimitives.IsBoolOrSwitchParameterType(_convertTypes[i]))111                    {112                        CheckBoolValue(result, _convertTypes[i]);113                    }114 115                    if (bindingScriptCmdlet)116                    {117                        // Check for conversion to something like bool[] or ICollection<bool>, but only for cmdlet binding118                        // to stay compatible with V1.119                        ParameterCollectionTypeInformation collectionTypeInfo = new ParameterCollectionTypeInformation(_convertTypes[i]);120                        if (collectionTypeInfo.ParameterCollectionType != ParameterCollectionType.NotCollection121                            && LanguagePrimitives.IsBoolOrSwitchParameterType(collectionTypeInfo.ElementType))122                        {123                            IList currentValueAsIList = ParameterBinderBase.GetIList(result);124                            if (currentValueAsIList != null)125                            {126                                foreach (object val in currentValueAsIList)127                                {128                                    CheckBoolValue(val, collectionTypeInfo.ElementType);129                                }130                            }131                            else132                            {133                                CheckBoolValue(result, collectionTypeInfo.ElementType);134                            }135                        }136                    }137 138                    result = LanguagePrimitives.ConvertTo(result, _convertTypes[i], CultureInfo.InvariantCulture);139 140                    // Do validation of invalid direct variable assignments which are allowed to141                    // be used for parameters.142                    //143                    // Note - this is duplicated in ExecutionContext.cs as parameter binding for script cmdlets can avoid this code path.144                    if ((!bindingScriptCmdlet) && (!bindingParameters))145                    {146                        // ActionPreference.Suspend is reserved for future use and is not supported as a preference variable.147                        if (_convertTypes[i] == typeof(ActionPreference))148                        {149                            ActionPreference resultPreference = (ActionPreference)result;150 151                            if (resultPreference == ActionPreference.Suspend)152                            {153                                throw new PSInvalidCastException("InvalidActionPreference", null, ErrorPackage.ActionPreferenceReservedForFutureUseError, resultPreference);154                            }155                        }156                    }157                }158            }159            catch (PSInvalidCastException e)160            {161                throw new ArgumentTransformationMetadataException(e.Message, e);162            }163 164            // Track the flow of untrusted object during the conversion when it's called directly from ParameterBinderBase.165            // When it's called from the override Transform method, the tracking is taken care of in the base type.166            if (bindingParameters || bindingScriptCmdlet)167            {168                ExecutionContext.PropagateInputSource(inputData, result, engineIntrinsics.SessionState.Internal.LanguageMode);169            }170 171            return result;172        }173 174        private static void CheckBoolValue(object value, Type boolType)175        {176            if (value != null)177            {178                Type resultType = value.GetType();179 180                if (resultType == typeof(PSObject))181                    resultType = ((PSObject)value).BaseObject.GetType();182 183                if (!(LanguagePrimitives.IsNumeric(resultType.GetTypeCode()) ||184                      LanguagePrimitives.IsBoolOrSwitchParameterType(resultType)))185                {186                    ThrowPSInvalidBooleanArgumentCastException(resultType, boolType);187                }188            }189            else190            {191                bool isNullable = boolType.IsGenericType &&192                    boolType.GetGenericTypeDefinition() == typeof(Nullable<>);193 194                if (!isNullable && LanguagePrimitives.IsBooleanType(boolType))195                {196                    ThrowPSInvalidBooleanArgumentCastException(null, boolType);197                }198            }199        }200 201        internal static void ThrowPSInvalidBooleanArgumentCastException(Type resultType, Type convertType)202        {203            throw new PSInvalidCastException("InvalidCastExceptionUnsupportedParameterType", null,204                                  ExtendedTypeSystem.InvalidCastExceptionForBooleanArgumentValue,205                                  resultType, convertType);206        }207    }208}209