Adding support for Content

This commit is contained in:
Sergey
2017-02-21 15:57:57 -08:00
parent b5235ba722
commit 1863bfbf1f
6 changed files with 69 additions and 17 deletions
pmd-visualforce
etc/grammar
src
main/java/net/sourceforge/pmd/lang/vf
test/resources/net/sourceforge/pmd/lang/vf/rule/security/xml

@ -145,7 +145,7 @@ PARSER_END(VfParser)
| <GE: ">=" >
| <LT: "<" >
| <GT: ">" >
| <EXCL: ("!"|"~") >
| <EXCL: ("!"|"~"|"NOT") >
| <PIPE_PIPE: "||" >
| <STRING_LITERAL: <QUOTED_STRING> >
| <DIGITS: (<NUM_CHAR>)+ >
@ -294,7 +294,7 @@ void Bom() #void :
/**
* Everything between a start-tag and the corresponding end-tag of an element (if an end tag exists).
*/
void Content() #void :
void Content() :
{}
{
( ElOrText() | ContentElement() )*

@ -0,0 +1,21 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.vf.ast;
public class ASTContent extends AbstractVFNode {
public ASTContent(int id) {
super(id);
}
public ASTContent(VfParser p, int id) {
super(p, id);
}
/** Accept the visitor. **/
public Object jjtAccept(VfParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

@ -83,10 +83,14 @@ public class VfParserVisitorAdapter implements VfParserVisitor {
public Object visit(ASTArguments node, Object data) {
return visit((VfNode) node, data);
}
@Override
public Object visit(ASTDotExpression node, Object data) {
return visit((VfNode) node, data);
}
@Override
public Object visit(ASTContent node, Object data) {
return visit((VfNode) node, data);
}
}

@ -18,6 +18,7 @@ import net.sourceforge.pmd.lang.vf.ast.ASTAttributeValue;
import net.sourceforge.pmd.lang.vf.ast.ASTCData;
import net.sourceforge.pmd.lang.vf.ast.ASTCommentTag;
import net.sourceforge.pmd.lang.vf.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.vf.ast.ASTContent;
import net.sourceforge.pmd.lang.vf.ast.ASTDeclaration;
import net.sourceforge.pmd.lang.vf.ast.ASTDoctypeDeclaration;
import net.sourceforge.pmd.lang.vf.ast.ASTDoctypeExternalId;
@ -71,7 +72,6 @@ public abstract class AbstractVfRule extends AbstractRule implements VfParserVis
public Object visit(ASTAttributeValue node, Object data) {
return visit((VfNode) node, data);
}
public Object visit(ASTElExpression node, Object data) {
return visit((VfNode) node, data);
@ -132,4 +132,9 @@ public abstract class AbstractVfRule extends AbstractRule implements VfParserVis
public Object visit(ASTDotExpression node, Object data) {
return visit((VfNode) node, data);
}
public Object visit(ASTContent node, Object data) {
return visit((VfNode) node, data);
}
}

@ -8,6 +8,7 @@ import java.util.List;
import java.util.regex.Pattern;
import net.sourceforge.pmd.lang.vf.ast.ASTAttribute;
import net.sourceforge.pmd.lang.vf.ast.ASTContent;
import net.sourceforge.pmd.lang.vf.ast.ASTElExpression;
import net.sourceforge.pmd.lang.vf.ast.ASTElement;
import net.sourceforge.pmd.lang.vf.ast.ASTIdentifier;
@ -136,14 +137,20 @@ public class VfUnescapeElRule extends AbstractVfRule {
}
private boolean hasAnyEL(final ASTElement node) {
final List<ASTElement> innerElements = node.findChildrenOfType(ASTElement.class);
for (ASTElement element : innerElements) {
if (element.getName().equalsIgnoreCase(APEX_PARAM)) {
final List<ASTAttribute> innerAttributes = element.findChildrenOfType(ASTAttribute.class);
for (ASTAttribute attrib : innerAttributes) {
final ASTElExpression elInVal = attrib.getFirstDescendantOfType(ASTElExpression.class);
if (elInVal != null) {
return true;
final ASTContent content = node.getFirstChildOfType(ASTContent.class);
if (content != null) {
List<ASTElement> innerElements = content.findChildrenOfType(ASTElement.class);
for (ASTElement element : innerElements) {
if (element.getName().equalsIgnoreCase(APEX_PARAM)) {
final List<ASTAttribute> innerAttributes = element.findChildrenOfType(ASTAttribute.class);
for (ASTAttribute attrib : innerAttributes) {
final List<ASTElExpression> elsInVal = attrib.findDescendantsOfType(ASTElExpression.class);
for (final ASTElExpression el : elsInVal) {
if (doesElContainAnyUnescapedIdentifiers(el)) {
return true;
}
}
}
}
}

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<test-data>
<test-code>
<description><![CDATA[
Default escaped EL - no XSS
@ -55,7 +54,7 @@ XSS via EL literal and no escaping
<source-type>vf</source-type>
</test-code>
<test-code>
<test-code>
<description><![CDATA[
XSS via EL boolean and no escaping
]]></description>
@ -81,6 +80,23 @@ XSS via EL via param binding
</apex:outputText>
</apex:page>
]]></code>
<source-type>vf</source-type>
</test-code>
<test-code>
<description><![CDATA[
Escaped EL via param binding
]]></description>
<expected-problems>0</expected-problems>
<code><![CDATA[
<apex:page>
<apex:outputText value='{0}' escape="false">
<apex:param value='{! HTMLENCODE(here) }' />
</apex:outputText>
</apex:page>
]]></code>
<source-type>vf</source-type>
</test-code>
@ -118,7 +134,7 @@ No XSS via EL via param binding
]]></code>
<source-type>vf</source-type>
</test-code>
<test-code>
<description><![CDATA[
No XSS with escaped EL
@ -131,6 +147,5 @@ No XSS with escaped EL
]]></code>
<source-type>vf</source-type>
</test-code>
</test-data>