Пример #1
0
        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());
        }
Пример #2
0
 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;
         }
         }
     }
 }
Пример #3
0
        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);
        }
Пример #5
0
        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);
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <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);
        }