Search in sources :

Example 6 with CFExpression

use of cfml.parsing.cfscript.CFExpression in project CFLint by cflint.

the class VariableNameChecker method expression.

@Override
public void expression(final CFExpression expression, final Context context, final BugList bugs) {
    if (expression instanceof CFVarDeclExpression) {
        final CFVarDeclExpression cfVarDeclExpression = (CFVarDeclExpression) expression;
        final int lineNo = expression.getLine() + context.startLine() - 1;
        final String varName = cfVarDeclExpression.getName();
        checkNameForBugs(context, varName, varName, context.getFilename(), context.getFunctionName(), lineNo, bugs);
    } else if (expression instanceof CFFullVarExpression) {
        final CFFullVarExpression cfFullVarExpression = (CFFullVarExpression) expression;
        for (final CFExpression subexpression : cfFullVarExpression.getExpressions()) {
            if (subexpression instanceof CFIdentifier) {
                final String varName = ((CFIdentifier) subexpression).getName();
                final int lineNo = ((CFIdentifier) subexpression).getLine() + context.startLine() - 1;
                checkNameForBugs(context, cfFullVarExpression.Decompile(0), varName, context.getFilename(), context.getFunctionName(), lineNo, bugs);
            }
        }
    } else if (expression instanceof CFIdentifier) {
        final String varName = ((CFIdentifier) expression).getName();
        final int lineNo = ((CFIdentifier) expression).getLine() + context.startLine() - 1;
        checkNameForBugs(context, varName, varName, context.getFilename(), context.getFunctionName(), lineNo, bugs);
    }
}
Also used : CFVarDeclExpression(cfml.parsing.cfscript.CFVarDeclExpression) CFIdentifier(cfml.parsing.cfscript.CFIdentifier) CFFullVarExpression(cfml.parsing.cfscript.CFFullVarExpression) CFExpression(cfml.parsing.cfscript.CFExpression)

Example 7 with CFExpression

use of cfml.parsing.cfscript.CFExpression in project CFLint by cflint.

the class QueryParamChecker method expression.

@Override
public void expression(final CFExpression expression, final Context context, final BugList bugs) {
    if (expression instanceof CFFunctionExpression) {
        final CFFunctionExpression functionExpression = (CFFunctionExpression) expression;
        if ("setSql".equalsIgnoreCase(functionExpression.getFunctionName()) && !functionExpression.getArgs().isEmpty()) {
            final CFExpression argsExpression = functionExpression.getArgs().get(0);
            final Pattern p = Pattern.compile(".*#[^#].*", Pattern.DOTALL);
            if (p.matcher(argsExpression.Decompile(0)).matches()) {
                context.addMessage("QUERYPARAM_REQ", functionExpression.getName());
            }
        }
    }
}
Also used : Pattern(java.util.regex.Pattern) CFFunctionExpression(cfml.parsing.cfscript.CFFunctionExpression) CFExpression(cfml.parsing.cfscript.CFExpression)

Example 8 with CFExpression

use of cfml.parsing.cfscript.CFExpression in project CFLint by cflint.

the class CFLint method reportRule.

