Пример #1
0
 /// <summary>
 /// Get the state of the buffer - the ast, tokens, errors, and position of the cursor
 /// </summary>
 public static void GetBufferState(out Ast ast, out Token[] tokens, out ParseError[] parseErrors, out int cursor)
 {
     _singleton.ParseInput();
     ast = _singleton._ast;
     tokens = _singleton._tokens;
     parseErrors = _singleton._parseErrors;
     cursor = _singleton._current;
 }
Пример #2
0
        /// <summary>
        /// Parse input from the specified file.
        /// </summary>
        /// <param name="fileName">The name of the file to parse.</param>
        /// <param name="tokens">Returns the tokens from parsing the script.</param>
        /// <param name="errors">Returns errors, if any, discovered while parsing the script.</param>
        /// <returns>The <see cref="ScriptBlockAst"/> that represents the input script file.</returns>
        public static ScriptBlockAst ParseFile(string fileName, out Token[] tokens, out ParseError[] errors)
        {
            const string scriptSchemaExtension = ".schema.psm1";
            var parseDscResource = false;
            // If the file has the 'schema.psm1' extension, then it is a 'DSC module file' however we don't actually load the
            // module at parse time so we can't use the normal mechanisms to bind the module name for configuration commands.
            // As an alternative, we extract the base name of the module file and use that as the module name for any keywords exported by this file.
            var parser = new Parser();
            if (!string.IsNullOrEmpty(fileName) && fileName.Length > scriptSchemaExtension.Length && fileName.EndsWith(scriptSchemaExtension, StringComparison.OrdinalIgnoreCase))
            {
                parser._keywordModuleName = Path.GetFileName(fileName.Substring(0, fileName.Length - scriptSchemaExtension.Length));
                parseDscResource = true;
            }

            string scriptContents;
            try
            {
                var esi = new ExternalScriptInfo(fileName, fileName);
                scriptContents = esi.ScriptContents;
            }
            catch (Exception e)
            {
                var emptyExtent = new EmptyScriptExtent();
                var errorMsg = string.Format(CultureInfo.CurrentCulture, ParserStrings.FileReadError, e.Message);
                errors = new[] { new ParseError(emptyExtent, "FileReadError", errorMsg) };
                tokens = Utils.EmptyArray<Token>();
                return new ScriptBlockAst(emptyExtent, null, new StatementBlockAst(emptyExtent, null, null), false);
            }

            var tokenList = new List<Token>();
            ScriptBlockAst result;
            try
            {
                if (!parseDscResource)
                {
                    DynamicKeyword.Push();
                }
                result = parser.Parse(fileName, scriptContents, tokenList, out errors, ParseMode.Default);
            }
            catch (Exception e)
            {
                throw new ParseException(ParserStrings.UnrecoverableParserError, e);
            }
            finally
            {
                if (!parseDscResource)
                {
                    DynamicKeyword.Pop();
                }
            }

            tokens = tokenList.ToArray();
            return result;
        }
        internal static ScriptFileMarker FromParseError(
            ParseError parseError)
        {
            Validate.IsNotNull("parseError", parseError);

            return new ScriptFileMarker
            {
                Message = parseError.Message,
                Level = ScriptFileMarkerLevel.Error,
                ScriptRegion = ScriptRegion.Create(parseError.Extent)
            };
        }
Пример #4
0
 public string FormatError(ParseError err)
 {
     return String.Format(
         "{0}({1},{2},{3},{4}): error {5}: {6}",
         err.Extent.File,
         err.Extent.StartLineNumber,
         err.Extent.StartColumnNumber,
         err.Extent.EndLineNumber,
         err.Extent.EndColumnNumber,
         err.ErrorId,
         err.Message);
 }
Пример #5
0
 public ParseException(ParseError[] errors)
 {
     if ((errors == null) || (errors.Length == 0))
     {
         throw new ArgumentNullException("errors");
     }
     this._errors = errors;
     base.SetErrorId(this._errors[0].ErrorId);
     base.SetErrorCategory(ErrorCategory.ParserError);
     if (errors[0].Extent != null)
     {
         this.ErrorRecord.SetInvocationInfo(new InvocationInfo(null, errors[0].Extent));
     }
 }
