Skip to content

Commit

Permalink
Merge pull request #12 from weblegacy/bugfix/issue#11
Browse files Browse the repository at this point in the history
bugfix for issue #11 (skip xml entities in filter method)
  • Loading branch information
ste-gr authored Oct 22, 2023
2 parents 543a3ba + 4ca1dbf commit ccd2d45
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 17 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## 1.4.5 / YYYY-MM-DD

* #11: add html-code to test it
* #11: further improvements in the "filter" method, reformatting, one more test case
* #11: improved entity handling in "filter" method
* #11: added another test case
* #11: fixed regex, added more test cases
* #11: bugfix for issue #11 (skip xml entities in filter method)
* Change all `javax.*`- to `jakarta.*`-namespaces from groovy-examples
* Upgrade `jsf` from 2.3.18 to 3.0.2
* Bump `jstl` from 1.2.7 to 2.0.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
name="testbean" scope="session" validate="false"/>
<action path="/html-form-postback" forward="/html-form.jsp"
name="testbean" scope="session" validate="false"/>
<action path="/html-button" forward="/html-button.jsp"/>
<action path="/logic-forward" forward="/logic-forward.jsp"/>
<action path="/logic-forward-test-forward"
forward="/logic-forward-test-forward.jsp"/>
Expand Down
78 changes: 78 additions & 0 deletions apps/examples/src/main/webapp/exercise/html-button.jsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<html:html>
<head>
<title>Test html:button Tag</title>
</head>

<body bgcolor="white">

<div align="center">
<h1>Test struts html:button Tag</h1>
</div>

<h2>Button</h2>
<p>
<html:button property="Test" value="Test"/>
</p>
<p>
<html:button property="Test äöü" value="Test äöü"/>
</p>
<p>
Test for XML Entities not handled correctly #11:
<html:button property="Test &auml;&ouml;&uuml;" value="Test &auml;&ouml;&uuml;"/>
</p>

<h2>Cancel</h2>
<p>
<html:cancel property="Test" value="Test"/>
</p>
<p>
<html:cancel property="Test äöü" value="Test äöü"/>
</p>
<p>
Test for XML Entities not handled correctly #11:
<html:cancel property="Test &auml;&ouml;&uuml;" value="Test &auml;&ouml;&uuml;"/>
</p>

<h2>Reset</h2>
<p>
<html:reset property="Test" value="Test"/>
</p>
<p>
<html:reset property="Test äöü" value="Test äöü"/>
</p>
<p>
Test for XML Entities not handled correctly #11:
<html:reset property="Test &auml;&ouml;&uuml;" value="Test &auml;&ouml;&uuml;"/>
</p>

<hr/>

<p>
<html:link action="welcome">
Return to the Taglib Exercises main page
</html:link>
</p>

</body>
</html:html>
2 changes: 2 additions & 0 deletions apps/examples/src/main/webapp/exercise/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ <h3>HTML Tags</h3>

<li><a href="html-form.do">&lt;html:form&gt;</a></li>

<li><a href="html-button.do">&lt;html:button&gt;</a></li>

<li>Other html tags [:TODO:]</li>