public void reportRule(final Element elem, final Object currentExpression, final Context context, final CFLintScanner pluginParm, final ContextMessage msg) {
    final Object expression = msg.getCfExpression() != null ? msg.getCfExpression() : currentExpression;
    // If we are processing includes, do NOT report any errors
    if (!includeFileStack.isEmpty()) {
        return;
    }
    final String msgcode = msg.getMessageCode();
    final String nameVar = msg.getVariable();
    final CFLintScanner plugin = msg.getSource() == null ? pluginParm : msg.getSource();
    if (checkForDisabled(elem, msgcode)) {
        return;
    }
    if (configuration == null) {
        throw new NullPointerException("Configuration is null");
    }
    PluginInfoRule ruleInfo;
    if (MISSING_SEMI.equals(msgcode)) {
        ruleInfo = new PluginInfoRule();
        final PluginMessage msgInfo = new PluginMessage(MISSING_SEMI);
        msgInfo.setMessageText("End of statement(;) expected after ${variable}");
        msgInfo.setSeverity(Levels.ERROR);
        ruleInfo.getMessages().add(msgInfo);
    } else if (PLUGIN_ERROR.equals(msgcode)) {
        ruleInfo = new PluginInfoRule();
        final PluginMessage msgInfo = new PluginMessage(PLUGIN_ERROR);
        msgInfo.setMessageText("Error in plugin: ${variable}");
        msgInfo.setSeverity(Levels.ERROR);
        ruleInfo.getMessages().add(msgInfo);
    } else if (AVOID_EMPTY_FILES.equals(msgcode)) {
        ruleInfo = new PluginInfoRule();
        final PluginMessage msgInfo = new PluginMessage(AVOID_EMPTY_FILES);
        msgInfo.setMessageText("CF file is empty: ${file}");
        msgInfo.setSeverity(Levels.WARNING);
        ruleInfo.getMessages().add(msgInfo);
    } else if (PARSE_ERROR.equals(msgcode)) {
        ruleInfo = new CFLintPluginInfo.PluginInfoRule();
        final CFLintPluginInfo.PluginInfoRule.PluginMessage msgInfo = new CFLintPluginInfo.PluginInfoRule.PluginMessage(PARSE_ERROR);
        msgInfo.setMessageText("Unable to parse");
        msgInfo.setSeverity(Levels.ERROR);
        ruleInfo.getMessages().add(msgInfo);
    } else {
        if (plugin == null) {
            throw new NullPointerException("Plugin not set.  Plugin should be using addMessage(messageCode,variable,source) to report messages in parent contexts");
        }
        ruleInfo = configuration.getRuleForPlugin(plugin);
    }
    if (ruleInfo == null) {
        throw new NullPointerException("Rule not found for " + plugin.getClass().getSimpleName());
    }
    final PluginMessage msgInfo = ruleInfo.getMessageByCode(msgcode);
    if (msgInfo == null) {
        throw new NullPointerException("Message definition not found for [" + msgcode + "] in " + plugin.getClass().getSimpleName());
    }
    final BugInfoBuilder bldr = new BugInfo.BugInfoBuilder().setMessageCode(msgcode).setVariable(nameVar).setFunction(context.getFunctionName()).setFilename(context.getFilename()).setComponent(context.getComponentName());
    bldr.setSeverity(msgInfo.getSeverity());
    bldr.setMessage(msgInfo.getMessageText());
    if (expression instanceof CFStatement) {
        bldr.setExpression(((CFStatement) expression).Decompile(0));
    } else if (expression instanceof CFScriptStatement) {
        bldr.setExpression(((CFScriptStatement) expression).Decompile(0));
    } else if (elem != null) {
        bldr.setExpression(elem.toString().replaceAll("\r\n", "\n"));
    }
    bldr.setRuleParameters(ruleInfo.getParameters());
    if (configuration.includes(ruleInfo.getMessageByCode(msgcode)) && !configuration.excludes(ruleInfo.getMessageByCode(msgcode))) {
        if (expression instanceof CFExpression) {
            final BugInfo bugInfo = bldr.build((CFExpression) expression, elem);
            final Token token = ((CFExpression) expression).getToken();
            if (!suppressed(bugInfo, token, context)) {
                bugs.add(bugInfo);
            }
            // If the context expression is attached, use the context line and column
            if (msg.getCfExpression() != null && msg.getCfExpression() != currentExpression) {
                if (msg.getLine() != null) {
                    bugInfo.setLine(msg.getLine());
                    if (msg.getOffset() != null) {
                        bugInfo.setOffset(msg.getOffset());
                        bugInfo.setColumn(msg.getOffset() - lineOffsets[msg.getLine() - 1]);
                    } else {
                        bugInfo.setOffset(lineOffsets != null ? lineOffsets[msg.getLine() - 1] : 0);
                        bugInfo.setColumn(0);
                    }
                }
            }
        } else {
            final BugInfo bug = bldr.build((CFScriptStatement) expression, elem);
            if (msg.getLine() != null) {
                bug.setLine(msg.getLine());
                if (msg.getOffset() != null) {
                    bug.setOffset(msg.getOffset());
                    bug.setColumn(msg.getOffset() - lineOffsets[msg.getLine() - 1]);
                } else {
                    bug.setOffset(lineOffsets != null ? lineOffsets[msg.getLine() - 1] : 0);
                    bug.setColumn(0);
                }
                bug.setLength(msg.getVariable() != null ? msg.getVariable().length() : 0);
            }
            if (!suppressed(bug, expression == null ? null : ((CFScriptStatement) expression).getToken(), context)) {
                bugs.add(bug);
            }
        }
    }
}
Also used : PluginMessage(com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginMessage) CFLintScanner(com.cflint.plugins.CFLintScanner) Token(org.antlr.v4.runtime.Token) BugInfoBuilder(com.cflint.BugInfo.BugInfoBuilder) CFExpression(cfml.parsing.cfscript.CFExpression) CFLintPluginInfo(com.cflint.config.CFLintPluginInfo) BugInfoBuilder(com.cflint.BugInfo.BugInfoBuilder) CFStatement(cfml.parsing.cfscript.CFStatement) CFScriptStatement(cfml.parsing.cfscript.script.CFScriptStatement) PluginMessage(com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginMessage) PluginInfoRule(com.cflint.config.CFLintPluginInfo.PluginInfoRule)

