Author: remy.maucherat(a)jboss.com
Date: 2010-02-01 08:38:55 -0500 (Mon, 01 Feb 2010)
New Revision: 1376
Modified:
trunk/java/org/apache/catalina/realm/JNDIRealm.java
trunk/java/org/apache/catalina/util/RequestUtil.java
trunk/java/org/apache/jasper/compiler/AttributeParser.java
trunk/java/org/apache/jasper/compiler/Generator.java
trunk/java/org/apache/jasper/compiler/Parser.java
trunk/java/org/apache/jasper/compiler/ScriptingVariabler.java
trunk/webapps/docs/changelog.xml
Log:
- Port 4 Tomcat patches, including two JSP regression fixes.
Modified: trunk/java/org/apache/catalina/realm/JNDIRealm.java
===================================================================
--- trunk/java/org/apache/catalina/realm/JNDIRealm.java 2010-01-27 14:57:29 UTC (rev
1375)
+++ trunk/java/org/apache/catalina/realm/JNDIRealm.java 2010-02-01 13:38:55 UTC (rev
1376)
@@ -381,6 +381,13 @@
protected String commonRole = null;
+ /**
+ * The timeout, in milliseconds, to use when trying to create a connection
+ * to the directory. The default is 5000 (5 seconds).
+ */
+ protected String connectionTimeout = "5000";
+
+
// ------------------------------------------------------------- Properties
/**
@@ -448,6 +455,28 @@
/**
+ * Return the connection timeout.
+ */
+ public String getConnectionTimeout() {
+
+ return connectionTimeout;
+
+ }
+
+
+ /**
+ * Set the connection timeout.
+ *
+ * @param timeout The new connection timeout
+ */
+ public void setConnectionTimeout(String timeout) {
+
+ this.connectionTimeout = timeout;
+
+ }
+
+
+ /**
* Return the connection URL for this Realm.
*/
public String getConnectionURL() {
@@ -1644,7 +1673,7 @@
Set<String> newThisRound = new HashSet<String>(); // Stores
the groups we find in this iteration
for (String groupDN : newGroupDNs) {
- filter = roleFormat.format(new String[] { groupDN });
+ filter = roleFormat.format(new String[] { groupDN, groupDN });
if (containerLog.isTraceEnabled()) {
containerLog.trace("Perform a nested group search with base
"+ roleBase + " and filter " + filter);
@@ -1962,6 +1991,8 @@
env.put(Context.REFERRAL, referrals);
if (derefAliases != null)
env.put(JNDIRealm.DEREF_ALIASES, derefAliases);
+ if (connectionTimeout != null)
+ env.put("com.sun.jndi.ldap.connect.timeout", connectionTimeout);
return env;
Modified: trunk/java/org/apache/catalina/util/RequestUtil.java
===================================================================
--- trunk/java/org/apache/catalina/util/RequestUtil.java 2010-01-27 14:57:29 UTC (rev
1375)
+++ trunk/java/org/apache/catalina/util/RequestUtil.java 2010-02-01 13:38:55 UTC (rev
1376)
@@ -281,7 +281,7 @@
* by a valid 2-digit hexadecimal number
*/
public static String URLDecode(byte[] bytes, String enc) {
- return URLDecode(bytes, null, false);
+ return URLDecode(bytes, enc, false);
}
/**
Modified: trunk/java/org/apache/jasper/compiler/AttributeParser.java
===================================================================
--- trunk/java/org/apache/jasper/compiler/AttributeParser.java 2010-01-27 14:57:29 UTC
(rev 1375)
+++ trunk/java/org/apache/jasper/compiler/AttributeParser.java 2010-02-01 13:38:55 UTC
(rev 1376)
@@ -24,7 +24,7 @@
* "\${1+1}". After unquoting, both appear as "${1+1}" but the first
should
* evaluate to "2" and the second to "${1+1}". Literal \, $ and #
need special
* treatment to ensure there is no ambiguity. The JSP attribute unquoting
- * covers \\, \", \', \$, \#, %\>, <\%, ' and "
+ * covers \\, \", \', \$, \#, %\>, <\%, &apos; and
&quot;
*/
public class AttributeParser {
@@ -43,13 +43,16 @@
* scripting expressions.
* @param isELIgnored Is expression language being ignored on the page
* where the JSP attribute is defined.
+ * @param isDeferredSyntaxAllowedAsLiteral
+ * Are deferred expressions treated as literals?
* @return An unquoted JSP attribute that, if it contains
* expression language can be safely passed to the EL
* processor without fear of ambiguity.
*/
public static String getUnquoted(String input, char quote,
- boolean isELIgnored) {
+ boolean isELIgnored, boolean isDeferredSyntaxAllowedAsLiteral) {
return (new AttributeParser(input, quote, isELIgnored,
+ isDeferredSyntaxAllowedAsLiteral,
STRICT_QUOTE_ESCAPING)).getUnquoted();
}
@@ -62,15 +65,18 @@
* scripting expressions.
* @param isELIgnored Is expression language being ignored on the page
* where the JSP attribute is defined.
+ * @param isDeferredSyntaxAllowedAsLiteral
+ * Are deferred expressions treated as literals?
* @param strict The value to use for STRICT_QUOTE_ESCAPING.
* @return An unquoted JSP attribute that, if it contains
* expression language can be safely passed to the EL
* processor without fear of ambiguity.
*/
protected static String getUnquoted(String input, char quote,
- boolean isELIgnored, boolean strict) {
+ boolean isELIgnored, boolean isDeferredSyntaxAllowedAsLiteral,
+ boolean strict) {
return (new AttributeParser(input, quote, isELIgnored,
- strict)).getUnquoted();
+ isDeferredSyntaxAllowedAsLiteral, strict)).getUnquoted();
}
/* The quoted input string. */
@@ -83,6 +89,9 @@
* treated as literals rather than quoted values. */
private final boolean isELIgnored;
+ /* Are deferred expression treated as literals */
+ private final boolean isDeferredSyntaxAllowedAsLiteral;
+
/* Overrides the STRICT_QUOTE_ESCAPING. Used for Unit tests only. */
private final boolean strict;
@@ -109,12 +118,15 @@
* @param strict
*/
private AttributeParser(String input, char quote,
- boolean isELIgnored, boolean strict) {
+ boolean isELIgnored, boolean isDeferredSyntaxAllowedAsLiteral,
+ boolean strict) {
this.input = input;
this.quote = quote;
// If quote is null this is a scriptign expressions and any EL syntax
// should be ignored
this.isELIgnored = isELIgnored || (quote == 0);
+ this.isDeferredSyntaxAllowedAsLiteral =
+ isDeferredSyntaxAllowedAsLiteral;
this.strict = strict;
this.type = getType(input);
this.size = input.length();
@@ -151,22 +163,27 @@
char ch = nextChar();
if (!isELIgnored && ch == '\\') {
if (type == 0) {
- type = '$';
+ result.append("\\");
+ } else {
+ result.append(type);
+ result.append("{'\\\\'}");
}
- result.append(type);
- result.append("{'\\\\'}");
} else if (!isELIgnored && ch == '$' &&
lastChEscaped){
if (type == 0) {
- type = '$';
+ result.append("\\$");
+ } else {
+ result.append(type);
+ result.append("{'$'}");
}
- result.append(type);
- result.append("{'$'}");
} else if (!isELIgnored && ch == '#' &&
lastChEscaped){
+ // Note if isDeferredSyntaxAllowedAsLiteral==true, \# will
+ // not be treated as an escape
if (type == 0) {
- type = '$';
+ result.append("\\#");
+ } else {
+ result.append(type);
+ result.append("{'#'}");
}
- result.append(type);
- result.append("{'#'}");
} else if (ch == type){
if (i < size) {
char next = input.charAt(i);
@@ -228,7 +245,7 @@
}
/*
- * Returns the nest unquoted character and sets the lastChEscaped flag to
+ * Returns the next unquoted character and sets the lastChEscaped flag to
* indicate if it was quoted/escaped or not.
* ' is always unquoted to '
* " is always unquoted to "
@@ -261,7 +278,10 @@
} else if (ch == '\\' && i + 1 < size) {
ch = input.charAt(i + 1);
if (ch == '\\' || ch == '\"' || ch == '\''
||
- (!isELIgnored && (ch == '$' || ch == '#')))
{
+ (!isELIgnored &&
+ (ch == '$' ||
+ (!isDeferredSyntaxAllowedAsLiteral &&
+ ch == '#')))) {
i += 2;
lastChEscaped = true;
} else {
@@ -311,13 +331,13 @@
int j = 0;
int len = value.length();
char current;
-
+
while (j < len) {
current = value.charAt(j);
if (current == '\\') {
// Escape character - skip a character
j++;
- } else if (current == '#') {
+ } else if (current == '#' &&
!isDeferredSyntaxAllowedAsLiteral) {
if (j < (len -1) && value.charAt(j + 1) == '{') {
return '#';
}
Modified: trunk/java/org/apache/jasper/compiler/Generator.java
===================================================================
--- trunk/java/org/apache/jasper/compiler/Generator.java 2010-01-27 14:57:29 UTC (rev
1375)
+++ trunk/java/org/apache/jasper/compiler/Generator.java 2010-02-01 13:38:55 UTC (rev
1376)
@@ -167,6 +167,25 @@
return b.toString();
}
+ /**
+ * Finds the <jsp:body> subelement of the given parent node. If not
+ * found, null is returned.
+ */
+ protected static Node.JspBody findJspBody(Node parent) {
+ Node.JspBody result = null;
+
+ Node.Nodes subelements = parent.getBody();
+ for (int i = 0; (subelements != null) && (i < subelements.size());
i++) {
+ Node n = subelements.getNode(i);
+ if (n instanceof Node.JspBody) {
+ result = (Node.JspBody) n;
+ break;
+ }
+ }
+
+ return result;
+ }
+
private String createJspId() throws JasperException {
if (this.jspIdPrefix == null) {
StringBuilder sb = new StringBuilder(32);
@@ -978,25 +997,6 @@
}
}
- /**
- * Finds the <jsp:body> subelement of the given parent node. If not
- * found, null is returned.
- */
- private Node.JspBody findJspBody(Node parent) throws JasperException {
- Node.JspBody result = null;
-
- Node.Nodes subelements = parent.getBody();
- for (int i = 0; (subelements != null) && (i < subelements.size());
i++) {
- Node n = subelements.getNode(i);
- if (n instanceof Node.JspBody) {
- result = (Node.JspBody) n;
- break;
- }
- }
-
- return result;
- }
-
public void visit(Node.ForwardAction n) throws JasperException {
Node.JspAttribute page = n.getPage();
Modified: trunk/java/org/apache/jasper/compiler/Parser.java
===================================================================
--- trunk/java/org/apache/jasper/compiler/Parser.java 2010-01-27 14:57:29 UTC (rev 1375)
+++ trunk/java/org/apache/jasper/compiler/Parser.java 2010-02-01 13:38:55 UTC (rev 1376)
@@ -247,7 +247,7 @@
quote = watch.charAt(0);
}
ret = AttributeParser.getUnquoted(reader.getText(start, stop),
- quote, pageInfo.isELIgnored());
+ quote, pageInfo.isELIgnored(),
pageInfo.isDeferredSyntaxAllowedAsLiteral());
} catch (IllegalArgumentException iae) {
err.jspError(start, iae.getMessage());
}
Modified: trunk/java/org/apache/jasper/compiler/ScriptingVariabler.java
===================================================================
--- trunk/java/org/apache/jasper/compiler/ScriptingVariabler.java 2010-01-27 14:57:29 UTC
(rev 1375)
+++ trunk/java/org/apache/jasper/compiler/ScriptingVariabler.java 2010-02-01 13:38:55 UTC
(rev 1376)
@@ -38,17 +38,17 @@
*/
static class CustomTagCounter extends Node.Visitor {
- private int count;
- private Node.CustomTag parent;
+ private int count;
+ private Node.CustomTag parent;
- public void visit(Node.CustomTag n) throws JasperException {
- n.setCustomTagParent(parent);
- Node.CustomTag tmpParent = parent;
- parent = n;
- visitBody(n);
- parent = tmpParent;
- n.setNumCount(new Integer(count++));
- }
+ public void visit(Node.CustomTag n) throws JasperException {
+ n.setCustomTagParent(parent);
+ Node.CustomTag tmpParent = parent;
+ parent = n;
+ visitBody(n);
+ parent = tmpParent;
+ n.setNumCount(new Integer(count++));
+ }
}
/*
@@ -57,92 +57,113 @@
*/
static class ScriptingVariableVisitor extends Node.Visitor {
- private ErrorDispatcher err;
- private Hashtable scriptVars;
-
- public ScriptingVariableVisitor(ErrorDispatcher err) {
- this.err = err;
- scriptVars = new Hashtable();
- }
+ private ErrorDispatcher err;
+ private Hashtable scriptVars;
- public void visit(Node.CustomTag n) throws JasperException {
- setScriptingVars(n, VariableInfo.AT_BEGIN);
- setScriptingVars(n, VariableInfo.NESTED);
- new ScriptingVariableVisitor(err).visitBody(n);
- setScriptingVars(n, VariableInfo.AT_END);
- }
+ public ScriptingVariableVisitor(ErrorDispatcher err) {
+ this.err = err;
+ scriptVars = new Hashtable();
+ }
- private void setScriptingVars(Node.CustomTag n, int scope)
- throws JasperException {
+ public void visit(Node.CustomTag n) throws JasperException {
+ setScriptingVars(n, VariableInfo.AT_BEGIN);
+ setScriptingVars(n, VariableInfo.NESTED);
+ visitBody(n);
+ setScriptingVars(n, VariableInfo.AT_END);
+ }
- TagVariableInfo[] tagVarInfos = n.getTagVariableInfos();
- VariableInfo[] varInfos = n.getVariableInfos();
- if (tagVarInfos.length == 0 && varInfos.length == 0) {
- return;
- }
+ private void setScriptingVars(Node.CustomTag n, int scope)
+ throws JasperException {
- Vector vec = new Vector();
+ TagVariableInfo[] tagVarInfos = n.getTagVariableInfos();
+ VariableInfo[] varInfos = n.getVariableInfos();
+ if (tagVarInfos.length == 0 && varInfos.length == 0) {
+ return;
+ }
- Integer ownRange = null;
- if (scope == VariableInfo.AT_BEGIN
- || scope == VariableInfo.AT_END) {
- Node.CustomTag parent = n.getCustomTagParent();
- if (parent == null)
- ownRange = MAX_SCOPE;
- else
- ownRange = parent.getNumCount();
- } else {
- // NESTED
- ownRange = n.getNumCount();
- }
+ Vector vec = new Vector();
- if (varInfos.length > 0) {
- for (int i=0; i<varInfos.length; i++) {
- if (varInfos[i].getScope() != scope
- || !varInfos[i].getDeclare()) {
- continue;
- }
- String varName = varInfos[i].getVarName();
-
- Integer currentRange = (Integer) scriptVars.get(varName);
- if (currentRange == null
- || ownRange.compareTo(currentRange) > 0) {
- scriptVars.put(varName, ownRange);
- vec.add(varInfos[i]);
- }
- }
- } else {
- for (int i=0; i<tagVarInfos.length; i++) {
- if (tagVarInfos[i].getScope() != scope
- || !tagVarInfos[i].getDeclare()) {
- continue;
- }
- String varName = tagVarInfos[i].getNameGiven();
- if (varName == null) {
- varName = n.getTagData().getAttributeString(
- tagVarInfos[i].getNameFromAttribute());
- if (varName == null) {
- err.jspError(n, "jsp.error.scripting.variable.missing_name",
- tagVarInfos[i].getNameFromAttribute());
- }
- }
+ Node.CustomTag parent = n.getCustomTagParent();
+ Integer ownRange = null;
+ if (scope == VariableInfo.AT_BEGIN
+ || scope == VariableInfo.AT_END) {
+ if (parent == null)
+ ownRange = MAX_SCOPE;
+ else
+ ownRange = parent.getNumCount();
+ } else {
+ // NESTED
+ ownRange = n.getNumCount();
+ }
- Integer currentRange = (Integer) scriptVars.get(varName);
- if (currentRange == null
- || ownRange.compareTo(currentRange) > 0) {
- scriptVars.put(varName, ownRange);
- vec.add(tagVarInfos[i]);
- }
- }
- }
+ if (varInfos.length > 0) {
+ for (int i=0; i<varInfos.length; i++) {
+ if (varInfos[i].getScope() != scope
+ || !varInfos[i].getDeclare()) {
+ continue;
+ }
+ String varName = varInfos[i].getVarName();
- n.setScriptingVars(vec, scope);
- }
+ Integer currentRange = (Integer) scriptVars.get(varName);
+ // If a fragment helper has been used for the parent tag
+ // the scripting variables always need to be declared
+ if (currentRange == null ||
+ ownRange.compareTo(currentRange) > 0 ||
+ parent != null && isImplementedAsFragment(parent)) {
+ scriptVars.put(varName, ownRange);
+ vec.add(varInfos[i]);
+ }
+ }
+ } else {
+ for (int i=0; i<tagVarInfos.length; i++) {
+ if (tagVarInfos[i].getScope() != scope
+ || !tagVarInfos[i].getDeclare()) {
+ continue;
+ }
+ String varName = tagVarInfos[i].getNameGiven();
+ if (varName == null) {
+ varName = n.getTagData().getAttributeString(
+ tagVarInfos[i].getNameFromAttribute());
+ if (varName == null) {
+ err.jspError(n,
"jsp.error.scripting.variable.missing_name",
+ tagVarInfos[i].getNameFromAttribute());
+ }
+ }
+
+ Integer currentRange = (Integer) scriptVars.get(varName);
+ // If a fragment helper has been used for the parent tag
+ // the scripting variables always need to be declared
+ if (currentRange == null ||
+ ownRange.compareTo(currentRange) > 0 ||
+ parent != null && isImplementedAsFragment(parent)) {
+ scriptVars.put(varName, ownRange);
+ vec.add(tagVarInfos[i]);
+ }
+ }
+ }
+
+ n.setScriptingVars(vec, scope);
+ }
}
+ private static boolean isImplementedAsFragment(Node.CustomTag n) {
+ // Replicates logic from Generator to determine if a fragment
+ // helper will be used
+ if (n.implementsSimpleTag()) {
+ if (Generator.findJspBody(n) == null) {
+ if (!n.hasEmptyBody()) {
+ return true;
+ }
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
public static void set(Node.Nodes page, ErrorDispatcher err)
- throws JasperException {
- page.visit(new CustomTagCounter());
- page.visit(new ScriptingVariableVisitor(err));
+ throws JasperException {
+ page.visit(new CustomTagCounter());
+ page.visit(new ScriptingVariableVisitor(err));
}
}
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2010-01-27 14:57:29 UTC (rev 1375)
+++ trunk/webapps/docs/changelog.xml 2010-02-01 13:38:55 UTC (rev 1376)
@@ -16,6 +16,34 @@
<body>
+<section name="JBoss Web 3.0.0.Beta3 (remm)">
+ <subsection name="Catalina">
+ <changelog>
+ <fix>
+ <bug>48629</bug>: Nested role seach fix in JNDI realm, submitted by
Gabriel. (markt)
+ </fix>
+ <fix>
+ Add LDAP connection timeout in JNDI realm. (markt)
+ </fix>
+ </changelog>
+ </subsection>
+ <subsection name="Coyote">
+ <changelog>
+ </changelog>
+ </subsection>
+ <subsection name="Jasper">
+ <changelog>
+ <fix>
+ <bug>48627</bug>: Don't convert literal attribute values to EL
since EL attributes
+ may not accept EL. (markt)
+ </fix>
+ <fix>
+ <bug>48616</bug>: Another variable declaration fix. (markt)
+ </fix>
+ </changelog>
+ </subsection>
+</section>
+
<section name="JBoss Web 3.0.0.Beta2 (remm)">
<subsection name="Catalina">
<changelog>