Example #1
0
        public Suppression(TextContainer text, int lineNumber)
        {
            if (text is null)
            {
                throw new ArgumentNullException("text");
            }
            _text       = text;
            _lineNumber = lineNumber;
            _lineText   = _text.GetLineContent(_lineNumber);

            ParseLine();
        }
Example #2
0
        /// <summary>
        /// Parse the line of code to find rule suppressors
        /// </summary>
        private void ParseLine()
        {
            if (_text != null)
            {
                _lineText = _text.GetLineContent(_lineNumber);
                // If the line with the issue doesn't contain a suppression check the lines above it
                if (!_lineText.Contains(KeywordPrefix))
                {
                    if (_lineNumber > 1)
                    {
                        var content = _text.GetLineContent(--_lineNumber);
                        if (content.Contains(Language.GetCommentSuffix(_text.Language)))
                        {
                            while (_lineNumber >= 1)
                            {
                                if (reg.IsMatch(_text.GetLineContent(_lineNumber)))
                                {
                                    _lineText = _text.GetLineContent(_lineNumber);
                                    break;
                                }
                                else if (_text.GetLineContent(_lineNumber).Contains(Language.GetCommentPrefix(_text.Language)))
                                {
                                    break;
                                }
                                _lineNumber--;
                            }
                        }
                        else if (content.Contains(Language.GetCommentInline(_text.Language)))
                        {
                            _lineText = content;
                        }
                    }
                }
            }

            Match match = reg.Match(_lineText);

            if (match.Success)
            {
                _suppressStart  = match.Index;
                _suppressLength = match.Length;

                string idString = match.Groups[1].Value.Trim();
                IssuesListIndex = match.Groups[1].Index;

                // Parse date
                if (match.Groups.Count > 2)
                {
                    string date = match.Groups[2].Value;
                    reg = new Regex(@"(\d{4}-\d{2}-\d{2})");
                    Match m = reg.Match(date);
                    if (m.Success)
                    {
                        try
                        {
                            _expirationDate = DateTime.ParseExact(m.Value, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
                        }
                        catch (FormatException)
                        {
                            _expirationDate = DateTime.MinValue;
                        }
                    }
                }

                // parse Ids.
                if (idString == KeywordAll)
                {
                    _issues.Add(new SuppressedIssue()
                    {
                        ID       = KeywordAll,
                        Boundary = new Boundary()
                        {
                            Index  = IssuesListIndex,
                            Length = KeywordAll.Length
                        }
                    });
                }
                else
                {
                    string[] ids   = idString.Split(',');
                    int      index = IssuesListIndex;
                    foreach (string id in ids)
                    {
                        _issues.Add(new SuppressedIssue()
                        {
                            ID       = id,
                            Boundary = new Boundary()
                            {
                                Index  = index,
                                Length = id.Length
                            }
                        });
                        index += id.Length + 1;
                    }
                }
            }
        }
Example #3
0
        /// <summary>
        /// Analyzes given line of code
        /// </summary>
        /// <param name="text">Source code</param>
        /// <param name="languages">List of languages</param>
        /// <returns>Array of matches</returns>
        public Issue[] Analyze(string text, string[] languages)
        {
            // Get rules for the given content type
            IEnumerable <Rule> rules         = GetRulesForLanguages(languages);
            List <Issue>       resultsList   = new List <Issue>();
            TextContainer      textContainer = new TextContainer(text, (languages.Length > 0) ? languages[0] : string.Empty);

            // Go through each rule
            foreach (Rule rule in rules)
            {
                List <Issue> matchList = new List <Issue>();

                // Skip rules that don't apply based on settings
                if (rule.Disabled || !SeverityLevel.HasFlag(rule.Severity))
                {
                    continue;
                }

                // Go through each matching pattern of the rule
                foreach (SearchPattern pattern in rule.Patterns)
                {
                    // Get all matches for the patttern
                    List <Boundary> matches = textContainer.MatchPattern(pattern);

                    if (matches.Count > 0)
                    {
                        foreach (Boundary match in matches)
                        {
                            bool passedConditions = true;
                            foreach (SearchCondition condition in rule.Conditions)
                            {
                                bool res = textContainer.MatchPattern(condition.Pattern, match, condition);
                                if (res && condition.NegateFinding)
                                {
                                    passedConditions = false;
                                    break;
                                }
                                if (!res && condition.NegateFinding)
                                {
                                    passedConditions = true;
                                    break;
                                }
                                if (!res)
                                {
                                    passedConditions = false;
                                    break;
                                }
                            }

                            if (passedConditions)
                            {
                                Issue issue = new Issue()
                                {
                                    Boundary      = match,
                                    StartLocation = textContainer.GetLocation(match.Index),
                                    EndLocation   = textContainer.GetLocation(match.Index + match.Length),
                                    Rule          = rule
                                };

                                matchList.Add(issue);
                            }
                        }
                    }
                }

                // We got matching rule and suppression are enabled,
                // let's see if we have a supression on the line
                if (EnableSuppressions && matchList.Count > 0)
                {
                    Suppression supp;
                    foreach (Issue result in matchList)
                    {
                        supp = new Suppression(textContainer.GetLineContent(result.StartLocation.Line));
                        // If rule is NOT being suppressed then report it
                        SuppressedIssue supissue = supp.GetSuppressedIssue(result.Rule.Id);
                        if (supissue == null)
                        {
                            resultsList.Add(result);
                        }
                        // Otherwise add the suppression info instead
                        else
                        {
                            Boundary bound = textContainer.GetLineBoundary(result.Boundary.Index);
                            bound.Index += supissue.Boundary.Index;
                            bound.Length = supissue.Boundary.Length;

                            //resultsList.Add();
                            Issue info = new Issue()
                            {
                                IsSuppressionInfo = true,
                                Boundary          = bound,
                                StartLocation     = textContainer.GetLocation(bound.Index),
                                EndLocation       = textContainer.GetLocation(bound.Index + bound.Length),
                                Rule = result.Rule
                            };

                            // Add info only if it's not exists on the same location
                            if (resultsList.FirstOrDefault(x => x.Rule.Id == info.Rule.Id && x.Boundary.Index == info.Boundary.Index) == null)
                            {
                                resultsList.Add(info);
                            }
                        }
                    }
                }
                // Otherwise put matchlist to resultlist
                else
                {
                    resultsList.AddRange(matchList);
                }
            }

            // Deal with overrides
            List <Issue> removes = new List <Issue>();

            foreach (Issue m in resultsList)
            {
                if (m.Rule.Overrides != null && m.Rule.Overrides.Length > 0)
                {
                    foreach (string ovrd in m.Rule.Overrides)
                    {
                        // Find all overriden rules and mark them for removal from issues list
                        foreach (Issue om in resultsList.FindAll(x => x.Rule.Id == ovrd))
                        {
                            if (om.Boundary.Index >= m.Boundary.Index &&
                                om.Boundary.Index <= m.Boundary.Index + m.Boundary.Length)
                            {
                                removes.Add(om);
                            }
                        }
                    }
                }
            }

            // Remove overriden rules
            resultsList.RemoveAll(x => removes.Contains(x));

            return(resultsList.ToArray());
        }