Example 9 with CFExpression

use of cfml.parsing.cfscript.CFExpression in project CFLint by cflint.

the class CFLint method unpackTagExpressions.

private Map<String, CFExpression> unpackTagExpressions(final Element elem) {
    // Use LinkedHashMap to preserve the order
    final Map<String, CFExpression> expressions = new LinkedHashMap<>();
    if (!elem.getName().toLowerCase().startsWith("cf") || elem.getAttributes() == null) {
        return expressions;
    }
    // variable attribute
    for (final Attribute attr : elem.getAttributes()) {
        if (detectScript(attr)) {
            // Try wrapping the expression in single or double quotes for
            // parsing.
            final List<String> literalChar = attr.getValue().contains("'") ? Arrays.asList("\"", "'") : Arrays.asList("'", "\"");
            try {
                final List<String> errors = new ArrayList<>();
                final ANTLRErrorListener errorReporter = new ArrayErrorListener(errors);
                final CFExpression exp = cfmlParser.parseCFMLExpression(literalChar.get(0) + attr.getValue() + literalChar.get(0), errorReporter);
                if (errors.isEmpty()) {
                    expressions.put(attr.getName().toLowerCase(), exp);
                    continue;
                }
            } catch (final Exception e) {
            }
            // Try other quotes before reporting a failure
            try {
                final CFExpression exp = cfmlParser.parseCFMLExpression(literalChar.get(1) + attr.getValue() + literalChar.get(1), this);
                expressions.put(attr.getName().toLowerCase(), exp);
            } catch (final Exception e2) {
                System.err.println("Error in parsing : " + attr.getValue() + " on tag " + elem.getName());
            }
        } else if (tagInfo.isExpressionAttribute(elem, attr.getName())) {
            try {
                final CFExpression exp = cfmlParser.parseCFMLExpression(attr.getValue(), this);
                expressions.put(attr.getName().toLowerCase(), exp);
            } catch (final Exception e2) {
                System.err.println("Error in parsing : " + attr.getValue() + " on tag " + elem.getName());
            }
        }
    }
    return expressions;
}
Also used : Attribute(net.htmlparser.jericho.Attribute) ArrayList(java.util.ArrayList) ArrayErrorListener(cfml.parsing.reporting.ArrayErrorListener) ANTLRErrorListener(org.antlr.v4.runtime.ANTLRErrorListener) ParseException(cfml.parsing.reporting.ParseException) IOException(java.io.IOException) CFLintScanException(com.cflint.exception.CFLintScanException) CFExpression(cfml.parsing.cfscript.CFExpression) LinkedHashMap(java.util.LinkedHashMap)

Example 10 with CFExpression

use of cfml.parsing.cfscript.CFExpression in project CFLint by cflint.

the class CFLint method process.

