Skip to content

Commit

Permalink
Issue with cfqueryparam on more than a single line (#740)
Browse files Browse the repository at this point in the history
 If a cfqueryparam is on more than a single line, subsequent @CFLintIgnore lines are incorrect

closes #740
  • Loading branch information
ghedwards authored Aug 10, 2024
1 parent 7b9807d commit ddd5f2d
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 13 deletions.
82 changes: 70 additions & 12 deletions src/main/java/com/cflint/plugins/core/QueryParamChecker.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.StringReader;
import java.io.BufferedReader;

import com.cflint.BugList;
import com.cflint.CF;
Expand Down Expand Up @@ -36,18 +38,33 @@ public void element(final Element element, final Context context, final BugList
if (
element.getName().equalsIgnoreCase(CF.CFQUERY) && !CF.QUERY.equalsIgnoreCase(element.getAttributeValue(CF.DBTYPE))) {
String content = element.getContent().toString();
final String allowVariableExpression = context.getConfiguration().getParameter(this,"allowVariableExpression");
Pattern allowVariableExpressionPattern = null;
if ( !"".equals(allowVariableExpression) ) {
allowVariableExpressionPattern = Pattern.compile(allowVariableExpression,Pattern.DOTALL);
}
final String allowLineExpression = context.getConfiguration().getParameter(this,"allowLineExpression");
//Todo : cfparser/Jericho does not support parsing out the cfqueryparam very well.
// the following code will not work when there is a > sign in the expression
content = content.replaceAll("<[cC][fF][qQ][uU][eE][rR][yY][pP][aA][rR][aA][mM][^>]*>", "");
if (content.indexOf('#') >= 0) {
final List<Integer> ignoreLines = determineIgnoreLines(element);
final List<Integer> ignoreLines = determineIgnoreLines(content, context.startLine());
final Matcher matcher = Pattern.compile("#(?:##)?([^#]+)(?:##)?#($|[^#])",Pattern.DOTALL).matcher(content);
while (matcher.find()) {
if (matcher.groupCount() >= 1) {
int currentline = context.startLine() + countNewLinesUpTo(content, matcher.start());
String linecontent = content.split("\\R")[currentline-context.startLine()];
int currentOffset = element.getStartTag().getEnd() + 1 + matcher.start();
final String variableName = matcher.group(1);
if (!ignoreLines.contains(currentline)) {
String variableName = matcher.group(1);
Pattern allowLineExpressionPattern = null;
if ( !"".equals(allowLineExpression) ) {
//System.out.println(allowLineExpression.replaceAll("\\$\\{variable\\}","\\\\Q" + Matcher.quoteReplacement(variableName) + "\\\\E"));
allowLineExpressionPattern = Pattern.compile(allowLineExpression.replaceAll("\\$\\{variable\\}","\\\\Q" + Matcher.quoteReplacement(variableName) + "\\\\E"),Pattern.DOTALL);
}
if ( !ignoreLines.contains(currentline)
&& (allowVariableExpressionPattern == null || !allowVariableExpressionPattern.matcher(variableName).find())
&& (allowLineExpressionPattern == null || !allowLineExpressionPattern.matcher(linecontent).find())) {
//System.out.println("linecontent:" + linecontent);
context.addMessage("CFQUERYPARAM_REQ", variableName, currentline, currentOffset);
}
}
Expand All @@ -63,18 +80,59 @@ public void element(final Element element, final Context context, final BugList
* @param element the element object
* @return the line numbers of any @@CFLintIgnore annotations.
*/
private List<Integer> determineIgnoreLines(final Element element) {
private List<Integer> determineIgnoreLines(final String textContent, final int start ) {

final List<Integer> ignoreLines = new ArrayList<>();
for (Element comment : element.getChildElements()) {
if ("!---".equals(comment.getName()) && comment.toString().contains("@CFLintIgnore") && comment.toString().contains("CFQUERYPARAM_REQ")) {
int ignoreLine = comment.getSource().getRow(comment.getEnd());
ignoreLines.add(ignoreLine);
ignoreLines.add(ignoreLine + 1);
ignoreLines.add(comment.getSource().getRow(comment.getBegin()));
} else {
ignoreLines.addAll(determineIgnoreLines(comment));
int currentline = start;
String line = null;
List<Integer> tmpIgnoreLines = new ArrayList<>();
int match = 0;

BufferedReader bufReader = new BufferedReader(new StringReader(textContent));

try {
while( (line=bufReader.readLine()) != null )
{
if ( line.contains("!---") ) {
if (!tmpIgnoreLines.contains(currentline)) {
tmpIgnoreLines.add(currentline);
}
match = 1;
}

if ( line.contains("@CFLintIgnore") && match > 0 ) {
if (!tmpIgnoreLines.contains(currentline)) {
tmpIgnoreLines.add(currentline);
}
match = 2;
}

if ( line.contains("CFQUERYPARAM_REQ") && match > 1 ) {
if (!tmpIgnoreLines.contains(currentline)) {
tmpIgnoreLines.add(currentline);
}
match = 3;
}

if ( line.contains("--->") && match > 2 ) {
if (!tmpIgnoreLines.contains(currentline)) {
tmpIgnoreLines.add(currentline);
}
if (!tmpIgnoreLines.contains(currentline+1)) {
tmpIgnoreLines.add(currentline+1);
}
ignoreLines.addAll(tmpIgnoreLines);
tmpIgnoreLines.clear();
match = 0;
}

currentline++;

}
} catch(Exception e) {
e.printStackTrace();
}

return ignoreLines;
}

Expand Down
11 changes: 10 additions & 1 deletion src/main/resources/cflint.definition.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,16 @@
"severity": "WARNING"
}
],
"parameter": []
"parameter": [
{
"name": "allowVariableExpression",
"value": ""
},
{
"name": "allowLineExpression",
"value": ""
}
]
},
{
"name": "TypedQueryNew",
Expand Down
3 changes: 3 additions & 0 deletions src/test/java/com/cflint/TestCFBugs_QueryParams.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ public void testCFScript_QueryParams_ignore_offset() throws CFLintScanException
" ON C.aID = A.aID\n" +
" AND C.bar = #magicVal# <!--- \n" +
" @CFLintIgnore CFQUERYPARAM_REQ --->\n" +
" <!--- @CFLintIgnore CFQUERYPARAM_REQ --->\n" +
" #delim# C.bar = <cfqueryparam\n " +
" value='#magicVal#' /> \n" +
" WHERE \n" +
" <!---\n" +
" @CFLintIgnore CFQUERYPARAM_REQ\n" +
Expand Down

0 comments on commit ddd5f2d

Please sign in to comment.