private object DoGetValue(IDictionary dictionary, object index, ExecutionContext context) { IEnumerator enumerator = LanguagePrimitives.GetEnumerator(index); if (enumerator != null) { ArrayList arrayList = new ArrayList(); while (ParserOps.MoveNext(context, (Token)null, enumerator)) { try { arrayList.Add(dictionary[enumerator.Current]); } catch (Exception ex) { CommandProcessorBase.CheckForSevereException(ex); } } return((object)arrayList.ToArray()); } try { return(dictionary[index]); } catch (Exception ex) { CommandProcessorBase.CheckForSevereException(ex); return((object)null); } }
private object DoGetValue(Array array, object index, ExecutionContext context) { if (array.Rank > 1) { return(this.GetMultiArrayValue(array, index, context)); } IEnumerator enumerator = LanguagePrimitives.GetEnumerator(index); if (enumerator == null) { return(this.GetArrayElement(array, index, out bool _)); } ArrayList arrayList = new ArrayList(); while (ParserOps.MoveNext(context, this.NodeToken, enumerator)) { bool failed; object arrayElement = this.GetArrayElement(array, ParserOps.Current(this.NodeToken, enumerator), out failed); if (!failed) { arrayList.Add(arrayElement); } } return((object)arrayList.ToArray()); }
private void ValidateNullOrEmptyArgument(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, Type argumentType, object parameterValue, bool recurseIntoCollections) { if ((parameterValue == null) && (argumentType != typeof(bool?))) { if (!parameterMetadata.AllowsNullArgument) { bindingTracer.WriteLine("ERROR: Argument cannot be null", new object[0]); ParameterBindingValidationException exception = new ParameterBindingValidationException(ErrorCategory.InvalidData, this.InvocationInfo, this.GetErrorExtent(parameter), parameterMetadata.Name, argumentType, (parameterValue == null) ? null : parameterValue.GetType(), "ParameterBinderStrings", "ParameterArgumentValidationErrorNullNotAllowed", new object[0]); throw exception; } } else if (argumentType == typeof(string)) { string str = parameterValue as string; if ((str.Length == 0) && !parameterMetadata.AllowsEmptyStringArgument) { bindingTracer.WriteLine("ERROR: Argument cannot be an empty string", new object[0]); ParameterBindingValidationException exception2 = new ParameterBindingValidationException(ErrorCategory.InvalidData, this.InvocationInfo, this.GetErrorExtent(parameter), parameterMetadata.Name, parameterMetadata.Type, (parameterValue == null) ? null : parameterValue.GetType(), "ParameterBinderStrings", "ParameterArgumentValidationErrorEmptyStringNotAllowed", new object[0]); throw exception2; } } else if (recurseIntoCollections) { switch (parameterMetadata.CollectionTypeInformation.ParameterCollectionType) { case ParameterCollectionType.IList: case ParameterCollectionType.Array: case ParameterCollectionType.ICollectionGeneric: { IEnumerator enumerator = LanguagePrimitives.GetEnumerator(parameterValue); bool flag = true; while (ParserOps.MoveNext(null, null, enumerator)) { object obj2 = ParserOps.Current(null, enumerator); flag = false; this.ValidateNullOrEmptyArgument(parameter, parameterMetadata, parameterMetadata.CollectionTypeInformation.ElementType, obj2, false); } if (flag && !parameterMetadata.AllowsEmptyCollectionArgument) { bindingTracer.WriteLine("ERROR: Argument cannot be an empty collection", new object[0]); ParameterBindingValidationException exception3 = new ParameterBindingValidationException(ErrorCategory.InvalidData, this.InvocationInfo, this.GetErrorExtent(parameter), parameterMetadata.Name, parameterMetadata.Type, (parameterValue == null) ? null : parameterValue.GetType(), "ParameterBinderStrings", (parameterMetadata.CollectionTypeInformation.ParameterCollectionType == ParameterCollectionType.Array) ? "ParameterArgumentValidationErrorEmptyArrayNotAllowed" : "ParameterArgumentValidationErrorEmptyCollectionNotAllowed", new object[0]); throw exception3; } return; } } } }
private object GetMultiArrayValue(Array array, object index, ExecutionContext context) { IEnumerator enumerator = LanguagePrimitives.GetEnumerator(index); if (enumerator == null) { this.ReportIndexingError(array, index, (Exception)null); } Exception reason = (Exception)null; int[] numArray = (int[])null; try { numArray = (int[])LanguagePrimitives.ConvertTo(index, typeof(int[]), (IFormatProvider)NumberFormatInfo.InvariantInfo); } catch (InvalidCastException ex) { reason = (Exception)ex; } if (numArray != null) { if (numArray.Length != array.Rank) { this.ReportIndexingError(array, index, (Exception)null); } return(this.GetArrayElement(array, (object)numArray, out bool _)); } ArrayList arrayList = new ArrayList(); while (ParserOps.MoveNext(context, this.NodeToken, enumerator)) { if (ParserOps.Current(this.NodeToken, enumerator) is IList) { bool failed; object arrayElement = this.GetArrayElement(array, enumerator.Current, out failed); if (!failed) { arrayList.Add(arrayElement); } } else if (arrayList.Count == 0) { this.ReportIndexingError(array, index, reason); } } return((object)arrayList.ToArray()); }
internal static void appendOneNativeArgument(ExecutionContext context, StringBuilder argumentBuilder, bool needInitialSpace, object obj) { IEnumerator enumerator = LanguagePrimitives.GetEnumerator(obj); bool flag = needInitialSpace; do { string str; if (enumerator == null) { str = PSObject.ToStringParser(context, obj); } else { if (!ParserOps.MoveNext(context, null, enumerator)) { break; } str = PSObject.ToStringParser(context, ParserOps.Current(null, enumerator)); } if (!string.IsNullOrEmpty(str)) { if (flag) { argumentBuilder.Append(' '); } else { flag = true; } if (((str.IndexOfAny(whiteSpace) >= 0) && (str.Length > 1)) && (str[0] != '"')) { argumentBuilder.Append('"'); argumentBuilder.Append(str); argumentBuilder.Append('"'); } else { argumentBuilder.Append(str); } } }while (enumerator != null); }
private object GetItemPropertyValue(object obj, object index, ExecutionContext context) { IEnumerator enumerator = LanguagePrimitives.GetEnumerator(index); if (enumerator != null) { ArrayList arrayList = new ArrayList(); while (ParserOps.MoveNext(context, this.NodeToken, enumerator)) { try { object obj1 = this.GetItem(obj, enumerator.Current); arrayList.Add(obj1); } catch (Exception ex) { CommandProcessorBase.CheckForSevereException(ex); if (this.IsMethodNotFoundException(ex)) { throw InterpreterError.NewInterpreterExceptionWithInnerException(index, typeof(RuntimeException), this.NodeToken, "CannotIndex", ex, (object)obj.GetType().FullName); } } } return((object)arrayList.ToArray()); } try { return(this.GetItem(obj, index)); } catch (Exception ex) { CommandProcessorBase.CheckForSevereException(ex); if (this.IsMethodNotFoundException(ex)) { throw InterpreterError.NewInterpreterExceptionWithInnerException(index, typeof(RuntimeException), this.NodeToken, "CannotIndex", ex, (object)obj.GetType().FullName); } return((object)null); } }
private object DoGetValue(string str, object index, ExecutionContext context) { IEnumerator enumerator = LanguagePrimitives.GetEnumerator(index); if (enumerator != null) { ArrayList arrayList = new ArrayList(); while (ParserOps.MoveNext(context, this.NodeToken, enumerator)) { int index1 = ParserOps.FixNum(ParserOps.Current(this.NodeToken, enumerator), this.NodeToken); if (index1 < 0) { index1 += str.Length; } try { arrayList.Add((object)str[index1]); } catch (IndexOutOfRangeException ex) { } } return((object)arrayList.ToArray()); } int index2 = ParserOps.FixNum(index, this.NodeToken); if (index2 < 0) { index2 += str.Length; } try { return((object)str[index2]); } catch (IndexOutOfRangeException ex) { return((object)null); } }
/// <summary> /// Stringize a non-IEnum argument to a native command, adding quotes /// and trailing spaces as appropriate. An array gets added as multiple arguments /// each of which will be stringized. /// </summary> /// <param name="context">Execution context instance.</param> /// <param name="parameter">The parameter associated with the operation.</param> /// <param name="obj">The object to append.</param> /// <param name="argArrayAst">If the argument was an array literal, the Ast, otherwise null.</param> /// <param name="sawVerbatimArgumentMarker">True if the argument occurs after --%.</param> /// <param name="stringConstantType">Bare, SingleQuoted, or DoubleQuoted.</param> private void AppendOneNativeArgument(ExecutionContext context, CommandParameterInternal parameter, object obj, ArrayLiteralAst argArrayAst, bool sawVerbatimArgumentMarker, StringConstantType stringConstantType) { IEnumerator list = LanguagePrimitives.GetEnumerator(obj); Diagnostics.Assert((argArrayAst == null) || (obj is object[] && ((object[])obj).Length == argArrayAst.Elements.Count), "array argument and ArrayLiteralAst differ in number of elements"); int currentElement = -1; string separator = string.Empty; do { string arg; object currentObj; if (list == null) { arg = PSObject.ToStringParser(context, obj); currentObj = obj; } else { if (!ParserOps.MoveNext(context, null, list)) { break; } currentObj = ParserOps.Current(null, list); arg = PSObject.ToStringParser(context, currentObj); currentElement += 1; if (currentElement != 0) { separator = GetEnumerableArgSeparator(argArrayAst, currentElement); } } if (!string.IsNullOrEmpty(arg)) { // Only add the separator to the argument string rather than adding a separator to the ArgumentList. _arguments.Append(separator); if (sawVerbatimArgumentMarker) { arg = Environment.ExpandEnvironmentVariables(arg); _arguments.Append(arg); // we need to split the argument on spaces _argumentList.AddRange(arg.Split(' ', StringSplitOptions.RemoveEmptyEntries)); } else { // We need to add quotes if the argument has unquoted spaces. The // quotes could appear anywhere inside the string, not just at the start, // e.g. // $a = 'a"b c"d' // echoargs $a 'a"b c"d' a"b c"d // // The above should see 3 identical arguments in argv (the command line will // actually have quotes in different places, but the Win32 command line=>argv parser // erases those differences. // // We need to check quotes that the win32 argument parser checks which is currently // just the normal double quotes, no other special quotes. Also note that mismatched // quotes are supported if (NeedQuotes(arg)) { _arguments.Append('"'); if (stringConstantType == StringConstantType.DoubleQuoted) { _arguments.Append(ResolvePath(arg, Context)); AddToArgumentList(parameter, ResolvePath(arg, Context)); } else { _arguments.Append(arg); AddToArgumentList(parameter, arg); } // need to escape all trailing backslashes so the native command receives it correctly // according to http://www.daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULESDOC for (int i = arg.Length - 1; i >= 0 && arg[i] == '\\'; i--) { _arguments.Append('\\'); } _arguments.Append('"'); } else { if (argArrayAst != null && UseArgumentList) { // We have a literal array, so take the extent, break it on spaces and add them to the argument list. foreach (string element in argArrayAst.Extent.Text.Split(' ', StringSplitOptions.RemoveEmptyEntries)) { PossiblyGlobArg(element, parameter, stringConstantType); } break; } else { PossiblyGlobArg(arg, parameter, stringConstantType); } } } } else if (UseArgumentList && currentObj != null) { // add empty strings to arglist, but not nulls AddToArgumentList(parameter, arg); } }while (list != null); }
/// <summary> /// Stringize a non-IEnum argument to a native command, adding quotes /// and trailing spaces as appropriate. An array gets added as multiple arguments /// each of which will be stringized. /// </summary> /// <param name="context">Execution context instance</param> /// <param name="obj">The object to append</param> /// <param name="argArrayAst">If the argument was an array literal, the Ast, otherwise null</param> /// <param name="sawVerbatimArgumentMarker">true if the argument occurs after --%</param> /// <param name="usedQuotes">True if the argument was a quoted string (single or double)</param> private void appendOneNativeArgument(ExecutionContext context, object obj, ArrayLiteralAst argArrayAst, bool sawVerbatimArgumentMarker, bool usedQuotes) { IEnumerator list = LanguagePrimitives.GetEnumerator(obj); Diagnostics.Assert(argArrayAst == null || obj is object[] && ((object[])obj).Length == argArrayAst.Elements.Count, "array argument and ArrayLiteralAst differ in number of elements"); int currentElement = -1; string separator = ""; do { string arg; if (list == null) { arg = PSObject.ToStringParser(context, obj); } else { if (!ParserOps.MoveNext(context, null, list)) { break; } arg = PSObject.ToStringParser(context, ParserOps.Current(null, list)); currentElement += 1; if (currentElement != 0) { separator = GetEnumerableArgSeparator(argArrayAst, currentElement); } } if (!String.IsNullOrEmpty(arg)) { _arguments.Append(separator); if (sawVerbatimArgumentMarker) { arg = Environment.ExpandEnvironmentVariables(arg); _arguments.Append(arg); } else { // We need to add quotes if the argument has unquoted spaces. The // quotes could appear anywhere inside the string, not just at the start, // e.g. // $a = 'a"b c"d' // echoargs $a 'a"b c"d' a"b c"d // // The above should see 3 identical arguments in argv (the command line will // actually have quotes in different places, but the Win32 command line=>argv parser // erases those differences. // // We need to check quotes that the win32 argument parser checks which is currently // just the normal double quotes, no other special quotes. Also note that mismatched // quotes are supported if (NeedQuotes(arg)) { _arguments.Append('"'); // need to escape all trailing backslashes so the native command receives it correctly // according to http://www.daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULESDOC _arguments.Append(arg); for (int i = arg.Length - 1; i >= 0 && arg[i] == '\\'; i--) { _arguments.Append('\\'); } _arguments.Append('"'); } else { PossiblyGlobArg(arg, usedQuotes); } } } } while (list != null); }
/// <summary> /// Stringize a non-IEnum argument to a native command, adding quotes /// and trailing spaces as appropriate. An array gets added as multiple arguments /// each of which will be stringized. /// </summary> /// <param name="context">Execution context instance</param> /// <param name="obj">The object to append</param> /// <param name="separator">A space or comma used when obj is enumerable</param> /// <param name="sawVerbatimArgumentMarker">true if the argument occurs after --%</param> private void appendOneNativeArgument(ExecutionContext context, object obj, char separator, bool sawVerbatimArgumentMarker) { IEnumerator list = LanguagePrimitives.GetEnumerator(obj); bool needSeparator = false; do { string arg; if (list == null) { arg = PSObject.ToStringParser(context, obj); } else { if (!ParserOps.MoveNext(context, null, list)) { break; } arg = PSObject.ToStringParser(context, ParserOps.Current(null, list)); } if (!String.IsNullOrEmpty(arg)) { if (needSeparator) { _arguments.Append(separator); } else { needSeparator = true; } if (sawVerbatimArgumentMarker) { arg = Environment.ExpandEnvironmentVariables(arg); _arguments.Append(arg); } else { // We need to add quotes if the argument has unquoted spaces. The // quotes could appear anywhere inside the string, not just at the start, // e.g. // $a = 'a"b c"d' // echoargs $a 'a"b c"d' a"b c"d // // The above should see 3 identical arguments in argv (the command line will // actually have quotes in different places, but the Win32 command line=>argv parser // erases those differences. // // We need to check quotes that the win32 argument parser checks which is currently // just the normal double quotes, no other special quotes. Also note that mismatched // quotes are supported if (NeedQuotes(arg)) { _arguments.Append('"'); _arguments.Append(arg); _arguments.Append('"'); } else { #if UNIX // On UNIX systems, we expand arguments containing wildcard expressions against // the file system just like bash, etc. if (System.Management.Automation.WildcardPattern.ContainsWildcardCharacters(arg)) { // See if the current working directory is a filesystem provider location // We won't do the expansion if it isn't since native commands can only access the file system. var cwdinfo = Context.EngineSessionState.CurrentLocation; // If it's a filesystem location then expand the wildcards if (string.Equals(cwdinfo.Provider.Name, Microsoft.PowerShell.Commands.FileSystemProvider.ProviderName, StringComparison.OrdinalIgnoreCase)) { bool normalizePath = true; // On UNIX, paths starting with ~ are not normalized if (arg.Length > 0 && arg[0] == '~') { normalizePath = false; } // See if there are any matching paths otherwise just add the pattern as the argument var paths = Context.EngineSessionState.InvokeProvider.ChildItem.Get(arg, false); if (paths.Count > 0) { bool first = true; foreach (var path in paths) { object pbo = path.BaseObject; if (!first) { _arguments.Append(" "); } else { if (!(pbo is System.IO.FileSystemInfo)) { // If the object is not a filesystem object, then just append // the pattern unchanged _arguments.Append(arg); break; } first = false; } var expandedPath = (pbo as System.IO.FileSystemInfo).FullName; if (normalizePath) { expandedPath = Context.SessionState.Path.NormalizeRelativePath(expandedPath, cwdinfo.ProviderPath); } // If the path contains spaces, then add quotes around it. if (NeedQuotes(expandedPath)) { _arguments.Append("\""); _arguments.Append(expandedPath); _arguments.Append("\""); } else { _arguments.Append(expandedPath); } } } else { _arguments.Append(arg); } } else { _arguments.Append(arg); } } else { // Even if there are no wildcards, we still need to possibly // expand ~ into the filesystem provider home directory path ProviderInfo fileSystemProvider = Context.EngineSessionState.GetSingleProvider( Microsoft.PowerShell.Commands.FileSystemProvider.ProviderName); string home = fileSystemProvider.Home; if (string.Equals(arg, "~")) { _arguments.Append(home); } else if (arg.StartsWith("~/", StringComparison.OrdinalIgnoreCase)) { var replacementString = home + arg.Substring(1); _arguments.Append(replacementString); } else { _arguments.Append(arg); } } #else _arguments.Append(arg); #endif } } } } while (list != null); }
/// <summary> /// Stringize a non-IEnum argument to a native command, adding quotes /// and trailing spaces as appropriate. An array gets added as multiple arguments /// each of which will be stringized. /// </summary> /// <param name="context">Execution context instance</param> /// <param name="obj">The object to append</param> /// <param name="separator">A space or comma used when obj is enumerable</param> /// <param name="sawVerbatimArgumentMarker">true if the argument occurs after --%</param> private void appendOneNativeArgument(ExecutionContext context, object obj, char separator, bool sawVerbatimArgumentMarker) { IEnumerator list = LanguagePrimitives.GetEnumerator(obj); bool needSeparator = false; do { string arg; if (list == null) { arg = PSObject.ToStringParser(context, obj); } else { if (!ParserOps.MoveNext(context, null, list)) { break; } arg = PSObject.ToStringParser(context, ParserOps.Current(null, list)); } if (!String.IsNullOrEmpty(arg)) { if (needSeparator) { _arguments.Append(separator); } else { needSeparator = true; } if (sawVerbatimArgumentMarker) { arg = Environment.ExpandEnvironmentVariables(arg); _arguments.Append(arg); } else { // We need to add quotes if the argument has unquoted spaces. The // quotes could appear anywhere inside the string, not just at the start, // e.g. // $a = 'a"b c"d' // echoargs $a 'a"b c"d' a"b c"d // // The above should see 3 identical arguments in argv (the command line will // actually have quotes in different places, but the Win32 command line=>argv parser // erases those differences. // // We need to check quotes that the win32 arugment parser checks which is currently // just the normal double quotes, no other special quotes. Also note that mismatched // quotes are supported. bool needQuotes = false; int quoteCount = 0; for (int i = 0; i < arg.Length; i++) { if (arg[i] == '"') { quoteCount += 1; } else if (char.IsWhiteSpace(arg[i]) && (quoteCount % 2 == 0)) { needQuotes = true; } } if (needQuotes) { _arguments.Append('"'); _arguments.Append(arg); _arguments.Append('"'); } else { _arguments.Append(arg); } } } } while (list != null); }