public static MatchesConditionPattern()

in DevSkim-VSCode-Plugin/server/src/devskimWorker.ts [489:548]


    public static MatchesConditionPattern(condition: Condition, documentContents: string, findingRange: Range, langID: string): boolean
    {
        let regionRegex: RegExp = /finding-region\s*\((-*\d+),\s*(-*\d+)\s*\)/;
        let XRegExp = require('xregexp');

        if (condition.negate_finding == undefined)
        {
            condition.negate_finding = false;
        }

        let modifiers: string[] = (condition.pattern.modifiers != undefined && condition.pattern.modifiers.length > 0) ?
            condition.pattern.modifiers.concat(["g"]) : ["g"];

        let conditionRegex: RegExp = DevSkimWorker.MakeRegex(condition.pattern.type, condition.pattern.pattern, modifiers, true);

        let startPos: number = findingRange.start.line;
        let endPos: number = findingRange.end.line;

        //calculate where to look for the condition.  finding-only is just within the actual finding the original pattern flagged.
        //finding-region(#,#) specifies an area around the finding.  A 0 for # means the line of the finding, negative values mean 
        //that many lines prior to the finding, and positive values mean that many line later in the code
        if (condition.search_in == undefined || condition.search_in.length == 0) 
        {
            startPos = DocumentUtilities.GetDocumentPosition(documentContents, findingRange.start.line);
            endPos = DocumentUtilities.GetDocumentPosition(documentContents, findingRange.end.line + 1);
        }
        else if (condition.search_in == "finding-only") 
        {
            startPos = DocumentUtilities.GetDocumentPosition(documentContents, findingRange.start.line) + findingRange.start.character;
            endPos = DocumentUtilities.GetDocumentPosition(documentContents, findingRange.end.line) + findingRange.end.character;
        }
        else 
        {
            let regionMatch = XRegExp.exec(condition.search_in, regionRegex);
            if (regionMatch && regionMatch.length > 2) 
            {
                startPos = DocumentUtilities.GetDocumentPosition(documentContents, findingRange.start.line + +regionMatch[1]);
                endPos = DocumentUtilities.GetDocumentPosition(documentContents, findingRange.end.line + +regionMatch[2] + 1);
            }
        }
        //go through all of the text looking for a match with the given pattern
        let subContents = documentContents.substring(startPos,endPos);
        let match = XRegExp.exec(subContents, conditionRegex, 0);
        while (match) 
        {
            //calculate what line we are on by grabbing the text before the match & counting the newlines in it
            let lineStart: number = DocumentUtilities.GetLineNumber(documentContents, match.index);
            let newlineIndex: number = (lineStart == 0) ? -1 : documentContents.substr(0, match.index).lastIndexOf("\n");

            //look for the suppression comment for that finding
            if (DocumentUtilities.MatchIsInScope(langID, documentContents.substr(0, match.index), newlineIndex, condition.pattern.scopes)) 
            {
                return condition.negate_finding ? false : true;
            }
            
            match = XRegExp.exec(subContents.substr(match.index + match[0].length), conditionRegex, 0);
        }

        return condition.negate_finding ? true : false;
    }