private void process(final Element elem, final String space, final Context context) throws CFLintScanException {
    if (skipToPosition > elem.getBegin()) {
        return;
    } else {
        skipToPosition = 0;
    }
    try {
        currentElement = elem;
        if (elem.getName().equalsIgnoreCase(CF.CFCOMPONENT)) {
            final Context componentContext = context.subContext(elem);
            componentContext.setInComponent(true);
            // elem.getAttributeValue(CF.DISPLAYNAME)
            componentContext.setComponentName(context.getFilename().replaceAll(".[cC][fF][cC]", "").replaceAll("^.*[/\\\\]", ""));
            componentContext.setContextType(ContextType.COMPONENT);
            handler.push(CF.COMPONENT);
            doStructureStart(elem, componentContext, CFCompDeclStatement.class);
        } else if (elem.getName().equalsIgnoreCase(CF.CFFUNCTION)) {
            final Context functionContext = context.subContext(elem);
            functionContext.setFunctionName(elem.getAttributeValue(CF.NAME));
            functionContext.setContextType(ContextType.FUNCTION);
            handler.push(CF.FUNCTION);
            doStructureStart(elem, functionContext, CFFuncDeclStatement.class);
        } else if (elem.getName().equalsIgnoreCase(CF.CFLOOP) && elem.getAttributeValue(CF.QUERY) != null) {
            // Give a cfloop for query its own context and set the column
            // names as variables if they are available
            final Context loopContext = context.subContext(elem);
            loopContext.setContextType(ContextType.QUERY_LOOP);
            handler.push(CF.CFLOOP);
            final String qryName = elem.getAttributeValue(CF.QUERY);
            handler.addVariables(handler.getQueryColumns(qryName));
            doStructureStart(elem, loopContext, CFFuncDeclStatement.class);
        }
        if (elem.getName().equalsIgnoreCase(CF.CFSET) || elem.getName().equalsIgnoreCase(CF.CFIF) || elem.getName().equalsIgnoreCase(CF.CFELSEIF) || elem.getName().equalsIgnoreCase(CF.CFRETURN)) {
            scanElement(elem, context);
            final Pattern p = Pattern.compile("<\\w+\\s(.*[^/])/?>", Pattern.MULTILINE | Pattern.DOTALL);
            final String expr = elem.getFirstStartTag().toString();
            final Matcher m = p.matcher(expr);
            if (m.matches()) {
                final String cfscript = m.group(1).trim();
                if (!cfscript.isEmpty()) {
                    try {
                        final CFExpression expression = cfmlParser.parseCFMLExpression(cfscript, this);
                        if (expression != null) {
                            process(expression, elem, context);
                        }
                    } catch (final Exception npe) {
                        printException(npe, elem);
                        final ContextMessage cm = new ContextMessage(PARSE_ERROR, null, null, context.startLine(), elem.getBegin());
                        reportRule(currentElement, null, context, null, cm);
                    }
                }
            }
            processStack(elem.getChildElements(), space + " ", context);
        } else if (elem.getName().equalsIgnoreCase(CF.CFARGUMENT) || elem.getName().equalsIgnoreCase(CF.CFDOCUMENTSECTION)) {
            scanElement(elem, context);
            final String name = elem.getAttributeValue(CF.NAME);
            if (name != null) {
                handler.addArgument(name);
            }
            processStack(elem.getChildElements(), space + " ", context);
        } else if (elem.getName().equalsIgnoreCase(CF.CFSCRIPT)) {
            scanElement(elem, context);
            String cfscript = elem.getContent().toString();
            if (elem.getEndTag() == null) {
                // Hack to fetch the entire cfscript text, if cfscript is a
                // word in the content somewhere, and causes
                // the jericho parser to fail
                EndTag nextTag = elem.getSource().getNextEndTag(elem.getBegin());
                while (nextTag != null && !nextTag.getName().equalsIgnoreCase(elem.getName())) {
                    nextTag = elem.getSource().getNextEndTag(nextTag.getEnd());
                }
                if (nextTag.getName().equalsIgnoreCase(elem.getName())) {
                    cfscript = elem.getSource().subSequence(elem.getStartTag().getEnd(), nextTag.getBegin()).toString();
                    skipToPosition = nextTag.getEnd();
                }
            }
            CFScriptStatement scriptStatement;
            try {
                scriptStatement = cfmlParser.parseScript(cfscript);
            } catch (ParseException e) {
                throw new CFLintScanException(e);
            } catch (IOException e) {
                throw new CFLintScanException(e);
            }
            final Context subcontext = context.subContext(elem, scriptStatement == null ? null : scriptStatement.getTokens());
            process(scriptStatement, subcontext);
            processStack(elem.getChildElements(), space + " ", context);
        } else if (elem.getName().equalsIgnoreCase(CF.CFFUNCTION)) {
            final Context functionContext = context.subContext(elem);
            functionContext.setFunctionName(elem.getAttributeValue(CF.NAME));
            functionContext.setContextType(ContextType.FUNCTION);
            scanElement(elem, functionContext);
            processStack(elem.getChildElements(), space + " ", functionContext);
            // Process any messages added by downstream parsing.
            for (final ContextMessage message : functionContext.getMessages()) {
                reportRule(elem, null, functionContext, message.getSource(), message);
            }
            functionContext.getMessages().clear();
            for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) {
                try {
                    structurePlugin.endFunction(functionContext, bugs);
                    for (final ContextMessage message : functionContext.getMessages()) {
                        reportRule(elem, null, functionContext, (CFLintScanner) structurePlugin, message);
                    }
                    functionContext.getMessages().clear();
                } catch (final Exception e) {
                    printException(e);
                    final ContextMessage cm = new ContextMessage(PARSE_ERROR, null, null, context.startLine());
                    reportRule(currentElement, null, context, null, cm);
                }
            }
            handler.pop();
        } else if (elem.getName().equalsIgnoreCase(CF.CFCOMPONENT)) {
            final Context componentContext = context.subContext(elem);
            componentContext.setInComponent(true);
            // elem.getAttributeValue(CF.DISPLAYNAME)
            componentContext.setComponentName(context.getFilename().replaceAll(".[cC][fF][cC]", "").replaceAll("^.*[/\\\\]", ""));
            componentContext.setContextType(ContextType.COMPONENT);
            scanElement(elem, componentContext);
            processStack(elem.getChildElements(), space + " ", componentContext);
            for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) {
                try {
                    structurePlugin.endComponent(componentContext, bugs);
                    for (final ContextMessage message : componentContext.getMessages()) {
                        reportRule(elem, null, componentContext, (CFLintScanner) structurePlugin, message);
                    }
                    componentContext.getMessages().clear();
                } catch (final Exception e) {
                    printException(e);
                    final ContextMessage cm = new ContextMessage(PARSE_ERROR, null, null, context.startLine());
                    reportRule(currentElement, null, context, null, cm);
                }
            }
            handler.pop();
        } else if (elem.getName().equalsIgnoreCase(CF.CFQUERY)) {
            scanElement(elem, context);
            for (final Entry<String, CFExpression> expression : unpackTagExpressions(elem).entrySet()) {
                if (expression != null) {
                    process(expression.getValue(), elem, context);
                }
            }
            final List<Element> list = elem.getAllElements();
            processStack(list.subList(1, list.size()), space + " ", context);
            // Save any columns from the cfquery
            final String qryName = elem.getAttributeValue(CF.NAME);
            if (qryName != null && qryName.trim().length() > 0) {
                final String qryText = elem.getTextExtractor().toString().toUpperCase();
                final Matcher m = Pattern.compile(".*SELECT\\s(\\w+(\\s*,\\s*\\w+)+)\\s+FROM\\s+.*").matcher(qryText);
                final List<String> cols = new ArrayList<>();
                if (m.matches()) {
                    cols.addAll(Arrays.asList(m.group(1).trim().split("\\s*,\\s*")));
                    handler.addQueryColumnSet(qryName, cols);
                }
            }
        } else if (elem.getName().equalsIgnoreCase(CF.CFQUERYPARAM)) {
            scanElement(elem, context);
            for (final Entry<String, CFExpression> expression : unpackTagExpressions(elem).entrySet()) {
                if (expression != null) {
                    process(expression.getValue(), elem, context);
                }
            }
        } else if (elem.getName().equalsIgnoreCase(CF.CFINCLUDE)) {
            scanElement(elem, context);
            final String path = elem.getAttributeValue(CF.TEMPLATE);
            final File include = new File(new File(context.getFilename()).getParentFile(), path);
            if (strictInclude || include.exists()) {
                if (includeFileStack.contains(include)) {
                    System.err.println("Terminated a recursive call to include file " + include);
                } else {
                    includeFileStack.push(include);
                    process(FileUtil.loadFile(include), context.getFilename());
                    includeFileStack.pop();
                }
            }
        } else if (elem.getName().equalsIgnoreCase(CF.CFLOOP) && elem.getAttributeValue(CF.QUERY) != null) {
            scanElement(elem, context);
            processStack(elem.getChildElements(), space + " ", context);
            handler.pop();
        } else {
            scanElement(elem, context);
            for (final Entry<String, CFExpression> expression : unpackTagExpressions(elem).entrySet()) {
                if (expression != null) {
                    process(expression.getValue(), elem, tagInfo.isAssignmentAttribute(elem, expression.getKey()) ? context.subContextInAssignment() : context);
                }
            }
            processStack(elem.getChildElements(), space + " ", context);
        }
        // Process any messages added by downstream parsing.
        for (final ContextMessage message : context.getMessages()) {
            reportRule(elem, null, context, message.getSource(), message);
        }
        context.getMessages().clear();
    } catch (final NullPointerException npe) {
        printException(npe);
        final ContextMessage cm = new ContextMessage(PARSE_ERROR, null, null, context.startLine());
        reportRule(currentElement, null, context, null, cm);
    }
}
Also used : Context(com.cflint.plugins.Context) CFFuncDeclStatement(cfml.parsing.cfscript.script.CFFuncDeclStatement) Pattern(java.util.regex.Pattern) EndTag(net.htmlparser.jericho.EndTag) Matcher(java.util.regex.Matcher) CFLintScanException(com.cflint.exception.CFLintScanException) CFLintScanner(com.cflint.plugins.CFLintScanner) IOException(java.io.IOException) ParseException(cfml.parsing.reporting.ParseException) IOException(java.io.IOException) CFLintScanException(com.cflint.exception.CFLintScanException) CFExpression(cfml.parsing.cfscript.CFExpression) Entry(java.util.Map.Entry) ContextMessage(com.cflint.plugins.Context.ContextMessage) CFScriptStatement(cfml.parsing.cfscript.script.CFScriptStatement) List(java.util.List) ArrayList(java.util.ArrayList) ParseException(cfml.parsing.reporting.ParseException) File(java.io.File) CFLintStructureListener(com.cflint.plugins.CFLintStructureListener)

