[
https://issues.apache.org/jira/browse/WW-4888?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16246042#comment-16246042
]
ASF GitHub Bot commented on WW-4888:
------------------------------------
lukaszlenart closed pull request #181: WW-4888 add escaping possibilities to
text-tag
URL: https://github.com/apache/struts/pull/181
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/core/src/main/java/org/apache/struts2/components/Text.java
b/core/src/main/java/org/apache/struts2/components/Text.java
index c7935ac7c..a5ea21715 100644
--- a/core/src/main/java/org/apache/struts2/components/Text.java
+++ b/core/src/main/java/org/apache/struts2/components/Text.java
@@ -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 @@
*
* <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 @@
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 void setSearchValueStack(String searchStack) {
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 boolean end(Writer writer, String body) {
if (msg != null) {
try {
if (getVar() == null) {
- writer.write(msg);
+ writer.write(prepare(msg));
} else {
putInContext(msg);
}
@@ -184,4 +213,22 @@ public void addParameter(Object value) {
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;
+ }
}
diff --git a/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java
b/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java
index 6407954fa..c0420dfad 100644
--- a/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java
+++ b/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java
@@ -35,6 +35,10 @@
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 @@ protected void populateParams() {
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 void setName(String name) {
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;
+ }
+
}
diff --git a/core/src/site/resources/tags/text.html
b/core/src/site/resources/tags/text.html
index bd2e51115..f068caddb 100644
--- a/core/src/site/resources/tags/text.html
+++ b/core/src/site/resources/tags/text.html
@@ -34,6 +34,38 @@
<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>
<td align="left" valign="top"></td>
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java
b/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java
index dae0d532a..856b9335b 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java
@@ -305,6 +305,46 @@ public void testPutId() throws Exception {
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
*
diff --git a/core/src/test/resources/org/apache/struts2/TestAction.properties
b/core/src/test/resources/org/apache/struts2/TestAction.properties
index 1ecb4cdfc..cd2ce8914 100644
--- a/core/src/test/resources/org/apache/struts2/TestAction.properties
+++ b/core/src/test/resources/org/apache/struts2/TestAction.properties
@@ -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
\ No newline at end of file
+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,","
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
> HTML escaping on the text tag
> -----------------------------
>
> Key: WW-4888
> URL: https://issues.apache.org/jira/browse/WW-4888
> Project: Struts 2
> Issue Type: Improvement
> Components: Core Tags
> Affects Versions: 2.5.13
> Reporter: Pierre-Yves Soblet
> Fix For: 2.5.14
>
> Attachments: text-vs-property.png
>
>
> Assuming an i18n bundle with the following entry:
> {code}
> sample.message=This is a dumb smiley <:‑|
> {code}
> The following tag produces a value that is properly escaped for HTML:
> {code}
> <s:property value="%{getText('sample.message')}"/>
> {code}
> However, the *text* tag does not escape the "<" character and cannot be
> safely used in HTML:
> {code}
> <s:text name="sample.message"/>
> {code}
> The text tag documentation
> (http://struts.apache.org/tag-developers/text-tag.html) neither states HTML
> escaping is performed nor warns it is not.
> In the FAQ, the "How to escape special chars in resource bundles" article
> (https://struts.apache.org/docs/how-to-escape-special-chars-in-resource-bundles.html)
> describes how to escape special characters of the MessageFormat syntax but
> does not mention HTML escaping.
> I assume HTML escaping on the text tag cannot be added now without breaking
> backward compatibility, but maybe an "escapeHtml" attribute could be added
> (as with the property tag)?
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)