mirror of
https://github.com/apache/struts.git
synced 2026-08-11 01:27:14 +00:00
Merge pull request #181 from sdutry/WW-4888
WW-4888 add escaping possibilities to text-tag
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
package org.apache.struts2.components;
|
||||
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -58,6 +59,10 @@ import java.util.List;
|
||||
*
|
||||
* <ul>
|
||||
* <li>name* (String) - the i18n message key</li>
|
||||
* <li>escapeHtml (Boolean) - Escape HTML. Defaults to false</li>
|
||||
* <li>escapeJavaScript (Boolean) - Escape JavaScript. Defaults to false</li>
|
||||
* <li>escapeXml (Boolean) - Escape XML. Defaults to false</li>
|
||||
* <li>escapeCsv (Boolean) - Escape CSV. Defaults to false</li>
|
||||
* </ul>
|
||||
*
|
||||
* <!-- END SNIPPET: params -->
|
||||
@@ -119,6 +124,10 @@ public class Text extends ContextBean implements Param.UnnamedParametric {
|
||||
protected String actualName;
|
||||
protected String name;
|
||||
protected String searchStack;
|
||||
private boolean escapeHtml = false;
|
||||
private boolean escapeJavaScript = false;
|
||||
private boolean escapeXml = false;
|
||||
private boolean escapeCsv = false;
|
||||
|
||||
public Text(ValueStack stack) {
|
||||
super(stack);
|
||||
@@ -134,6 +143,26 @@ public class Text extends ContextBean implements Param.UnnamedParametric {
|
||||
this.searchStack = searchStack;
|
||||
}
|
||||
|
||||
@StrutsTagAttribute(description="Whether to escape HTML", type="Boolean", defaultValue="false")
|
||||
public void setEscapeHtml(boolean escape) {
|
||||
this.escapeHtml = escape;
|
||||
}
|
||||
|
||||
@StrutsTagAttribute(description="Whether to escape Javascript", type="Boolean", defaultValue="false")
|
||||
public void setEscapeJavaScript(boolean escapeJavaScript) {
|
||||
this.escapeJavaScript = escapeJavaScript;
|
||||
}
|
||||
|
||||
@StrutsTagAttribute(description="Whether to escape XML", type="Boolean", defaultValue="false")
|
||||
public void setEscapeXml(boolean escapeXml) {
|
||||
this.escapeXml = escapeXml;
|
||||
}
|
||||
|
||||
@StrutsTagAttribute(description="Whether to escape CSV (useful to escape a value for a column)", type="Boolean", defaultValue="false")
|
||||
public void setEscapeCsv(boolean escapeCsv) {
|
||||
this.escapeCsv = escapeCsv;
|
||||
}
|
||||
|
||||
public boolean usesBody() {
|
||||
// overriding this to true such that EVAL_BODY_BUFFERED is return and
|
||||
// bodyContent will be valid hence, text between start & end tag will
|
||||
@@ -161,7 +190,7 @@ public class Text extends ContextBean implements Param.UnnamedParametric {
|
||||
if (msg != null) {
|
||||
try {
|
||||
if (getVar() == null) {
|
||||
writer.write(msg);
|
||||
writer.write(prepare(msg));
|
||||
} else {
|
||||
putInContext(msg);
|
||||
}
|
||||
@@ -184,4 +213,22 @@ public class Text extends ContextBean implements Param.UnnamedParametric {
|
||||
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
private String prepare(String value) {
|
||||
String result = value;
|
||||
if (escapeHtml) {
|
||||
result = StringEscapeUtils.escapeHtml4(result);
|
||||
}
|
||||
if (escapeJavaScript) {
|
||||
result = StringEscapeUtils.escapeEcmaScript(result);
|
||||
}
|
||||
if (escapeXml) {
|
||||
result = StringEscapeUtils.escapeXml(result);
|
||||
}
|
||||
if (escapeCsv) {
|
||||
result = StringEscapeUtils.escapeCsv(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ public class TextTag extends ContextBeanTag {
|
||||
|
||||
protected String name;
|
||||
protected String searchValueStack;
|
||||
private boolean escapeHtml = false;
|
||||
private boolean escapeJavaScript = false;
|
||||
private boolean escapeXml = false;
|
||||
private boolean escapeCsv = false;
|
||||
|
||||
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
|
||||
return new Text(stack);
|
||||
@@ -46,6 +50,10 @@ public class TextTag extends ContextBeanTag {
|
||||
Text text = (Text) component;
|
||||
text.setName(name);
|
||||
text.setSearchValueStack(searchValueStack);
|
||||
text.setEscapeHtml(escapeHtml);
|
||||
text.setEscapeJavaScript(escapeJavaScript);
|
||||
text.setEscapeXml(escapeXml);
|
||||
text.setEscapeCsv(escapeCsv);
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
@@ -55,4 +63,21 @@ public class TextTag extends ContextBeanTag {
|
||||
public void setSearchValueStack(String searchStack) {
|
||||
this.searchValueStack = searchStack;
|
||||
}
|
||||
|
||||
public void setEscapeHtml(boolean escapeHtml) {
|
||||
this.escapeHtml = escapeHtml;
|
||||
}
|
||||
|
||||
public void setEscapeJavaScript(boolean escapeJavaScript) {
|
||||
this.escapeJavaScript = escapeJavaScript;
|
||||
}
|
||||
|
||||
public void setEscapeXml(boolean escapeXml) {
|
||||
this.escapeXml = escapeXml;
|
||||
}
|
||||
|
||||
public void setEscapeCsv(boolean escapeCsv) {
|
||||
this.escapeCsv = escapeCsv;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,38 @@ Please do not edit it directly.
|
||||
<th align="left" valign="top"><h4>Type</h4></th>
|
||||
<th align="left" valign="top"><h4>Description</h4></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" valign="top">escapeCsv</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">Boolean</td>
|
||||
<td align="left" valign="top">Whether to escape CSV (useful to escape a value for a column)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" valign="top">escapeHtml</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">Boolean</td>
|
||||
<td align="left" valign="top">Whether to escape HTML</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" valign="top">escapeJavaScript</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">Boolean</td>
|
||||
<td align="left" valign="top">Whether to escape Javascript</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" valign="top">escapeXml</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">Boolean</td>
|
||||
<td align="left" valign="top">Whether to escape XML</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" valign="top">name</td>
|
||||
<td align="left" valign="top"><strong>true</strong></td>
|
||||
|
||||
@@ -305,6 +305,46 @@ public class TextTagTest extends AbstractTagTest {
|
||||
assertEquals("No foo here", stack.findString("myId")); // is in stack now
|
||||
}
|
||||
|
||||
public void testEscapeHtml() throws Exception {
|
||||
final String key = "foo.escape.html";
|
||||
final String value = "1 < 2";
|
||||
tag.setName(key);
|
||||
tag.setEscapeHtml(true);
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
assertEquals(value, writer.toString());
|
||||
}
|
||||
|
||||
public void testEscapeXml() throws Exception {
|
||||
final String key = "foo.escape.xml";
|
||||
final String value = "<>'"&";
|
||||
tag.setName(key);
|
||||
tag.setEscapeXml(true);
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
assertEquals(value, writer.toString());
|
||||
}
|
||||
|
||||
public void testEscapeJavaScript() throws Exception {
|
||||
final String key = "foo.escape.javascript";
|
||||
final String value = "\\t\\b\\n\\f\\r\\\"\\\'\\/\\\\";
|
||||
tag.setName(key);
|
||||
tag.setEscapeJavaScript(true);
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
assertEquals(value, writer.toString());
|
||||
}
|
||||
|
||||
public void testEscapeCsv() throws Exception {
|
||||
final String key = "foo.escape.csv";
|
||||
final String value = "\"something,\"\",\"\"\"";
|
||||
tag.setName(key);
|
||||
tag.setEscapeCsv(true);
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
assertEquals(value, writer.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* todo remove ActionContext set after LocalizedTextUtil is fixed to not use ThreadLocal
|
||||
*
|
||||
|
||||
@@ -21,4 +21,8 @@ expressionKey=Foo is ${foo}
|
||||
messageFormatKey=Params are {0} {1} {2}
|
||||
foo.bar.baz=This should start with foo
|
||||
bar.baz=No foo here
|
||||
some.image.from.properties=some.gif
|
||||
some.image.from.properties=some.gif
|
||||
foo.escape.html=1 < 2
|
||||
foo.escape.xml=<>''\"&
|
||||
foo.escape.javascript=\u0009\u0008\n\u000C\u000D\"''/\u005C
|
||||
foo.escape.csv=something,","
|
||||
|
||||
Reference in New Issue
Block a user