Merge branch 'pr-340'

This commit is contained in:
Juan Martín Sotuyo Dodero
2017-04-14 17:21:51 -03:00
8 changed files with 140 additions and 153 deletions

View File

@ -70,7 +70,7 @@ PARSER_END(VfParser)
| <#XMLNAME: (<ALPHA_CHAR> | "_" | ":") (<IDENTIFIER_CHAR>)* >
| <#QUOTED_STRING_NO_BREAKS: ( "'" ( ~["'", "\r", "\n"] )* "'" )
| ( "\"" ( ~["\"", "\r", "\n"] )* "\"" ) >
| <#QUOTED_STRING: ( "'" ( ~["'"] )* "'" ) | ( "\"" ( ~["\""] )* "\"" ) >
| <#QUOTED_STRING: ( "'" ( ~["'"] )* "'" ) | ( "\"" ( ~["\""] | "\\\"" )* "\"" ) >
| <#WHITESPACE: ( " " | "\t" | "\n" | "\r" ) >
| <#NEWLINE: ( "\r\n" | "\r" | "\n" ) >
| <#QUOTE: ( "'" | "\"" )>
@ -82,6 +82,8 @@ PARSER_END(VfParser)
| <#TEXT_IN_EL: (~["}", "'", "\""])+ >
| <#CLOSEBRACE: ("}")>
| <#DOT: "." >
| <#COMMNT_START: "/*" >
| <#COMMNT_END: "*/" >
}
@ -90,7 +92,7 @@ PARSER_END(VfParser)
< (<WHITESPACE>)+ >
}
<AfterTagState, InTagState, HtmlScriptContentState, HtmlStyleContentState, ElTagState, ElAttribTagStateSQ, ElAttribTagStateDQ, ElInScriptState > SPECIAL_TOKEN:
<AfterTagState, InTagState, HtmlScriptContentState, ElTagState, ElAttribTagStateSQ, ElAttribTagStateDQ, ElInScriptState > SPECIAL_TOKEN:
{
< (<WHITESPACE>)+ >
}
@ -104,7 +106,6 @@ PARSER_END(VfParser)
| <DOCTYPE_DECL_START: "<!DOCTYPE" > : DocTypeState
| <CDATA_START: "<![CDATA[" > : CDataState
| <HTML_SCRIPT_START: "<script" > : InTagState
| <HTML_STYLE_START: "<style" > : InTagState
}
@ -116,7 +117,7 @@ PARSER_END(VfParser)
<ElTagState, ElAttribTagStateSQ, ElAttribTagStateDQ, ElAttribTagStateNQ, ElInScriptState> TOKEN :
{
<NULL: "null" >
<NULL: "null" >
| <TRUE: "true" >
| <FALSE: "false" >
| <LPAREN: "(" >
@ -162,22 +163,25 @@ PARSER_END(VfParser)
<ElAttribTagStateSQ> TOKEN :
{
<END_OF_EL_ATTRIB_SQ: (<WHITESPACES>)? <CLOSEBRACE> > : AttrValueBetweenSingleQuotesState
<COMMENT_OPEN_SQ: <COMMNT_START> > : InlineCommentStateSQ
| <END_OF_EL_ATTRIB_SQ: (<WHITESPACES>)? <CLOSEBRACE> > : AttrValueBetweenSingleQuotesState
}
<ElAttribTagStateDQ> TOKEN :
{
<END_OF_EL_ATTRIB_DQ: (<WHITESPACES>)? <CLOSEBRACE> > : AttrValueBetweenDoubleQuotesState
{
<COMMENT_OPEN_DQ: <COMMNT_START> > : InlineCommentStateDQ
| <END_OF_EL_ATTRIB_DQ: (<WHITESPACES>)? <CLOSEBRACE> > : AttrValueBetweenDoubleQuotesState
}
<ElAttribTagStateNQ> TOKEN :
{
<END_OF_EL_ATTRIB_NQ: (<WHITESPACES>)? <CLOSEBRACE> > : AttrValueNoQuotesState
<END_OF_EL_ATTRIB_NQ: (<WHITESPACES>)? <CLOSEBRACE> > : AttrValueNoQuotesState
}
<ElInScriptState> TOKEN :
{
<END_OF_EL_SCRIPT: (<WHITESPACES>)? <CLOSEBRACE> > : HtmlScriptContentState
<COMMENT_OPEN_SCRIPT: <COMMNT_START> > : InlineCommentStateScript
| <END_OF_EL_SCRIPT: (<WHITESPACES>)? <CLOSEBRACE> > : HtmlScriptContentState
}
<DocTypeState, DocTypeExternalIdState> TOKEN :
@ -232,7 +236,7 @@ PARSER_END(VfParser)
{
<ENDING_WHITESPACE: " " >: InTagState
| <EL_EXPRESSION_IN_ATTRIBUTE_NQ: "{!" (<WHITESPACES>)? > : ElAttribTagStateNQ
| <UNPARSED_TEXT_NO_WHITESPACE: ( ~["{", " "] |(["{"] ~["!"]) )+ >
| <UNPARSED_TEXT_NO_WHITESPACE: ( ~["{", " "] | (["{"] ~["!"]) )+ >
}
@ -246,18 +250,37 @@ PARSER_END(VfParser)
<AttrValueBetweenDoubleQuotesState> TOKEN :
{
<ENDING_DOUBLE_QUOTE: "\""> : InTagState
<ENDING_DOUBLE_QUOTE: "\""> : InTagState
| <EL_EXPRESSION_IN_ATTRIBUTE_DQ: "{!" (<WHITESPACES>)? > : ElAttribTagStateDQ
| <UNPARSED_TEXT_NO_DOUBLE_QUOTES:
| <UNPARSED_TEXT_NO_DOUBLE_QUOTES:
( (~["{", "\""]) | (["{"] ~["!", "\""]) )+ >
}
<CommentState> TOKEN :
{
< COMMENT_END: ("--" (" ")* ">" | "->") > : AfterTagState
< COMMENT_END: ("--" (" ")* ">" ) > : AfterTagState
| < COMMENT_TEXT: (~[]) >
}
<InlineCommentStateScript> TOKEN :
{
< COMMENT_CLOSE_SCRIPT: (<COMMNT_END>) > : ElInScriptState
| < COMMENT_INNER_TEXT_SCRIPT: (~[]) >
}
<InlineCommentStateSQ> TOKEN :
{
< COMMENT_CLOSE_SQ: (<COMMNT_END>) > : ElAttribTagStateSQ
| < COMMENT_INNER_TEXT_SQ: (~[]) >
}
<InlineCommentStateDQ> TOKEN :
{
< COMMENT_CLOSE_DQ: (<COMMNT_END>) > : ElAttribTagStateDQ
| < COMMENT_INNER_TEXT_DQ: (~[]) >
}
<HtmlScriptContentState> TOKEN :
{
<HTML_SCRIPT_END_TAG : "</script>" > : AfterTagState
@ -265,12 +288,6 @@ PARSER_END(VfParser)
| <HTML_SCRIPT_CONTENT: ( (~["{"]) | (["{"] ~["!"]) ) >
}
<HtmlStyleContentState> TOKEN :
{
<HTML_STYLE_CONTENT: (~[]) >
| <HTML_STYLE_END_TAG : "</style>" > : AfterTagState
}
/** ************************* VF GRAMMAR **************************** */
/**
@ -328,11 +345,10 @@ void ContentElement() #void :
{}
{
(
CommentTag()
CommentTag()
| Element()
| CData()
| HtmlScript()
| HtmlStyle()
| HtmlScript()
)
}
@ -409,7 +425,11 @@ void ElExpression() :
void Expression() :
{}
{
ConditionalExpression() [ AssignmentOperator() Expression() ]
ConditionalExpression() [ AssignmentOperator() Expression() ]
| CommentExpression() ( ConditionalExpression() | CommentExpression() )*
| ELDQCommentExpression() ( ConditionalExpression() | ELDQCommentExpression() )*
| ELSQCommentExpression() ( ConditionalExpression() | ELSQCommentExpression() )*
}
void AssignmentOperator() #void :
@ -489,17 +509,34 @@ void NegationExpression() #void :
void PrimaryExpression() #void :
{}
{
PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )*
PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )*
}
void ELSQCommentExpression() #void :
{}
{
<COMMENT_OPEN_SQ> ( <COMMENT_INNER_TEXT_SQ> )* <COMMENT_CLOSE_SQ>
}
void ELDQCommentExpression() #void :
{}
{
<COMMENT_OPEN_DQ> ( <COMMENT_INNER_TEXT_DQ> )* <COMMENT_CLOSE_DQ>
}
void CommentExpression() #void :
{}
{
<COMMENT_OPEN_SCRIPT> ( <COMMENT_INNER_TEXT_SCRIPT> )* <COMMENT_CLOSE_SCRIPT>
}
void PrimaryPrefix() #void :
{}
{
Literal()
| Identifier()
Literal()
| Identifier()
| <LPAREN> Expression() <RPAREN>
| <LSQUARE> Expression() (<COMMA> Expression())* <RSQUARE>
}
void PrimarySuffix() #void :
@ -660,18 +697,10 @@ void Attribute() :
)
}
void CommentTag() :
void CommentTag() #void :
{}
{
StringBuffer content = new StringBuffer();
Token t;
}
{
<COMMENT_START>
( t = <COMMENT_TEXT> { content.append(t.image); } )*
<COMMENT_END>
{
jjtThis.setImage(content.toString().trim());
}
<COMMENT_START> ( <COMMENT_TEXT> )* <COMMENT_END>
}
void Declaration() :
@ -745,26 +774,3 @@ void HtmlScriptContent() #Text :
{ jjtThis.setImage(content.toString()); }
}
void HtmlStyle() :
{
StringBuffer content = new StringBuffer();
String tagName;
Token t;
}
{
<HTML_STYLE_START> {}
(Attribute() )* {}
(
(
<TAG_END> {token_source.SwitchTo(HtmlStyleContentState);}
(t = <HTML_STYLE_CONTENT> { content.append(t.image); })*
<HTML_STYLE_END_TAG> { jjtThis.setImage(content.toString().trim());}
)
|
(
<TAG_SLASHEND>
)
)
}

View File

@ -33,8 +33,7 @@
javacchome="${javacc-home.path}" />
<!-- Ensure generated using CharStream interface debugparser="true"
debugtokenmanager="true"-->
<javacc static="false"
<javacc static="false"
usercharstream="true"
unicodeinput="true"
javaunicodeescape="false"

View File

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

View File

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

View File

@ -39,10 +39,6 @@ public class VfParserVisitorAdapter implements VfParserVisitor {
return visit((VfNode) node, data);
}
public Object visit(ASTCommentTag node, Object data) {
return visit((VfNode) node, data);
}
public Object visit(ASTDeclaration node, Object data) {
return visit((VfNode) node, data);
}
@ -59,11 +55,6 @@ public class VfParserVisitorAdapter implements VfParserVisitor {
return visit((VfNode) node, data);
}
@Override
public Object visit(ASTHtmlStyle node, Object data) {
return visit((VfNode) node, data);
}
@Override
public Object visit(ASTLiteral node, Object data) {
return visit((VfNode) node, data);

View File

@ -16,7 +16,6 @@ import net.sourceforge.pmd.lang.vf.ast.ASTArguments;
import net.sourceforge.pmd.lang.vf.ast.ASTAttribute;
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;
@ -27,7 +26,6 @@ import net.sourceforge.pmd.lang.vf.ast.ASTElExpression;
import net.sourceforge.pmd.lang.vf.ast.ASTElement;
import net.sourceforge.pmd.lang.vf.ast.ASTExpression;
import net.sourceforge.pmd.lang.vf.ast.ASTHtmlScript;
import net.sourceforge.pmd.lang.vf.ast.ASTHtmlStyle;
import net.sourceforge.pmd.lang.vf.ast.ASTIdentifier;
import net.sourceforge.pmd.lang.vf.ast.ASTLiteral;
import net.sourceforge.pmd.lang.vf.ast.ASTText;
@ -72,7 +70,7 @@ 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);
}
@ -89,10 +87,6 @@ public abstract class AbstractVfRule extends AbstractRule implements VfParserVis
return visit((VfNode) node, data);
}
public Object visit(ASTCommentTag node, Object data) {
return visit((VfNode) node, data);
}
public Object visit(ASTDeclaration node, Object data) {
return visit((VfNode) node, data);
}
@ -108,10 +102,6 @@ public abstract class AbstractVfRule extends AbstractRule implements VfParserVis
public Object visit(ASTHtmlScript node, Object data) {
return visit((VfNode) node, data);
}
public Object visit(ASTHtmlStyle node, Object data) {
return visit((VfNode) node, data);
}
public Object visit(ASTLiteral node, Object data) {
return visit((VfNode) node, data);
@ -120,7 +110,7 @@ public abstract class AbstractVfRule extends AbstractRule implements VfParserVis
public Object visit(ASTIdentifier node, Object data) {
return visit((VfNode) node, data);
}
public Object visit(ASTExpression node, Object data) {
return visit((VfNode) node, data);
}
@ -128,7 +118,7 @@ public abstract class AbstractVfRule extends AbstractRule implements VfParserVis
public Object visit(ASTArguments node, Object data) {
return visit((VfNode) node, data);
}
public Object visit(ASTDotExpression node, Object data) {
return visit((VfNode) node, data);
}

View File

@ -128,18 +128,6 @@ public class VfDocStyleTest extends AbstractVfNodesTest {
}
/**
* Test parsing of a XML comment.
*
*/
@Test
public void testComment() {
Set<ASTCommentTag> comments = getNodes(ASTCommentTag.class, TEST_COMMENT);
assertEquals("One comment expected!", 1, comments.size());
ASTCommentTag comment = comments.iterator().next();
assertEquals("Correct comment content expected!", "comment", comment.getImage());
}
/**
* Test parsing of HTML &lt;script&gt; element.
*/
@ -151,8 +139,48 @@ public class VfDocStyleTest extends AbstractVfNodesTest {
ASTText text = script.getFirstChildOfType(ASTText.class);
assertEquals("Correct script content expected!", "Script!", text.getImage());
}
/**
* Test parsing of EL in attribute of an element.
*/
@Test
public void testELInTagValue() {
Set<ASTElement> elememts = getNodes(ASTElement.class, TEST_EL_IN_TAG_ATTRIBUTE);
assertEquals("One element expected!", 1, elememts.size());
ASTElement element = elememts.iterator().next();
ASTAttributeValue attribute = element.getFirstDescendantOfType(ASTAttributeValue.class);
ASTIdentifier id = attribute.getFirstDescendantOfType(ASTIdentifier.class);
assertEquals("Correct identifier expected", "foo", id.getImage());
}
/**
* Test parsing of EL in attribute of an element that also has a comment.
*/
@Test
public void testELInTagValueWithCommentDQ() {
Set<ASTElement> elememts = getNodes(ASTElement.class, TEST_EL_IN_TAG_ATTRIBUTE_WITH_COMMENT);
assertEquals("One element expected!", 1, elememts.size());
ASTElement element = elememts.iterator().next();
ASTElExpression elExpr = element.getFirstDescendantOfType(ASTElExpression.class);
ASTIdentifier id = elExpr.getFirstDescendantOfType(ASTIdentifier.class);
assertEquals("Correct identifier expected", "init", id.getImage());
}
/**
* Test parsing of EL in attribute of an element that also has a comment.
*/
@Test
public void testELInTagValueWithCommentSQ() {
Set<ASTElement> elememts = getNodes(ASTElement.class, TEST_EL_IN_TAG_ATTRIBUTE_WITH_COMMENT_SQ);
assertEquals("One element expected!", 1, elememts.size());
ASTElement element = elememts.iterator().next();
ASTElExpression elExpr = element.getFirstDescendantOfType(ASTElExpression.class);
ASTIdentifier id = elExpr.getFirstDescendantOfType(ASTIdentifier.class);
assertEquals("Correct identifier expected", "init", id.getImage());
}
/**
* Test parsing of EL in HTML &lt;script&gt; element.
*/
@ -167,7 +195,22 @@ public class VfDocStyleTest extends AbstractVfNodesTest {
ASTIdentifier id = el.getFirstDescendantOfType(ASTIdentifier.class);
assertEquals("Correct EL content expected!", "elInScript", id.getImage());
}
/**
* Test parsing of inline comment in EL.
*/
@Test
public void testInlineCommentInEL() {
Set<ASTHtmlScript> scripts = getNodes(ASTHtmlScript.class, TEST_EL_IN_HTML_SCRIPT_WITH_COMMENT);
assertEquals("One script expected!", 1, scripts.size());
ASTHtmlScript script = scripts.iterator().next();
ASTText text = script.getFirstChildOfType(ASTText.class);
assertEquals("Correct script content expected!", "vartext=", text.getImage());
ASTElExpression el = script.getFirstChildOfType(ASTElExpression.class);
ASTIdentifier id = el.getFirstDescendantOfType(ASTIdentifier.class);
assertEquals("Correct EL content expected!", "elInScript", id.getImage());
}
/**
* Test parsing of quoted EL in HTML &lt;script&gt; element.
*/
@ -177,7 +220,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest {
assertEquals("One script expected!", 1, scripts.size());
ASTHtmlScript script = scripts.iterator().next();
ASTText text = script.getFirstChildOfType(ASTText.class);
assertEquals("Correct script content expected!", "vartext='textHere", text.getImage());
assertEquals("Correct script content expected!", "vartext='textHere", text.getImage());
ASTElExpression el = script.getFirstChildOfType(ASTElExpression.class);
ASTIdentifier id = el.getFirstDescendantOfType(ASTIdentifier.class);
assertEquals("Correct EL content expected!", "elInScript", id.getImage());
@ -224,19 +267,16 @@ public class VfDocStyleTest extends AbstractVfNodesTest {
ASTHtmlScript next = script.iterator().next();
ASTText text = next.getFirstChildOfType(ASTText.class);
assertTrue(text.getImage().contains("<!--"));
Set<ASTCommentTag> comments = getNodes(ASTCommentTag.class, TEST_COMPLEX_SCRIPT);
assertEquals("One comment expected!", 1, comments.size());
}
/**
* Test parsing of HTML &lt;script&gt; element.
* Test parsing of HTML &lt;style&gt; element.
*/
@Test
public void testInlineCss() {
Set<ASTElement> elements = getNodes(ASTElement.class, TEST_INLINE_STYLE);
Set<ASTHtmlStyle> styles = getNodes(ASTHtmlStyle.class, TEST_INLINE_STYLE);
assertEquals("Two elements expected!", 2, elements.size());
assertEquals("One style expected!", 1, styles.size());
assertEquals("Two elements expected!", 3, elements.size());
}
/**
@ -636,7 +676,7 @@ public class VfDocStyleTest extends AbstractVfNodesTest {
assertEquals("One attribute expected!", 1, attributes.size());
Iterator<ASTAttributeValue> iterator = attributes.iterator();
ASTAttributeValue attr = iterator.next();
ASTIdentifier id = attr.getFirstDescendantOfType(ASTIdentifier.class);
ASTIdentifier id = attr.getFirstDescendantOfType(ASTIdentifier.class);
assertEquals("Expected to detect proper value for EL in attribute!", "something", id.getImage());
}
@ -650,13 +690,16 @@ public class VfDocStyleTest extends AbstractVfNodesTest {
+ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" "
+ "\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n" + "<greeting>Hello, world!</greeting>";
private static final String TEST_COMMENT = "<html><!-- comment --></html>";
private static final String TEST_ATTRIBUTE_VALUE_CONTAINING_HASH = "<tag:if something=\"#yes#\" foo=\"CREATE\"> <a href=\"#\">foo</a> </tag:if>";
private static final String TEST_HTML_SCRIPT = "<html><head><script>Script!</script></head></html>";
private static final String TEST_EL_IN_TAG_ATTRIBUTE = "<apex:page action=\"{!foo}\">text</apex:page>";
private static final String TEST_EL_IN_TAG_ATTRIBUTE_WITH_COMMENT = "<apex:page action=\"{!/*comment here*/init}\">text</apex:page>";
private static final String TEST_EL_IN_TAG_ATTRIBUTE_WITH_COMMENT_SQ = "<apex:page action='{!/*comment here*/init}'>text</apex:page>";
private static final String TEST_EL_IN_HTML_SCRIPT = "<html><head><script>var text={!elInScript};</script></head></html>";
private static final String TEST_EL_IN_HTML_SCRIPT_WITH_COMMENT = "<html><head><script>var text={!/*junk1*/elInScript/*junk2*/};</script></head></html>";
private static final String TEST_QUOTED_EL_IN_HTML_SCRIPT = "<html><head><script>var text='textHere{!elInScript}';</script></head></html>";

View File

@ -572,5 +572,6 @@ You need to use this, if you have a large project with many files, and you hit t
* [#327](https://github.com/pmd/pmd/pull/327): \[apex] Fixed SOQL injection detection for escaped vars
* [#331](https://github.com/pmd/pmd/pull/331): \[java] JunitTestsShouldIncludeAssertRule now handles AllocationExpression correctly
* [#332](https://github.com/pmd/pmd/pull/332): \[java] Future-proof DontImportJavaLangRule
* [#340](https://github.com/pmd/pmd/pull/340): \[vf] Multiple parser bug fixes
* [#341](https://github.com/pmd/pmd/pull/341): \[vf] JSON.parse(..) and NOT(..) are safely evaluated