JBossWeb SVN: r1383 - in trunk: java/org/apache/catalina/startup and 1 other directories.
by jbossweb-commits@lists.jboss.org
Author: jfrederic.clere(a)jboss.com
Date: 2010-02-10 07:35:31 -0500 (Wed, 10 Feb 2010)
New Revision: 1383
Modified:
trunk/java/org/apache/catalina/loader/LocalStrings.properties
trunk/java/org/apache/catalina/loader/WebappClassLoader.java
trunk/java/org/apache/catalina/startup/ContextConfig.java
trunk/java/org/apache/catalina/startup/ExpandWar.java
trunk/java/org/apache/catalina/startup/HostConfig.java
trunk/java/org/apache/catalina/startup/LocalStrings.properties
trunk/webapps/docs/changelog.xml
Log:
Port 892815 (even we don't use that part).
Modified: trunk/java/org/apache/catalina/loader/LocalStrings.properties
===================================================================
--- trunk/java/org/apache/catalina/loader/LocalStrings.properties 2010-02-10 09:38:30 UTC (rev 1382)
+++ trunk/java/org/apache/catalina/loader/LocalStrings.properties 2010-02-10 12:35:31 UTC (rev 1383)
@@ -13,7 +13,9 @@
standardLoader.removeRepository=Removing repository {0}
standardLoader.starting=Starting this Loader
standardLoader.stopping=Stopping this Loader
+webappClassLoader.illegalJarPath=Illegal JAR entry detected with name {0}
webappClassLoader.stopped=Illegal access: this web application instance has been stopped already. Could not load {0}. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
+webappClassLoader.validationErrorJarPath=Unable to validate JAR entry with name {0}
webappLoader.addRepository=Adding repository {0}
webappLoader.deploy=Deploying class repositories to work directory {0}
webappLoader.jarDeploy=Deploy JAR {0} to {1}
Modified: trunk/java/org/apache/catalina/loader/WebappClassLoader.java
===================================================================
--- trunk/java/org/apache/catalina/loader/WebappClassLoader.java 2010-02-10 09:38:30 UTC (rev 1382)
+++ trunk/java/org/apache/catalina/loader/WebappClassLoader.java 2010-02-10 12:35:31 UTC (rev 1383)
@@ -284,8 +284,8 @@
* Path where resources loaded from JARs will be extracted.
*/
protected File loaderDir = null;
+ protected String canonicalLoaderDir = null;
-
/**
* The PermissionCollection for each CodeSource for a web
* application context.
@@ -442,6 +442,18 @@
*/
public void setWorkDir(File workDir) {
this.loaderDir = new File(workDir, "loader");
+ if (loaderDir == null) {
+ canonicalLoaderDir = null;
+ } else {
+ try {
+ canonicalLoaderDir = loaderDir.getCanonicalPath();
+ if (!canonicalLoaderDir.endsWith(File.separator)) {
+ canonicalLoaderDir += File.separator;
+ }
+ } catch (IOException ioe) {
+ canonicalLoaderDir = null;
+ }
+ }
}
/**
@@ -1514,6 +1526,18 @@
&& (!jarEntry2.getName().endsWith(".class"))) {
resourceFile = new File
(loaderDir, jarEntry2.getName());
+ try {
+ if (!resourceFile.getCanonicalPath().startsWith(
+ canonicalLoaderDir)) {
+ throw new IllegalArgumentException(
+ sm.getString("webappClassLoader.illegalJarPath",
+ jarEntry2.getName()));
+ }
+ } catch (IOException ioe) {
+ throw new IllegalArgumentException(
+ sm.getString("webappClassLoader.validationErrorJarPath",
+ jarEntry2.getName()), ioe);
+ }
resourceFile.getParentFile().mkdirs();
FileOutputStream os = null;
InputStream is = null;
Modified: trunk/java/org/apache/catalina/startup/ContextConfig.java
===================================================================
--- trunk/java/org/apache/catalina/startup/ContextConfig.java 2010-02-10 09:38:30 UTC (rev 1382)
+++ trunk/java/org/apache/catalina/startup/ContextConfig.java 2010-02-10 12:35:31 UTC (rev 1383)
@@ -1618,9 +1618,8 @@
if (contextPath.equals("")) {
contextPath = "ROOT";
} else {
- if (contextPath.lastIndexOf('/') > 0) {
- contextPath = "/" + contextPath.substring(1).replace('/','#');
- }
+ // Context path must start with '/'
+ contextPath = "/" + contextPath.substring(1).replace('/','#');
}
if (docBase.toLowerCase().endsWith(".war") && !file.isDirectory() && unpackWARs) {
URL war = new URL("jar:" + (new File(docBase)).toURI().toURL() + "!/");
@@ -1630,18 +1629,24 @@
if (context instanceof StandardContext) {
((StandardContext) context).setOriginalDocBase(origDocBase);
}
+ } else if (docBase.toLowerCase().endsWith(".war") &&
+ !file.isDirectory() && !unpackWARs) {
+ URL war =
+ new URL("jar:" + (new File (docBase)).toURI().toURL() + "!/");
+ ExpandWar.validate(host, war, contextPath);
} else {
File docDir = new File(docBase);
if (!docDir.exists()) {
File warFile = new File(docBase + ".war");
+ URL war = new URL("jar:" + warFile.toURI().toURL() + "!/");
if (warFile.exists()) {
if (unpackWARs) {
- URL war = new URL("jar:" + warFile.toURI().toURL() + "!/");
docBase = ExpandWar.expand(host, war, contextPath);
file = new File(docBase);
docBase = file.getCanonicalPath();
} else {
docBase = warFile.getCanonicalPath();
+ ExpandWar.validate(host, war, contextPath);
}
}
if (context instanceof StandardContext) {
@@ -2055,7 +2060,8 @@
if (!docBaseFile.isAbsolute()) {
docBaseFile = new File(appBase, docBase);
}
- ExpandWar.delete(docBaseFile);
+ // No need to log failure - it is expected in this case
+ ExpandWar.delete(docBaseFile, false);
}
overlays.clear();
Modified: trunk/java/org/apache/catalina/startup/ExpandWar.java
===================================================================
--- trunk/java/org/apache/catalina/startup/ExpandWar.java 2010-02-10 09:38:30 UTC (rev 1382)
+++ trunk/java/org/apache/catalina/startup/ExpandWar.java 2010-02-10 12:35:31 UTC (rev 1383)
@@ -105,7 +105,8 @@
* (must start with "jar:")
* @param pathname Context path name for web application
*
- * @exception IllegalArgumentException if this is not a "jar:" URL
+ * @exception IllegalArgumentException if this is not a "jar:" URL or if the
+ * WAR file is invalid
* @exception IOException if an input/output error was encountered
* during expansion
*/
@@ -123,6 +124,7 @@
(sm.getString("hostConfig.appBase",
appBase.getAbsolutePath()));
}
+
File docBase = new File(appBase, pathname);
if (docBase.exists()) {
// War file is already installed
@@ -133,16 +135,29 @@
docBase.mkdir();
// Expand the WAR into the new document base directory
+ String canonicalDocBasePrefix = docBase.getCanonicalPath();
+ if (!canonicalDocBasePrefix.endsWith(File.separator)) {
+ canonicalDocBasePrefix += File.separator;
+ }
JarURLConnection juc = (JarURLConnection) war.openConnection();
juc.setUseCaches(false);
JarFile jarFile = null;
InputStream input = null;
+ boolean success = false;
try {
jarFile = juc.getJarFile();
Enumeration jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = (JarEntry) jarEntries.nextElement();
String name = jarEntry.getName();
+ File expandedFile = new File(docBase, name);
+ if (!expandedFile.getCanonicalPath().startsWith(
+ canonicalDocBasePrefix)) {
+ // Trying to expand outside the docBase
+ // Throw an exception to stop the deployment
+ throw new IllegalArgumentException(
+ sm.getString("expandWar.illegalPath",war, name));
+ }
int last = name.lastIndexOf('/');
if (last >= 0) {
File parent = new File(docBase,
@@ -155,21 +170,24 @@
input = jarFile.getInputStream(jarEntry);
// Bugzilla 33636
- File expandedFile = expand(input, docBase, name);
+ expand(input, expandedFile);
long lastModified = jarEntry.getTime();
- if ((lastModified != -1) && (lastModified != 0) && (expandedFile != null)) {
+ if ((lastModified != -1) && (lastModified != 0)) {
expandedFile.setLastModified(lastModified);
}
input.close();
input = null;
}
+ success = true;
} catch (IOException e) {
- // If something went wrong, delete expanded dir to keep things
- // clean
- deleteDir(docBase);
throw e;
} finally {
+ if (!success) {
+ // If something went wrong, delete expanded dir to keep things
+ // clean
+ deleteDir(docBase);
+ }
if (input != null) {
try {
input.close();
@@ -195,6 +213,69 @@
/**
+ * Validate the WAR file found at the specified URL.
+ *
+ * @param host Host war is being installed for
+ * @param war URL of the web application archive to be validated
+ * (must start with "jar:")
+ * @param pathname Context path name for web application
+ *
+ * @exception IllegalArgumentException if this is not a "jar:" URL or if the
+ * WAR file is invalid
+ * @exception IOException if an input/output error was encountered
+ * during validation
+ */
+ public static void validate(Host host, URL war, String pathname)
+ throws IOException {
+
+ // Make the appBase absolute
+ File appBase = new File(host.getAppBase());
+ if (!appBase.isAbsolute()) {
+ appBase = new File(System.getProperty("catalina.base"),
+ host.getAppBase());
+ }
+
+ File docBase = new File(appBase, pathname);
+
+ // Calculate the document base directory
+ String canonicalDocBasePrefix = docBase.getCanonicalPath();
+ if (!canonicalDocBasePrefix.endsWith(File.separator)) {
+ canonicalDocBasePrefix += File.separator;
+ }
+ JarURLConnection juc = (JarURLConnection) war.openConnection();
+ juc.setUseCaches(false);
+ JarFile jarFile = null;
+ try {
+ jarFile = juc.getJarFile();
+ Enumeration<JarEntry> jarEntries = jarFile.entries();
+ while (jarEntries.hasMoreElements()) {
+ JarEntry jarEntry = jarEntries.nextElement();
+ String name = jarEntry.getName();
+ File expandedFile = new File(docBase, name);
+ if (!expandedFile.getCanonicalPath().startsWith(
+ canonicalDocBasePrefix)) {
+ // Entry located outside the docBase
+ // Throw an exception to stop the deployment
+ throw new IllegalArgumentException(
+ sm.getString("expandWar.illegalPath",war, name));
+ }
+ }
+ } catch (IOException e) {
+ throw e;
+ } finally {
+ if (jarFile != null) {
+ try {
+ jarFile.close();
+ } catch (Throwable t) {
+ // Ignore
+ }
+ jarFile = null;
+ }
+ }
+ }
+
+
+ /**
* Copy the specified file or directory to the destination.
*
* @param src File object representing the source
@@ -254,27 +335,62 @@
/**
* Delete the specified directory, including all of its contents and
- * subdirectories recursively.
+ * sub-directories recursively. Any failure will be logged.
*
* @param dir File object representing the directory to be deleted
*/
public static boolean delete(File dir) {
+ // Log failure by default
+ return delete(dir, true);
+ }
+
+ /**
+ * Delete the specified directory, including all of its contents and
+ * sub-directories recursively.
+ *
+ * @param dir File object representing the directory to be deleted
+ * @param logFailure <code>true</code> if failure to delete the resource
+ * should be logged
+ */
+ public static boolean delete(File dir, boolean logFailure) {
+ boolean result;
if (dir.isDirectory()) {
- return deleteDir(dir);
+ result = deleteDir(dir, logFailure);
} else {
- return dir.delete();
+ if (dir.exists()) {
+ result = dir.delete();
+ } else {
+ result = true;
+ }
}
+ if (logFailure && !result) {
+ log.error(sm.getString(
+ "expandWar.deleteFailed", dir.getAbsolutePath()));
+ }
+ return result;
}
/**
* Delete the specified directory, including all of its contents and
- * subdirectories recursively.
+ * sub-directories recursively. Any failure will be logged.
*
* @param dir File object representing the directory to be deleted
*/
public static boolean deleteDir(File dir) {
+ return deleteDir(dir, true);
+ }
+ /**
+ * Delete the specified directory, including all of its contents and
+ * sub-directories recursively.
+ *
+ * @param dir File object representing the directory to be deleted
+ * @param logFailure <code>true</code> if failure to delete the resource
+ * should be logged
+ */
+ public static boolean deleteDir(File dir, boolean logFailure) {
+
String files[] = dir.list();
if (files == null) {
files = new String[0];
@@ -282,13 +398,26 @@
for (int i = 0; i < files.length; i++) {
File file = new File(dir, files[i]);
if (file.isDirectory()) {
- deleteDir(file);
+ deleteDir(file, logFailure);
} else {
file.delete();
}
}
- return dir.delete();
+ boolean result;
+ if (dir.exists()) {
+ result = dir.delete();
+ } else {
+ result = true;
+ }
+
+ if (logFailure && !result) {
+ log.error(sm.getString(
+ "expandWar.deleteFailed", dir.getAbsolutePath()));
+ }
+
+ return result;
+
}
@@ -302,11 +431,27 @@
* @return A handle to the expanded File
*
* @exception IOException if an input/output error occurs
+ *
+ * @deprecated
*/
protected static File expand(InputStream input, File docBase, String name)
throws IOException {
+ File file = new File(docBase, name);
+ expand(input, file);
+ return file;
+ }
- File file = new File(docBase, name);
+
+ /**
+ * Expand the specified input stream into the specified file.
+ *
+ * @param input InputStream to be copied
+ * @param file The file to be created
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ private static void expand(InputStream input, File file)
+ throws IOException {
BufferedOutputStream output = null;
try {
output =
@@ -327,8 +472,6 @@
}
}
}
-
- return file;
}
Modified: trunk/java/org/apache/catalina/startup/HostConfig.java
===================================================================
--- trunk/java/org/apache/catalina/startup/HostConfig.java 2010-02-10 09:38:30 UTC (rev 1382)
+++ trunk/java/org/apache/catalina/startup/HostConfig.java 2010-02-10 12:35:31 UTC (rev 1383)
@@ -28,7 +28,9 @@
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -141,6 +143,11 @@
*/
protected static Digester digester = createDigester();
+ /**
+ * The list of Wars in the appBase to be ignored because they are invalid
+ * (e.g. contain /../ sequences).
+ */
+ protected Set<String> invalidWars = new HashSet<String>();
// ------------------------------------------------------------- Properties
@@ -656,13 +663,22 @@
if (files[i].equalsIgnoreCase("WEB-INF"))
continue;
File dir = new File(appBase, files[i]);
- if (files[i].toLowerCase().endsWith(".war") && dir.isFile()) {
+ if (files[i].toLowerCase().endsWith(".war") && dir.isFile()
+ && !invalidWars.contains(files[i]) ) {
// Calculate the context path and make sure it is unique
String contextPath = "/" + files[i].replace('#','/');
int period = contextPath.lastIndexOf(".");
- if (period >= 0)
- contextPath = contextPath.substring(0, period);
+ contextPath = contextPath.substring(0, period);
+
+ // Check for WARs with /../ /./ or similar sequences in the name
+ if (!validateContextPath(appBase, contextPath)) {
+ log.error(sm.getString(
+ "hostConfig.illegalWarName", files[i]));
+ invalidWars.add(files[i]);
+ continue;
+ }
+
if (contextPath.equals("/ROOT"))
contextPath = "";
@@ -680,6 +696,42 @@
}
+ private boolean validateContextPath(File appBase, String contextPath) {
+ // More complicated than the ideal as the canonical path may or may
+ // not end with File.separator for a directory
+
+ StringBuilder docBase;
+ String canonicalDocBase = null;
+
+ try {
+ String canonicalAppBase = appBase.getCanonicalPath();
+ docBase = new StringBuilder(canonicalAppBase);
+ if (canonicalAppBase.endsWith(File.separator)) {
+ docBase.append(contextPath.substring(1).replace(
+ '/', File.separatorChar));
+ } else {
+ docBase.append(contextPath.replace('/', File.separatorChar));
+ }
+ // At this point docBase should be canonical but will not end
+ // with File.separator
+
+ canonicalDocBase =
+ (new File(docBase.toString())).getCanonicalPath();
+
+ // If the canonicalDocBase ends with File.separator, add one to
+ // docBase before they are compared
+ if (canonicalDocBase.endsWith(File.separator)) {
+ docBase.append(File.separator);
+ }
+ } catch (IOException ioe) {
+ return false;
+ }
+
+ // Compare the two. If they are not the same, the contextPath must
+ // have /../ like sequences in it
+ return canonicalDocBase.equals(docBase.toString());
+ }
+
/**
* @param contextPath
* @param war
Modified: trunk/java/org/apache/catalina/startup/LocalStrings.properties
===================================================================
--- trunk/java/org/apache/catalina/startup/LocalStrings.properties 2010-02-10 09:38:30 UTC (rev 1382)
+++ trunk/java/org/apache/catalina/startup/LocalStrings.properties 2010-02-10 12:35:31 UTC (rev 1383)
@@ -47,6 +47,8 @@
engineConfig.start=EngineConfig: Processing START
engineConfig.stop=EngineConfig: Processing STOP
expandWar.copy=Error copying {0} to {1}
+expandWar.deleteFailed=[{0}] could not be completely deleted. The presence of the remaining files may cause problems
+expandWar.illegalPath=The archive [{0}] is malformed and will be ignored: an entry contains an illegal path [{1}]
hostConfig.appBase=Application base directory {0} does not exist
hostConfig.canonicalizing=Error delete redeploy resources from context [{0}]
hostConfig.cce=Lifecycle event data object {0} is not a Host
@@ -66,6 +68,7 @@
hostConfig.expand=Expanding web application archive {0}
hostConfig.expand.error=Exception while expanding web application archive {0}
hostConfig.expanding=Expanding discovered web application archives
+hostConfig.illegalWarName=The war name [{0}] is invalid. The archive will be ignored.
hostConfig.jmx.register=Register context [{0}] failed
hostConfig.jmx.unregister=Unregister context [{0}] failed
hostConfig.reload=Reloading context [{0}]
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2010-02-10 09:38:30 UTC (rev 1382)
+++ trunk/webapps/docs/changelog.xml 2010-02-10 12:35:31 UTC (rev 1383)
@@ -70,6 +70,12 @@
<add>
On demand webapp startup plumbing, submitted by Brian Stansberry. (remm)
</add>
+ <fix>
+ Various (un)deployment related improvements including better handling of
+ failed (un)deployment, additional checking for valid zip entries that
+ don't make sense in a WAR and improved validation of WAR file names.
+ (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
14 years, 10 months
JBossWeb SVN: r1382 - branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/tomcat/util/net/jsse.
by jbossweb-commits@lists.jboss.org
Author: jfrederic.clere(a)jboss.com
Date: 2010-02-10 04:38:30 -0500 (Wed, 10 Feb 2010)
New Revision: 1382
Modified:
branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/tomcat/util/net/jsse/JSSESupport.java
Log:
Port r1270.
Modified: branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java
===================================================================
--- branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java 2010-02-08 14:10:38 UTC (rev 1381)
+++ branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java 2010-02-10 09:38:30 UTC (rev 1382)
@@ -42,6 +42,8 @@
import java.util.Vector;
import javax.net.ssl.CertPathTrustManagerParameters;
+import javax.net.ssl.HandshakeCompletedEvent;
+import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.ManagerFactoryParameters;
@@ -95,6 +97,7 @@
protected String clientAuth = "false";
protected SSLServerSocketFactory sslProxy = null;
protected String[] enabledCiphers;
+ protected boolean allowUnsafeLegacyRenegotiation = false;
/**
* Flag to state that we require client authentication.
@@ -145,13 +148,36 @@
SSLSocket asock = null;
try {
asock = (SSLSocket)socket.accept();
+ if (!allowUnsafeLegacyRenegotiation) {
+ asock.addHandshakeCompletedListener(
+ new DisableSslRenegotiation());
+ }
configureClientAuth(asock);
} catch (SSLException e){
throw new SocketException("SSL handshake error" + e.toString());
}
return asock;
}
+
+ private static class DisableSslRenegotiation
+ implements HandshakeCompletedListener {
+ private volatile boolean completed = false;
+ public void handshakeCompleted(HandshakeCompletedEvent event) {
+ if (completed) {
+ try {
+ log.warn("SSL renegotiation is disabled, closing connection");
+ event.getSession().invalidate();
+ event.getSocket().close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ completed = true;
+ }
+ }
+
+
public void handshake(Socket sock) throws IOException {
((SSLSocket)sock).startHandshake();
}
Modified: branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/tomcat/util/net/jsse/JSSESupport.java
===================================================================
--- branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/tomcat/util/net/jsse/JSSESupport.java 2010-02-08 14:10:38 UTC (rev 1381)
+++ branches/JBOSSWEB_2_0_0_GA_CP/src/share/classes/org/apache/tomcat/util/net/jsse/JSSESupport.java 2010-02-10 09:38:30 UTC (rev 1382)
@@ -170,7 +170,10 @@
break;
}
}
- ssl.setSoTimeout(oldTimeout);
+ // If legacy re-negotiation is disabled, socked could be closed here
+ if (!ssl.isClosed()) {
+ ssl.setSoTimeout(oldTimeout);
+ }
if (listener.completed == false) {
throw new SocketException("SSL Cert handshake timeout");
}
14 years, 10 months
JBossWeb SVN: r1381 - in trunk: webapps/docs and 1 other directory.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2010-02-08 09:10:38 -0500 (Mon, 08 Feb 2010)
New Revision: 1381
Modified:
trunk/java/org/apache/jasper/compiler/Parser.java
trunk/webapps/docs/changelog.xml
Log:
- Another EL handling fix.
Modified: trunk/java/org/apache/jasper/compiler/Parser.java
===================================================================
--- trunk/java/org/apache/jasper/compiler/Parser.java 2010-02-04 13:46:08 UTC (rev 1380)
+++ trunk/java/org/apache/jasper/compiler/Parser.java 2010-02-08 14:10:38 UTC (rev 1381)
@@ -1408,9 +1408,9 @@
parseXMLScriptlet(parent);
} else if (reader.matches("<jsp:text")) {
parseXMLTemplateText(parent);
- } else if (reader.matches("${") && !pageInfo.isELIgnored()) {
+ } else if (!pageInfo.isELIgnored() && reader.matches("${")) {
parseELExpression(parent, '$');
- } else if (reader.matches("#{") && !pageInfo.isELIgnored()) {
+ } else if (!pageInfo.isELIgnored() && reader.matches("#{")) {
parseELExpression(parent, '#');
} else if (reader.matches("<jsp:")) {
parseStandardAction(parent);
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2010-02-04 13:46:08 UTC (rev 1380)
+++ trunk/webapps/docs/changelog.xml 2010-02-08 14:10:38 UTC (rev 1381)
@@ -44,6 +44,9 @@
<fix>
<bug>48616</bug>: Another variable declaration fix. (markt)
</fix>
+ <fix>
+ <bug>48668</bug>: Fix handling of EL like strings when EL is disabled. (markt)
+ </fix>
</changelog>
</subsection>
</section>
14 years, 10 months
JBossWeb SVN: r1380 - trunk/java/org/apache/jasper/compiler.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2010-02-04 08:46:08 -0500 (Thu, 04 Feb 2010)
New Revision: 1380
Modified:
trunk/java/org/apache/jasper/compiler/AttributeParser.java
Log:
- Port small EL patch.
Modified: trunk/java/org/apache/jasper/compiler/AttributeParser.java
===================================================================
--- trunk/java/org/apache/jasper/compiler/AttributeParser.java 2010-02-03 15:17:04 UTC (rev 1379)
+++ trunk/java/org/apache/jasper/compiler/AttributeParser.java 2010-02-04 13:46:08 UTC (rev 1380)
@@ -214,8 +214,8 @@
private void parseEL() {
boolean endEL = false;
boolean insideLiteral = false;
+ char literalQuote = 0;
while (i < size && !endEL) {
- char literalQuote = '\'';
char ch = nextChar();
if (ch == '\'' || ch == '\"') {
if (insideLiteral) {
14 years, 11 months
JBossWeb SVN: r1379 - in trunk: java/org/apache/naming and 1 other directories.
by jbossweb-commits@lists.jboss.org
Author: remy.maucherat(a)jboss.com
Date: 2010-02-03 10:17:04 -0500 (Wed, 03 Feb 2010)
New Revision: 1379
Modified:
trunk/java/org/apache/catalina/valves/RemoteIpValve.java
trunk/java/org/apache/naming/NamingContext.java
trunk/webapps/docs/changelog.xml
Log:
- Port IP valve update.
- createSubcontext oops fix.
Modified: trunk/java/org/apache/catalina/valves/RemoteIpValve.java
===================================================================
--- trunk/java/org/apache/catalina/valves/RemoteIpValve.java 2010-02-02 15:20:12 UTC (rev 1378)
+++ trunk/java/org/apache/catalina/valves/RemoteIpValve.java 2010-02-03 15:17:04 UTC (rev 1379)
@@ -26,10 +26,14 @@
import java.util.regex.PatternSyntaxException;
import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import org.apache.tomcat.util.res.StringManager;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
-import org.apache.tomcat.util.res.StringManager;
+import org.apache.catalina.valves.Constants;
+import org.apache.catalina.valves.RequestFilterValve;
+import org.apache.catalina.valves.ValveBase;
/**
* <p>
@@ -121,6 +125,19 @@
* <td><code>https</code></td>
* </tr>
* <tr>
+ * <td>httpServerPort</td>
+ * <td>Value returned by {@link ServletRequest#getServerPort()} when the <code>protocolHeader</code> indicates <code>http</code> protocol</td>
+ * <td>N/A</td>
+ * <td>integer</td>
+ * <td>80</td>
+ * </tr>
+ * <tr>
+ * <td>httpsServerPort</td>
+ * <td>Value returned by {@link ServletRequest#getServerPort()} when the <code>protocolHeader</code> indicates <code>https</code> protocol</td>
+ * <td>N/A</td>
+ * <td>integer</td>
+ * <td>443</td>
+ * </tr>
* </table>
* </p>
* <p>
@@ -348,7 +365,7 @@
/**
* The StringManager for this package.
*/
- protected static StringManager sm = StringManager.getManager(Constants.Package);
+ protected static final StringManager sm = StringManager.getManager(Constants.Package);
/**
* Convert a given comma delimited list of regular expressions into an array of compiled {@link Pattern}
@@ -411,6 +428,11 @@
}
/**
+ * @see #setHttpServerPort(int)
+ */
+ private int httpServerPort = 80;
+
+ /**
* @see #setHttpsServerPort(int)
*/
private int httpsServerPort = 443;
@@ -452,6 +474,10 @@
return httpsServerPort;
}
+ public int getHttpServerPort() {
+ return httpServerPort;
+ }
+
/**
* Return descriptive information about this Valve implementation.
*/
@@ -503,7 +529,7 @@
public String getRemoteIpHeader() {
return remoteIpHeader;
}
-
+
/**
* @see #setTrustedProxies(String)
* @return comma delimited list of trusted proxies
@@ -576,12 +602,21 @@
if (protocolHeader != null) {
String protocolHeaderValue = request.getHeader(protocolHeader);
- if (protocolHeaderValue != null && protocolHeaderHttpsValue.equalsIgnoreCase(protocolHeaderValue)) {
+ if (protocolHeaderValue == null) {
+ // don't modify the secure,scheme and serverPort attributes
+ // of the request
+ } else if (protocolHeaderHttpsValue.equalsIgnoreCase(protocolHeaderValue)) {
request.setSecure(true);
// use request.coyoteRequest.scheme instead of request.setScheme() because request.setScheme() is no-op in Tomcat 6.0
request.getCoyoteRequest().scheme().setString("https");
request.setServerPort(httpsServerPort);
+ } else {
+ request.setSecure(false);
+ // use request.coyoteRequest.scheme instead of request.setScheme() because request.setScheme() is no-op in Tomcat 6.0
+ request.getCoyoteRequest().scheme().setString("http");
+
+ request.setServerPort(httpServerPort);
}
}
@@ -609,6 +644,18 @@
/**
* <p>
+ * Server Port value if the {@link #protocolHeader} is not <code>null</code> and does not indicate HTTP
+ * </p>
+ * <p>
+ * Default value : 80
+ * </p>
+ */
+ public void setHttpServerPort(int httpServerPort) {
+ this.httpServerPort = httpServerPort;
+ }
+
+ /**
+ * <p>
* Server Port value if the {@link #protocolHeader} indicates HTTPS
* </p>
* <p>
@@ -687,7 +734,7 @@
* Default value : <code>X-Forwarded-For</code>
* </p>
*
- * @param remoteIPHeader
+ * @param remoteIpHeader
*/
public void setRemoteIpHeader(String remoteIpHeader) {
this.remoteIpHeader = remoteIpHeader;
@@ -695,7 +742,7 @@
/**
* <p>
- * Comma delimited list of proxies that are trusted when they appear in the {@link #remoteIPHeader} header. Can be expressed as a
+ * Comma delimited list of proxies that are trusted when they appear in the {@link #remoteIpHeader} header. Can be expressed as a
* regular expression.
* </p>
* <p>
Modified: trunk/java/org/apache/naming/NamingContext.java
===================================================================
--- trunk/java/org/apache/naming/NamingContext.java 2010-02-02 15:20:12 UTC (rev 1378)
+++ trunk/java/org/apache/naming/NamingContext.java 2010-02-03 15:17:04 UTC (rev 1379)
@@ -516,7 +516,7 @@
throws NamingException {
checkWritable();
- Context newContext = new NamingContext(env, this.name);
+ Context newContext = new NamingContext(env, name.get(name.size() - 1));
bind(name, newContext);
return newContext;
Modified: trunk/webapps/docs/changelog.xml
===================================================================
--- trunk/webapps/docs/changelog.xml 2010-02-02 15:20:12 UTC (rev 1378)
+++ trunk/webapps/docs/changelog.xml 2010-02-03 15:17:04 UTC (rev 1379)
@@ -25,6 +25,10 @@
<fix>
Add LDAP connection timeout in JNDI realm. (markt)
</fix>
+ <fix>
+ <bug>48050</bug>: createSubcontext method returns Context with wrong name. Based on a
+ suggestion by gingyang.xu. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
14 years, 11 months
JBossWeb SVN: r1378 - branches/JBOSSWEB_2_0_0_GA_CP11_JBPAPP-3629/src/share/classes/org/apache/tomcat/util/http.
by jbossweb-commits@lists.jboss.org
Author: mmillson
Date: 2010-02-02 10:20:12 -0500 (Tue, 02 Feb 2010)
New Revision: 1378
Modified:
branches/JBOSSWEB_2_0_0_GA_CP11_JBPAPP-3629/src/share/classes/org/apache/tomcat/util/http/Cookies.java
Log:
Allow equals sign in version0 cookie values for [JBPAPP-3629].
Modified: branches/JBOSSWEB_2_0_0_GA_CP11_JBPAPP-3629/src/share/classes/org/apache/tomcat/util/http/Cookies.java
===================================================================
--- branches/JBOSSWEB_2_0_0_GA_CP11_JBPAPP-3629/src/share/classes/org/apache/tomcat/util/http/Cookies.java 2010-02-02 14:42:08 UTC (rev 1377)
+++ branches/JBOSSWEB_2_0_0_GA_CP11_JBPAPP-3629/src/share/classes/org/apache/tomcat/util/http/Cookies.java 2010-02-02 15:20:12 UTC (rev 1378)
@@ -46,6 +46,12 @@
MimeHeaders headers;
+ /**
+ * If true, cookie values are allowed to contain an equals character without
+ * being quoted.
+ */
+ public static final boolean ALLOW_EQUALS_IN_VALUE;
+
/*
List of Separator Characters (see isSeparator())
Excluding the '/' char violates the RFC, but
@@ -65,6 +71,10 @@
for (int i = 0; i < SEPARATORS.length; i++) {
separators[SEPARATORS[i]] = true;
}
+
+ ALLOW_EQUALS_IN_VALUE = Boolean.valueOf(System.getProperty(
+ "org.apache.tomcat.util.http.ServerCookie.ALLOW_EQUALS_IN_VALUE",
+ "false")).booleanValue();
}
/**
@@ -367,7 +377,7 @@
// Get the cookie name. This must be a token
valueEnd = valueStart = nameStart = pos;
- pos = nameEnd = getTokenEndPosition(bytes,pos,end);
+ pos = nameEnd = getTokenEndPosition(bytes,pos,end,true);
// Skip whitespace
while (pos < end && isWhiteSpace(bytes[pos])) {pos++; };
@@ -414,12 +424,14 @@
// The position is OK (On a delimiter)
break;
default:;
- if (!isSeparator(bytes[pos])) {
+ if (!isSeparator(bytes[pos]) ||
+ bytes[pos] == '=' && ALLOW_EQUALS_IN_VALUE) {
// Token
valueStart=pos;
// getToken returns the position at the delimeter
// or other non-token character
- valueEnd=getTokenEndPosition(bytes, valueStart, end);
+ valueEnd = getTokenEndPosition(bytes, valueStart, end,
+ false);
// We need pos to advance
pos = valueEnd;
} else {
@@ -551,13 +563,26 @@
}
/**
+ * @deprecated - Use private method
+ * {@link #getTokenEndPosition(byte[], int, int, boolean)} instead
+ */
+ public static final int getTokenEndPosition(byte bytes[], int off, int end){
+ return getTokenEndPosition(bytes, off, end, true);
+ }
+
+ /**
* Given the starting position of a token, this gets the end of the
* token, with no separator characters in between.
* JVK
*/
- public static final int getTokenEndPosition(byte bytes[], int off, int end){
+ private static final int getTokenEndPosition(byte bytes[], int off, int end,
+ boolean isName) {
int pos = off;
- while (pos < end && !isSeparator(bytes[pos])) {pos++; };
+ while (pos < end &&
+ (!isSeparator(bytes[pos]) ||
+ bytes[pos]=='=' && ALLOW_EQUALS_IN_VALUE && !isName)) {
+ pos++;
+ }
if (pos > end)
return end;
14 years, 11 months
JBossWeb SVN: r1377 - branches.
by jbossweb-commits@lists.jboss.org
Author: mmillson
Date: 2010-02-02 09:42:08 -0500 (Tue, 02 Feb 2010)
New Revision: 1377
Added:
branches/JBOSSWEB_2_0_0_GA_CP11_JBPAPP-3629/
Log:
Create JBPAPP-3629 patch branch from JBOSSWEB_2_0_0_GA_CP11 tag
Copied: branches/JBOSSWEB_2_0_0_GA_CP11_JBPAPP-3629 (from rev 1376, tags/JBOSSWEB_2_0_0_GA_CP11)
14 years, 11 months
JBossWeb SVN: r1376 - in trunk: java/org/apache/catalina/util and 2 other directories.
by jbossweb-commits@lists.jboss.org
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>
14 years, 11 months