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);
}
}
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());
}
}
}
}
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);
}
}
}
}
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;
}
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);
}
}
Aggregations