Aggregations

CFExpression (cfml.parsing.cfscript.CFExpression)12 CFIdentifier (cfml.parsing.cfscript.CFIdentifier)5 CFFullVarExpression (cfml.parsing.cfscript.CFFullVarExpression)4 ParseException (cfml.parsing.reporting.ParseException)4 CFLintScanException (com.cflint.exception.CFLintScanException)4 CFLintScanner (com.cflint.plugins.CFLintScanner)4 IOException (java.io.IOException)4 CFVarDeclExpression (cfml.parsing.cfscript.CFVarDeclExpression)3 CFFuncDeclStatement (cfml.parsing.cfscript.script.CFFuncDeclStatement)3 CFScriptStatement (cfml.parsing.cfscript.script.CFScriptStatement)3 Context (com.cflint.plugins.Context)3 ContextMessage (com.cflint.plugins.Context.ContextMessage)3 ArrayList (java.util.ArrayList)3 CFFunctionExpression (cfml.parsing.cfscript.CFFunctionExpression)2 CFMember (cfml.parsing.cfscript.CFMember)2 CFCompDeclStatement (cfml.parsing.cfscript.script.CFCompDeclStatement)2 CFLintStructureListener (com.cflint.plugins.CFLintStructureListener)2 File (java.io.File)2 List (java.util.List)2 Pattern (java.util.regex.Pattern)2