Exemplo n.º 1
0
        internal static CommandParameterInternal ToCommandParameterInternal(CommandParameter publicParameter, bool forNativeCommand)
        {
            string str2;

            if (publicParameter == null)
            {
                throw PSTraceSource.NewArgumentNullException("publicParameter");
            }
            string name = publicParameter.Name;
            object obj2 = publicParameter.Value;

            if (name == null)
            {
                return(CommandParameterInternal.CreateArgument(PositionUtilities.EmptyExtent, obj2, false));
            }
            if (!name[0].IsDash())
            {
                str2 = forNativeCommand ? name : ("-" + name);
                return(CommandParameterInternal.CreateParameterWithArgument(PositionUtilities.EmptyExtent, name, str2, PositionUtilities.EmptyExtent, obj2, true));
            }
            bool spaceAfterParameter = false;
            int  length = name.Length;

            while ((length > 0) && char.IsWhiteSpace(name[length - 1]))
            {
                spaceAfterParameter = true;
                length--;
            }
            str2 = name.Substring(0, length);
            bool   flag2         = name[length - 1] == ':';
            string parameterName = str2.Substring(1, str2.Length - (flag2 ? 2 : 1));

            if (!flag2 && (obj2 == null))
            {
                return(CommandParameterInternal.CreateParameter(PositionUtilities.EmptyExtent, parameterName, str2));
            }
            return(CommandParameterInternal.CreateParameterWithArgument(PositionUtilities.EmptyExtent, parameterName, str2, PositionUtilities.EmptyExtent, obj2, spaceAfterParameter));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Binds the specified parameters to the native command.
        /// </summary>
        /// <param name="parameters">
        /// The parameters to bind.
        /// </param>
        /// <param name="outputRedirected">
        /// true if minishell output is redirected.
        /// </param>
        /// <param name="hostName">
        /// name of the calling host.
        /// </param>
        /// <remarks>
        /// For any parameters that do not have a name, they are added to the command
        /// line arguments for the command
        /// </remarks>
        internal Collection<CommandParameterInternal> BindParameters(Collection<CommandParameterInternal> parameters, bool outputRedirected, string hostName)
        {
            MinishellParameters seen = 0;
            string inputFormat = null;
            string outputFormat = null;
            for (int i = 0; i < parameters.Count; i++)
            {
                var parameter = parameters[i];

                if (parameter.ParameterNameSpecified)
                {
                    var parameterName = parameter.ParameterName;

                    if (CommandParameter.StartsWith(parameterName, StringComparison.OrdinalIgnoreCase))
                    {
                        HandleSeenParameter(ref seen, MinishellParameters.Command, CommandParameter);

                        // Value must be specified for -Command parameter.
                        if (i + 1 >= parameters.Count)
                        {
                            throw NewParameterBindingException(null, ErrorCategory.InvalidArgument, CommandParameter,
                                                               typeof(ScriptBlock), null,
                                                               NativeCP.NoValueForCommandParameter,
                                                               "NoValueForCommandParameter");
                        }

                        i += 1;

                        // Value of -Command parameter must be scriptblock
                        var scriptBlockArgument = parameters[i];
                        var argumentValue = PSObject.Base(scriptBlockArgument.ArgumentValue);
                        if (!scriptBlockArgument.ArgumentSpecified || argumentValue is not ScriptBlock)
                        {
                            throw NewParameterBindingException(null, ErrorCategory.InvalidArgument, CommandParameter,
                                                               typeof(ScriptBlock), argumentValue.GetType(),
                                                               NativeCP.IncorrectValueForCommandParameter,
                                                               "IncorrectValueForCommandParameter");
                        }

                        // Replace the parameters with -EncodedCommand <base64 encoded scriptblock>
                        parameters[i - 1] = CommandParameterInternal.CreateParameter(EncodedCommandParameter, "-" + EncodedCommandParameter, parameter.ParameterAst);
                        string encodedScript = StringToBase64Converter.StringToBase64String(argumentValue.ToString());
                        parameters[i] = CommandParameterInternal.CreateArgument(encodedScript, scriptBlockArgument.ArgumentAst);
                    }
                    else if (InputFormatParameter.StartsWith(parameterName, StringComparison.OrdinalIgnoreCase))
                    {
                        HandleSeenParameter(ref seen, MinishellParameters.InputFormat, InputFormatParameter);

                        // Value for -Inputformat must be specified
                        if (i + 1 >= parameters.Count)
                        {
                            throw NewParameterBindingException(null, ErrorCategory.InvalidArgument, InputFormatParameter,
                                                               typeof(string), null,
                                                               NativeCP.NoValueForInputFormatParameter,
                                                               "NoValueForInputFormatParameter");
                        }

                        // Update the argument (partial arguments are allowed)
                        i += 1;
                        var inputFormatArg = parameters[i];
                        inputFormat = ProcessFormatParameterValue(InputFormatParameter, inputFormatArg.ArgumentValue);
                        parameters[i - 1] = CommandParameterInternal.CreateParameter(InputFormatParameter, "-" + InputFormatParameter, parameter.ParameterAst);
                        parameters[i] = CommandParameterInternal.CreateArgument(inputFormat, inputFormatArg.ArgumentAst);
                    }
                    else if (OutputFormatParameter.StartsWith(parameterName, StringComparison.OrdinalIgnoreCase))
                    {
                        HandleSeenParameter(ref seen, MinishellParameters.OutputFormat, OutputFormatParameter);

                        // Value for -Inputformat must be specified
                        if (i + 1 >= parameters.Count)
                        {
                            throw NewParameterBindingException(null, ErrorCategory.InvalidArgument, OutputFormatParameter,
                                                               typeof(string), null,
                                                               NativeCP.NoValueForOutputFormatParameter,
                                                               "NoValueForInputFormatParameter");
                        }

                        // Update the argument (partial arguments are allowed)
                        i += 1;
                        var outputFormatArg = parameters[i];
                        outputFormat = ProcessFormatParameterValue(OutputFormatParameter, outputFormatArg.ArgumentValue);
                        parameters[i - 1] = CommandParameterInternal.CreateParameter(OutputFormatParameter, "-" + OutputFormatParameter, parameter.ParameterAst);
                        parameters[i] = CommandParameterInternal.CreateArgument(outputFormat, outputFormatArg.ArgumentAst);
                    }
                    else if (ArgsParameter.StartsWith(parameterName, StringComparison.OrdinalIgnoreCase))
                    {
                        HandleSeenParameter(ref seen, MinishellParameters.Arguments, ArgsParameter);

                        // Value for -Args parameter must be specified
                        if (i + 1 >= parameters.Count)
                        {
                            throw NewParameterBindingException(null, ErrorCategory.InvalidArgument, ArgsParameter,
                                                               typeof(string), null, NativeCP.NoValuesSpecifiedForArgs,
                                                               "NoValuesSpecifiedForArgs");
                        }

                        // Get the encoded value for -args parameter
                        i += 1;
                        var argsArg = parameters[i];
                        var encodedArgs = ConvertArgsValueToEncodedString(argsArg.ArgumentValue);
                        parameters[i - 1] = CommandParameterInternal.CreateParameter(EncodedArgsParameter, "-" + EncodedArgsParameter, parameter.ParameterAst);
                        // NOTE: do not pass the ArgumentAst; it will fail validation in BindParameters if there
                        // are multiple arguments (array) but encodedArgs is an encoded string.
                        parameters[i] = CommandParameterInternal.CreateArgument(encodedArgs);
                    }
                }
                else
                {
                    // -Command is positional parameter. Bind first scriptblock to it, others are errors.
                    var scriptBlockArgument = parameters[i];
                    var argumentValue = PSObject.Base(scriptBlockArgument.ArgumentValue);
                    if (argumentValue is ScriptBlock)
                    {
                        HandleSeenParameter(ref seen, MinishellParameters.Command, CommandParameter);

                        // Replace the argument with -EncodedCommand <base64 encoded scriptblock>
                        string encodedScript = StringToBase64Converter.StringToBase64String(argumentValue.ToString());
                        parameters[i] = CommandParameterInternal.CreateParameterWithArgument(
                            parameter.ArgumentAst, EncodedCommandParameter, "-" + EncodedCommandParameter,
                            parameter.ArgumentAst, encodedScript,
                            spaceAfterParameter: true);
                    }
                }
            }

            // Add InputFormat and OutputFormat parameter if not specified
            if (inputFormat == null)
            {
                // For minishell default input format is xml
                parameters.Add(CommandParameterInternal.CreateParameter(InputFormatParameter, "-" + InputFormatParameter));
                parameters.Add(CommandParameterInternal.CreateArgument(XmlFormatValue));
                inputFormat = XmlFormatValue;
            }

            if (outputFormat == null)
            {
                // If output is redirected, output format should be xml
                outputFormat = outputRedirected ? XmlFormatValue : TextFormatValue;
                parameters.Add(CommandParameterInternal.CreateParameter(OutputFormatParameter, "-" + OutputFormatParameter));
                parameters.Add(CommandParameterInternal.CreateArgument(outputFormat));
            }

            // Set the output and input format class variable
            InputFormat = XmlFormatValue.StartsWith(inputFormat, StringComparison.OrdinalIgnoreCase)
                ? NativeCommandIOFormat.Xml
                : NativeCommandIOFormat.Text;
            OutputFormat = XmlFormatValue.StartsWith(outputFormat, StringComparison.OrdinalIgnoreCase)
                ? NativeCommandIOFormat.Xml
                : NativeCommandIOFormat.Text;

            // Note if a minishell is invoked from a non-console host, we need to
            // pass -nonInteractive flag. Our console host's name is "ConsoleHost".
            // Correct check would be see if current host has access to console and
            // pass noninteractive flag if doesn't.
            if (string.IsNullOrEmpty(hostName) || !hostName.Equals("ConsoleHost", StringComparison.OrdinalIgnoreCase))
            {
                NonInteractive = true;
                parameters.Insert(0, CommandParameterInternal.CreateParameter(NonInteractiveParameter, "-" + NonInteractiveParameter));
            }

            ((NativeCommandParameterBinder)DefaultParameterBinder).BindParameters(parameters);

            Diagnostics.Assert(s_emptyReturnCollection.Count == 0, "This list shouldn't be used for anything as it's shared.");

            return s_emptyReturnCollection;
        }
Exemplo n.º 3
0
        internal static CommandParameterInternal ToCommandParameterInternal(CommandParameter publicParameter, bool forNativeCommand)
        {
            if (publicParameter == null)
            {
                throw PSTraceSource.NewArgumentNullException(nameof(publicParameter));
            }

            string name  = publicParameter.Name;
            object value = publicParameter.Value;

            Debug.Assert((name == null) || (name.Trim().Length != 0), "Parameter name has to null or have some non-whitespace characters in it");

            if (name == null)
            {
                return(CommandParameterInternal.CreateArgument(value));
            }

            string parameterText;

            if (!name[0].IsDash())
            {
                parameterText = forNativeCommand ? name : "-" + name;
                return(CommandParameterInternal.CreateParameterWithArgument(
                           /*parameterAst*/ null, name, parameterText,
                           /*argumentAst*/ null, value,
                           true));
            }

            // if first character of name is '-', then we try to fake the original token
            // reconstructing dashes, colons and followed-by-space information

            // find the last non-whitespace character
            bool spaceAfterParameter = false;
            int  endPosition         = name.Length;

            while ((endPosition > 0) && char.IsWhiteSpace(name[endPosition - 1]))
            {
                spaceAfterParameter = true;
                endPosition--;
            }

            Debug.Assert(endPosition > 0, "parameter name should have some non-whitespace characters in it");

            // now make sure that parameterText doesn't have whitespace at the end,
            parameterText = name.Substring(0, endPosition);

            // parameterName should contain only the actual name of the parameter (no whitespace, colons, dashes)
            bool hasColon      = (name[endPosition - 1] == ':');
            var  parameterName = parameterText.Substring(1, parameterText.Length - (hasColon ? 2 : 1));

            // At this point we have rebuilt the token.  There are 3 strings that might be different:
            //           name = nameToken.Script = "-foo: " <- needed to fake FollowedBySpace=true (i.e. for "testecho.exe -a:b -c: d")
            // tokenString = nameToken.TokenText = "-foo:" <- needed to preserve full token text (i.e. for write-output)
            //                    nameToken.Data =  "foo" <- needed to preserve name of parameter so parameter binding works
            // Now we just need to use the token to build appropriate CommandParameterInternal object

            // is this a name+value pair, or is it just a name (of a parameter)?
            if (!hasColon && value == null)
            {
                // just a name
                return(CommandParameterInternal.CreateParameter(parameterName, parameterText));
            }

            // name+value pair
            return(CommandParameterInternal.CreateParameterWithArgument(
                       /*parameterAst*/ null, parameterName, parameterText,
                       /*argumentAst*/ null, value,
                       spaceAfterParameter));
        }