Пример #6
0
        public void LoadFile(string fileName)
        {
            Token[] tokens;
            ParseError[] localErrors=null;

            try
            {
                var ast = Parser.ParseFile(fileName, out tokens, out localErrors);
                errors.AddRange(localErrors);
            }
            catch (ParseException ex)
            {
                var pos = new ScriptPosition(fileName,0,0,"");
                var err = new ParseError(new ScriptExtent(pos, pos), "FatalParserError", GetNestedMessage(ex));
                errors.Add(err);
            }
        }
Пример #7
0
 internal ScriptBlockAst Parse(string fileName, string input, List<Token> tokenList, out ParseError[] errors)
 {
     ScriptBlockAst scriptBlockAst;
     try
     {
         scriptBlockAst = this.ParseTask(fileName, input, tokenList, false);
     }
     finally
     {
         errors = this._errorList.ToArray();
     }
     return scriptBlockAst;
 }
Пример #8
0
 internal PSParseError(ParseError error)
 {
     this._message = error.Message;
     this._psToken = new PSToken(error.Extent);
 }
Пример #9
0
        // This function performs semantic checks for all DSC Resources keywords.
        private static ParseError[] CheckMandatoryPropertiesPresent(DynamicKeywordStatementAst kwAst)
        {
            HashSet<string> mandatoryPropertiesNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
            foreach (var pair in kwAst.Keyword.Properties)
            {
                if (pair.Value.Mandatory)
                {
                    mandatoryPropertiesNames.Add(pair.Key);
                }
            }

            // by design mandatoryPropertiesNames are not empty at this point:
            // every resource must have at least one Key property.

            HashtableAst hashtableAst = null;
            foreach (var ast in kwAst.CommandElements)
            {
                hashtableAst = ast as HashtableAst;
                if (hashtableAst != null)
                {
                    break;
                }
            }

            if (hashtableAst == null)
            {
                // nothing to validate
                return null;
            }

            foreach (var pair in hashtableAst.KeyValuePairs)
            {
                object evalResultObject;
                if (IsConstantValueVisitor.IsConstant(pair.Item1, out evalResultObject, forAttribute: false, forRequires: false))
                {
                    var presentName = evalResultObject as string;
                    if (presentName != null)
                    {
                        if (mandatoryPropertiesNames.Remove(presentName) && mandatoryPropertiesNames.Count == 0)
                        {
                            // optimization, once all mandatory properties are specified, we can safely exit.
                            return null;
                        }
                    }
                }
            }

            if (mandatoryPropertiesNames.Count > 0)
            {
                ParseError[] errors = new ParseError[mandatoryPropertiesNames.Count];
                var extent = kwAst.CommandElements[0].Extent;
                int i = 0;
                foreach (string name in mandatoryPropertiesNames)
                {
                    errors[i] = new ParseError(extent, "MissingValueForMandatoryProperty",
                        string.Format(CultureInfo.CurrentCulture, ParserStrings.MissingValueForMandatoryProperty,
                                    kwAst.Keyword.Keyword, kwAst.Keyword.Properties.First(
                                        p => StringComparer.OrdinalIgnoreCase.Equals(p.Value.Name, name)).Value.TypeConstraint, name));
                    i++;
                }

                return errors;
            }

            return null;
        }
Пример #10
0
 private void SaveError(IScriptExtent extent, Expression<Func<string>> errorExpr, bool incompleteInput, object[] args)
 {
     string str = null;
     string name = null;
     MemberExpression body = errorExpr.Body as MemberExpression;
     if (body != null)
     {
         PropertyInfo member = body.Member as PropertyInfo;
         if (member != null)
         {
             MethodInfo getMethod = member.GetGetMethod(true);
             if (getMethod != null && getMethod.IsStatic && getMethod.ReturnType.Equals(typeof(string)))
             {
                 str = (string)getMethod.Invoke(null, null);
                 name = member.Name;
             }
         }
     }
     if (str == null)
     {
         str = errorExpr.Compile()();
         name = "ParserError";
     }
     if (args != null && args.Any<object>())
     {
         str = string.Format(CultureInfo.CurrentCulture, str, args);
     }
     ParseError parseError = new ParseError(extent, name, str, incompleteInput);
     this.SaveError(parseError);
 }