</ul>
Expand Down
81 changes: 64 additions & 17 deletions core/src/main/java/org/apache/struts/util/ResponseUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,51 +23,81 @@
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* General purpose utility methods related to generating a servlet response in
* the Struts controller framework.
*
* @version $Rev$ $Date: 2005-08-21 14:46:28 -0400 (Sun, 21 Aug 2005)
* $
*/
public class ResponseUtils {

// ------------------------------------------------------- Static Variables

/**
* The {@code Log} instance for this class.
*/
private static final Logger LOG =
LoggerFactory.getLogger(ResponseUtils.class);

/**
* Pattern to find XML-Entity-Patterns.
*
* <p>Valid patterns are:</p>
*
* <ul>
* <li>&amp;[a-zA-Z][a-z-A-Z0-9]*; - &amp;amp;, &amp;quot;</li>
* <li>&amp;#[0-9]+; - &amp;#32;, &amp;#64;</li>
* <li>&amp;#x[a-fA-F0-9]+; - &amp;#x20, &amp;3f</li>
* </ul>
*
* <p>See also <a href="https://www.w3.org/TR/xml11/#sec-references">
* XML-Reference 1.1</a>.</p>
*/
private static final Pattern XML_ENTITY_PATTERN =
Pattern.compile("&(?:[a-zA-Z][a-zA-Z\\d]*|#\\d+|#x[a-fA-F\\d]+);");

/**
* The message resources for this package.
*/
protected static MessageResources messages =
MessageResources.getMessageResources(
"org.apache.struts.util.LocalStrings");

// ----------------------------------------------------------- Constructors

/**
* The {@code Log} instance for this class.
* Class is not instanceable.
*/
private final static Logger LOG =
LoggerFactory.getLogger(ResponseUtils.class);
protected ResponseUtils() {
}

// --------------------------------------------------------- Public Methods

/**
* Filter the specified string for characters that are senstive to HTML
* Filter the specified string for characters that are sensitive to HTML
* interpreters, returning the string with these characters replaced by
* the corresponding character entities.
*
* @param value The string to be filtered and returned
*
* @return String The filtered string
*/
public static String filter(String value) {
if ((value == null) || (value.length() == 0)) {
if (value == null || value.isEmpty()) {
return value;
}

final int length = value.length();

StringBuilder result = null;
String filtered = null;
String filtered;
Matcher entityMatcher = null;

for (int i = 0; i < value.length(); i++) {
for (int i = 0; i < length; i++) {
filtered = null;

switch (value.charAt(i)) {
Expand All @@ -82,7 +112,19 @@ public static String filter(String value) {
break;

case '&':
filtered = "&amp;";
if (entityMatcher == null) {
entityMatcher = XML_ENTITY_PATTERN.matcher(value);
}
entityMatcher.region(i, length);
if (entityMatcher.lookingAt()) {
filtered = value.substring(entityMatcher.start(), entityMatcher.end());
i += filtered.length() - 1;
if (result == null) {
continue;
}
} else {
filtered = "&amp;";
}

break;

Expand All @@ -95,11 +137,14 @@ public static String filter(String value) {
filtered = "&#39;";

break;

default:
break;
}

if (result == null) {
if (filtered != null) {
result = new StringBuilder(value.length() + 50);
result = new StringBuilder(length + 50);

if (i > 0) {
result.append(value.substring(0, i));
Expand All @@ -116,13 +161,14 @@ public static String filter(String value) {
}
}

return (result == null) ? value : result.toString();
return result == null ? value : result.toString();
}

/**
* URLencodes a string assuming the character encoding is UTF-8.
*
* @param url
* @param url The url to encode
*
* @return String The encoded url in UTF-8
*/
public static String encodeURL(String url) {
Expand All @@ -134,14 +180,16 @@ public static String encodeURL(String url) {
* encoding charset didn't found, then it will be tried with the
* default-charset.
*
* @param url The url to encode
* @param enc The character encoding the urlencode is performed on.
*
* @return String The encoded url.
*/
public static String encodeURL(String url, String enc) {
String str = null;

try {
if ((enc == null) || (enc.length() == 0)) {
if (enc == null || enc.isEmpty()) {
enc = "UTF-8";
}

Expand All @@ -160,6 +208,5 @@ public static String encodeURL(String url, String enc) {
}

return str;

}
}
}
66 changes: 66 additions & 0 deletions core/src/test/java/org/apache/struts/util/TestResponseUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts.util;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.apache.struts.mock.TestMockBase;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

/**
* Unit tests for {@link ResponseUtils}.
*
* @version $Rev$ $Date$
*/
public class TestResponseUtils extends TestMockBase {
// ----------------------------------------------------- Instance Variables
// ----------------------------------------------------- Setup and Teardown
@BeforeEach
public void setUp() {
super.setUp();
}

@AfterEach
public void tearDown() {
super.tearDown();
}

// ------------------------------------------------------- Individual Tests
// ---------------------------------------------------------- filter()
@Test
public void testFilter() {
assertEquals("123&amp;456", ResponseUtils.filter("123&456"));
assertEquals("123&amp;456;", ResponseUtils.filter("123&456;"));
assertEquals("123&amp;456", ResponseUtils.filter("123&amp;456"));
assertEquals("123&#123;456", ResponseUtils.filter("123&#123;456"));
assertEquals("123&amp;#12a;456", ResponseUtils.filter("123&#12a;456"));
assertEquals("123&#x12a;456", ResponseUtils.filter("123&#x12a;456"));
assertEquals("123&amp;#x12ah;456", ResponseUtils.filter("123&#x12ah;456"));
assertEquals("123&lt;&gt;&quot;&#39;456", ResponseUtils.filter("123<>\"'456"));
assertEquals("123&Uuml;456;", ResponseUtils.filter("123&Uuml;456;"));
assertEquals("123&x;456", ResponseUtils.filter("123&x;456"));
assertEquals("123&amp;1;456", ResponseUtils.filter("123&1;456"));
assertEquals("&amp;456&Uuml;4", ResponseUtils.filter("&amp;456&Uuml;4"));
assertEquals("&amp;45&amp;6&Uuml;4&#39;", ResponseUtils.filter("&amp;45&6&Uuml;4'"));
}
}

0 comments on commit ccd2d45

Please sign in to comment.