Пример #11
0
 private void SaveError(ParseError error)
 {
     Func<ParseError, bool> func = null;
     if (this._errorList.Any<ParseError>())
     {
         List<ParseError> parseErrors = this._errorList;
         if (func == null)
         {
             func = (ParseError err) =>
             {
                 if (!err.ErrorId.Equals(error.ErrorId, StringComparison.Ordinal) || err.Extent.EndColumnNumber != error.Extent.EndColumnNumber || err.Extent.EndLineNumber != error.Extent.EndLineNumber || err.Extent.StartColumnNumber != error.Extent.StartColumnNumber)
                 {
                     return false;
                 }
                 else
                 {
                     return err.Extent.StartLineNumber == error.Extent.StartLineNumber;
                 }
             }
             ;
         }
         if (parseErrors.Where<ParseError>(func).Any<ParseError>())
         {
             return;
         }
     }
     this._errorList.Add(error);
 }
Пример #12
0
 internal void ReportError(ParseError error)
 {
     this.SaveError(error);
 }
Пример #13
0
 internal PSParseError(Language.ParseError error)
 {
     Message = error.Message;
     Token   = new PSToken(error.Extent);
 }
 /// <summary>
 /// Tokonize the script and get the needed data.
 /// </summary>
 /// <param name="script">The active script.</param>
 /// <param name="tokens">The tokens to get.</param>
 /// <param name="errors">The parse errors to get.</param>
 /// <returns></returns>
 public static Ast Tokenize(string script, out Token[] tokens, out ParseError[] errors)
 {
     Ast result;
     try
     {
         Ast ast = System.Management.Automation.Language.Parser.ParseInput(script, out tokens, out errors);
         result = ast;
     }
     catch (RuntimeException ex)
     {
         var parseError = new ParseError(null, ex.ErrorRecord.FullyQualifiedErrorId, ex.Message);
         errors = new[] { parseError };
         tokens = new Token[0];
         result = null;
     }
     return result;
 }
        /// <summary>
        /// Parses the current file contents to get the AST, tokens,
        /// and parse errors.
        /// </summary>
        private void ParseFileContents()
        {
            ParseError[] parseErrors = null;

            try
            {
                this.ScriptAst =
                    Parser.ParseInput(
                        this.Contents, 
                        out this.scriptTokens, 
                        out parseErrors);
            }
            catch (RuntimeException ex)
            {
                var parseError = 
                    new ParseError(
                        null,
                        ex.ErrorRecord.FullyQualifiedErrorId, 
                        ex.Message);

                parseErrors = new[] { parseError };
                this.scriptTokens = new Token[0];
                this.ScriptAst = null;
            }

            // Translate parse errors into syntax markers
            this.SyntaxMarkers =
                parseErrors
                    .Select(ScriptFileMarker.FromParseError)
                    .ToArray();
            
            //Get all dot sourced referenced files and store  them
            this.ReferencedFiles =
                AstOperations.FindDotSourcedIncludes(this.ScriptAst);
        }
Пример #16
0
        private void SaveError(IScriptExtent extent, Expression<Func<string>> errorExpr, bool incompleteInput, params object[] args)
        {
            string errorMsg = null;
            string errorId = null;
            var memberExpression = errorExpr.Body as MemberExpression;
            if (memberExpression != null)
            {
                var propertyInfo = memberExpression.Member as PropertyInfo;
                if (propertyInfo != null)
                {
                    var getter = propertyInfo.GetMethod;
                    if (getter != null && getter.IsStatic && getter.ReturnType == typeof(string))
                    {
                        errorMsg = (string)getter.Invoke(null, null);
                        errorId = propertyInfo.Name;
                    }
                }
            }
            if (errorMsg == null)
            {
                errorMsg = errorExpr.Compile().Invoke();
                errorId = "ParserError";
            }

            if (args != null && args.Any())
            {
                errorMsg = string.Format(CultureInfo.CurrentCulture, errorMsg, args);
            }

            ParseError errorToSave = new ParseError(extent, errorId, errorMsg, incompleteInput);
            SaveError(errorToSave);
        }
Пример #17
0
        private void SaveError(ParseError error)
        {
            if (ErrorList.Any())
            {
                // Avoiding adding duplicate errors - can happen when the tokenizer resyncs.
                if (ErrorList.Any(err => err.ErrorId.Equals(error.ErrorId, StringComparison.Ordinal)
                                          && err.Extent.EndColumnNumber == error.Extent.EndColumnNumber
                                          && err.Extent.EndLineNumber == error.Extent.EndLineNumber
                                          && err.Extent.StartColumnNumber == error.Extent.StartColumnNumber
                                          && err.Extent.StartLineNumber == error.Extent.StartLineNumber))
                {
                    return;
                }
            }

            ErrorList.Add(error);
        }
Пример #18
0
 internal ScriptBlockAst Parse(string fileName, string input, List<Token> tokenList, out ParseError[] errors, ParseMode parseMode)
 {
     try
     {
         return ParseTask(fileName, input, tokenList, false, parseMode);
     }
     finally
     {
         errors = ErrorList.ToArray();
     }
 }
Пример #19
0
        /// <summary>
        /// Parse input that does not come from a file.
        /// </summary>
        /// <param name="input">The input to parse.</param>
        /// <param name="fileName">The fileName if present or null.</param>
        /// <param name="tokens">Returns the tokens from parsing the script.</param>
        /// <param name="errors">Returns errors, if any, discovered while parsing the script.</param>
        /// <returns>The <see cref="ScriptBlockAst"/> that represents the input script file.</returns>
        public static ScriptBlockAst ParseInput(string input, string fileName, out Token[] tokens, out ParseError[] errors)
        {
            Parser parser = new Parser();
            List<Token> tokenList = new List<Token>();
            ScriptBlockAst result;
            try
            {
                result = parser.Parse(fileName, input, tokenList, out errors, ParseMode.Default);
            }
            catch (Exception e)
            {
                throw new ParseException(ParserStrings.UnrecoverableParserError, e);
            }

            tokens = tokenList.ToArray();
            return result;
        }
Пример #20
0
 public ParseErrorEventArgs(ParseError[] parseErrors)
 {
     Errors = parseErrors;
 }
Пример #21
0
 public static ScriptBlockAst ParseFile(string fileName, out Token[] tokens, out ParseError[] errors)
 {
     ScriptBlockAst scriptBlockAst;
     Parser parser = new Parser();
     ExternalScriptInfo externalScriptInfo = new ExternalScriptInfo(fileName, fileName);
     List<Token> tokens1 = new List<Token>();
     try
     {
         scriptBlockAst = parser.Parse(fileName, externalScriptInfo.ScriptContents, tokens1, out errors);
     }
     catch (Exception exception1)
     {
         Exception exception = exception1;
         throw new ParseException(ParserStrings.UnrecoverableParserError, exception);
     }
     tokens = tokens1.ToArray();
     return scriptBlockAst;
 }
Пример #22
0
        private void PerformSecurityChecks()
        {
            var scriptBlockAst = Ast as ScriptBlockAst;
            if (scriptBlockAst == null)
            {
                // Checks are only needed at the top level.
                return;
            }

            // Call the AMSI API to determine if the script block has malicious content
            var scriptExtent = scriptBlockAst.Extent;
            if (AmsiUtils.ScanContent(scriptExtent.Text, scriptExtent.File) == AmsiUtils.AmsiNativeMethods.AMSI_RESULT.AMSI_RESULT_DETECTED)
            {
                var parseError = new ParseError(scriptExtent, "ScriptContainedMaliciousContent", ParserStrings.ScriptContainedMaliciousContent);
                throw new ParseException(new[] { parseError });
            }

            if (ScriptBlock.CheckSuspiciousContent(scriptBlockAst) != null)
            {
                HasSuspiciousContent = true;
            }
        }
Пример #23
0
 public static ScriptBlockAst ParseInput(string input, out Token[] tokens, out ParseError[] errors)
 {
     return Parser.ParseInput(input, null, out tokens, out errors);
 }
Пример #24
0
 internal static ScriptBlockAst ParseInput(string input, string fileName, out Token[] tokens, out ParseError[] errors)
 {
     ScriptBlockAst scriptBlockAst;
     Parser parser = new Parser();
     List<Token> tokens1 = new List<Token>();
     try
     {
         scriptBlockAst = parser.Parse(fileName, input, tokens1, out errors);
     }
     catch (Exception exception1)
     {
         Exception exception = exception1;
         throw new ParseException(ParserStrings.UnrecoverableParserError, exception);
     }
     tokens = tokens1.ToArray();
     return scriptBlockAst;
 }
Пример #25
0
 internal static Ast Tokenize(string script, out Token[] tokens, out ParseError[] errors)
 {
     Ast result;
     try
     {
         Token[] array;
         Ast ast = Parser.ParseInput(script, out array, out errors);
         tokens = new Token[array.Length - 1];
         Array.Copy(array, tokens, tokens.Length);
         result = ast;
     }
     catch (RuntimeException ex)
     {
         var parseError = new ParseError(new EmptyScriptExtent(), ex.ErrorRecord.FullyQualifiedErrorId, ex.Message);
         errors = new []{parseError};
         tokens = new Token[0];
         result = null;
     }
     return result;
 }