Author: markt
Date: Fri Aug 12 08:13:09 2011
New Revision: 1157000

URL: http://svn.apache.org/viewvc?rev=1157000&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=36362
Handle tag files with attribute names that are not valid Java identifiers

Modified:
    tomcat/tc5.5.x/trunk/STATUS.txt
    
tomcat/tc5.5.x/trunk/container/modules/cluster/src/share/org/apache/catalina/cluster/session/ReplicationStream.java
    
tomcat/tc5.5.x/trunk/container/modules/groupcom/src/share/org/apache/catalina/tribes/io/ReplicationStream.java
    tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml
    
tomcat/tc5.5.x/trunk/jasper/src/share/org/apache/jasper/compiler/Generator.java
    
tomcat/tc5.5.x/trunk/jasper/src/share/org/apache/jasper/compiler/JspUtil.java

Modified: tomcat/tc5.5.x/trunk/STATUS.txt
URL: 
http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/STATUS.txt?rev=1157000&r1=1156999&r2=1157000&view=diff
==============================================================================
--- tomcat/tc5.5.x/trunk/STATUS.txt (original)
+++ tomcat/tc5.5.x/trunk/STATUS.txt Fri Aug 12 08:13:09 2011
@@ -77,15 +77,6 @@ PATCHES PROPOSED TO BACKPORT:
   +1: markt
   -1: 
   
-* Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=36362
-  Handle tag files with attribute names that are not valid Java identifiers
-  http://svn.apache.org/viewvc?rev=1138950&view=rev
-  http://svn.apache.org/viewvc?rev=1138953&view=rev
-  http://svn.apache.org/viewvc?rev=1140693&view=rev
-  http://svn.apache.org/viewvc?rev=1142043&view=rev
-  +1: markt, kkolinko, kfujino
-  -1:
-
 * Multiple improvements to the Windows Installer
   - https://issues.apache.org/bugzilla/show_bug.cgi?id=33262
     Install monitor to auto-start for current user only rather than all users 
to

Modified: 
tomcat/tc5.5.x/trunk/container/modules/cluster/src/share/org/apache/catalina/cluster/session/ReplicationStream.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/container/modules/cluster/src/share/org/apache/catalina/cluster/session/ReplicationStream.java?rev=1157000&r1=1156999&r2=1157000&view=diff
==============================================================================
--- 
tomcat/tc5.5.x/trunk/container/modules/cluster/src/share/org/apache/catalina/cluster/session/ReplicationStream.java
 (original)
+++ 
tomcat/tc5.5.x/trunk/container/modules/cluster/src/share/org/apache/catalina/cluster/session/ReplicationStream.java
 Fri Aug 12 08:13:09 2011
@@ -22,6 +22,8 @@ import java.io.InputStream;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamClass;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
 
 /**
  * Custom subclass of <code>ObjectInputStream</code> that loads from the
@@ -86,6 +88,43 @@ public final class ReplicationStream ext
         }
     }
     
+    /**
+     * ObjectInputStream.resolveProxyClass has some funky way of using 
+     * the incorrect class loader to resolve proxy classes, let's do it our 
way instead
+     */
+    protected Class resolveProxyClass(String[] interfaces)
+        throws IOException, ClassNotFoundException {
+        
+        ClassLoader latestLoader = classLoader;
+        ClassLoader nonPublicLoader = null;
+        boolean hasNonPublicInterface = false;
+
+        // define proxy in class loader of non-public interface(s), if any
+        Class[] classObjs = new Class[interfaces.length];
+        for (int i = 0; i < interfaces.length; i++) {
+            Class cl = this.findWebappClass(interfaces[i]);
+            if (latestLoader == null) latestLoader = cl.getClassLoader();
+            if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
+                if (hasNonPublicInterface) {
+                    if (nonPublicLoader != cl.getClassLoader()) {
+                        throw new IllegalAccessError(
+                            "conflicting non-public interface class loaders");
+                    }
+                } else {
+                    nonPublicLoader = cl.getClassLoader();
+                    hasNonPublicInterface = true;
+                }
+            }
+            classObjs[i] = cl;
+        }
+        try {
+            return Proxy.getProxyClass(hasNonPublicInterface ? nonPublicLoader
+                    : latestLoader, classObjs);
+        } catch (IllegalArgumentException e) {
+            throw new ClassNotFoundException(null, e);
+        }
+    }
+
     public Class findReplicationClass(String name)
         throws ClassNotFoundException, IOException {
         return Class.forName(name, false, getClass().getClassLoader());

Modified: 
tomcat/tc5.5.x/trunk/container/modules/groupcom/src/share/org/apache/catalina/tribes/io/ReplicationStream.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/container/modules/groupcom/src/share/org/apache/catalina/tribes/io/ReplicationStream.java?rev=1157000&r1=1156999&r2=1157000&view=diff
==============================================================================
--- 
tomcat/tc5.5.x/trunk/container/modules/groupcom/src/share/org/apache/catalina/tribes/io/ReplicationStream.java
 (original)
+++ 
tomcat/tc5.5.x/trunk/container/modules/groupcom/src/share/org/apache/catalina/tribes/io/ReplicationStream.java
 Fri Aug 12 08:13:09 2011
@@ -22,6 +22,8 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamClass;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
 
 /**
  * Custom subclass of <code>ObjectInputStream</code> that loads from the
@@ -71,23 +73,68 @@ public final class ReplicationStream ext
     public Class resolveClass(ObjectStreamClass classDesc)
         throws ClassNotFoundException, IOException {
         String name = classDesc.getName();
-        boolean tryRepFirst = name.startsWith("org.apache.catalina.tribes");
         try {
-            try
-            {
-                if ( tryRepFirst ) return findReplicationClass(name);
-                else return findExternalClass(name);
-            }
-            catch ( Exception x )
-            {
-                if ( tryRepFirst ) return findExternalClass(name);
-                else return findReplicationClass(name);
-            }
+            return resolveClass(name);
         } catch (ClassNotFoundException e) {
             return super.resolveClass(classDesc);
         }
     }
     
+    public Class resolveClass(String name)
+        throws ClassNotFoundException, IOException {
+    
+        boolean tryRepFirst = name.startsWith("org.apache.catalina.tribes");
+            try {
+            if (tryRepFirst)
+                return findReplicationClass(name);
+            else
+                return findExternalClass(name);
+        } catch (Exception x) {
+            if (tryRepFirst)
+                return findExternalClass(name);
+            else
+                return findReplicationClass(name);
+        }
+    }
+
+    /**
+     * ObjectInputStream.resolveProxyClass has some funky way of using 
+     * the incorrect class loader to resolve proxy classes, let's do it our 
way instead
+     */
+    protected Class resolveProxyClass(String[] interfaces)
+            throws IOException, ClassNotFoundException {
+        
+        ClassLoader latestLoader = (classLoaders!=null && 
classLoaders.length==0)?null:classLoaders[0];
+        ClassLoader nonPublicLoader = null;
+        boolean hasNonPublicInterface = false;
+
+        // define proxy in class loader of non-public interface(s), if any
+        Class[] classObjs = new Class[interfaces.length];
+        for (int i = 0; i < interfaces.length; i++) {
+            Class cl = this.resolveClass(interfaces[i]);
+            if (latestLoader==null) latestLoader = cl.getClassLoader();
+            if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
+                if (hasNonPublicInterface) {
+                    if (nonPublicLoader != cl.getClassLoader()) {
+                        throw new IllegalAccessError(
+                                "conflicting non-public interface class 
loaders");
+                    }
+                } else {
+                    nonPublicLoader = cl.getClassLoader();
+                    hasNonPublicInterface = true;
+                }
+            }
+            classObjs[i] = cl;
+        }
+        try {
+            return Proxy.getProxyClass(hasNonPublicInterface ? nonPublicLoader
+                    : latestLoader, classObjs);
+        } catch (IllegalArgumentException e) {
+            throw new ClassNotFoundException(null, e);
+        }
+    }
+
+    
     public Class findReplicationClass(String name)
         throws ClassNotFoundException, IOException {
         Class clazz = Class.forName(name, false, getClass().getClassLoader());

Modified: tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml?rev=1157000&r1=1156999&r2=1157000&view=diff
==============================================================================
--- tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml (original)
+++ tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml Fri Aug 12 
08:13:09 2011
@@ -66,6 +66,15 @@
       </fix>
     </changelog>
   </subsection>
+  <subsection name="Jasper">
+    <changelog>
+      <fix>
+        <bug>36362</bug>: Handle the case where tag file attributes (which can
+        use any valid XML name) have a name which is not a Java identifier.
+        (markt)
+      </fix>
+    </changelog>
+  </subsection>
   <subsection name="Webapps">
     <changelog>
       <fix>

Modified: 
tomcat/tc5.5.x/trunk/jasper/src/share/org/apache/jasper/compiler/Generator.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/jasper/src/share/org/apache/jasper/compiler/Generator.java?rev=1157000&r1=1156999&r2=1157000&view=diff
==============================================================================
--- 
tomcat/tc5.5.x/trunk/jasper/src/share/org/apache/jasper/compiler/Generator.java 
(original)
+++ 
tomcat/tc5.5.x/trunk/jasper/src/share/org/apache/jasper/compiler/Generator.java 
Fri Aug 12 08:13:09 2011
@@ -3558,54 +3558,56 @@ class Generator {
                 
out.print(JspUtil.toJavaSourceType(attrInfos[i].getTypeName()));
                 out.print(" ");
             }
-            out.print(attrInfos[i].getName());
+            out.print(JspUtil.makeJavaIdentifierForAttribute(
+                    attrInfos[i].getName()));
             out.println(";");
         }
         out.println();
 
         // Define attribute getter and setter methods
-        if (attrInfos != null) {
-            for (int i = 0; i < attrInfos.length; i++) {
-                // getter method
-                out.printin("public ");
-                if (attrInfos[i].isFragment()) {
-                    out.print("javax.servlet.jsp.tagext.JspFragment ");
-                } else {
-                    
out.print(JspUtil.toJavaSourceType(attrInfos[i].getTypeName()));
-                    out.print(" ");
-                }
-                out.print(toGetterMethod(attrInfos[i].getName()));
-                out.println(" {");
-                out.pushIndent();
-                out.printin("return this.");
-                out.print(attrInfos[i].getName());
-                out.println(";");
-                out.popIndent();
-                out.printil("}");
-                out.println();
+        for (int i = 0; i < attrInfos.length; i++) {
+            String javaName =
+                JspUtil.makeJavaIdentifierForAttribute(attrInfos[i].getName());
 
-                // setter method
-                out.printin("public void ");
-                out.print(toSetterMethodName(attrInfos[i].getName()));
-                if (attrInfos[i].isFragment()) {
-                    out.print("(javax.servlet.jsp.tagext.JspFragment ");
-                } else {
-                    out.print("(");
-                    
out.print(JspUtil.toJavaSourceType(attrInfos[i].getTypeName()));
-                    out.print(" ");
-                }
-                out.print(attrInfos[i].getName());
-                out.println(") {");
-                out.pushIndent();
-                out.printin("this.");
-                out.print(attrInfos[i].getName());
-                out.print(" = ");
-                out.print(attrInfos[i].getName());
-                out.println(";");
-                out.popIndent();
-                out.printil("}");
-                out.println();
+            // getter method
+            out.printin("public ");
+            if (attrInfos[i].isFragment()) {
+                out.print("javax.servlet.jsp.tagext.JspFragment ");
+            } else {
+                
out.print(JspUtil.toJavaSourceType(attrInfos[i].getTypeName()));
+                out.print(" ");
             }
+            out.print(toGetterMethod(attrInfos[i].getName()));
+            out.println(" {");
+            out.pushIndent();
+            out.printin("return this.");
+            out.print(javaName);
+            out.println(";");
+            out.popIndent();
+            out.printil("}");
+            out.println();
+
+            // setter method
+            out.printin("public void ");
+            out.print(toSetterMethodName(attrInfos[i].getName()));
+            if (attrInfos[i].isFragment()) {
+                out.print("(javax.servlet.jsp.tagext.JspFragment ");
+            } else {
+                out.print("(");
+                
out.print(JspUtil.toJavaSourceType(attrInfos[i].getTypeName()));
+                out.print(" ");
+            }
+            out.print(javaName);
+            out.println(") {");
+            out.pushIndent();
+            out.printin("this.");
+            out.print(javaName);
+            out.print(" = ");
+            out.print(javaName);
+            out.println(";");
+            out.popIndent();
+            out.printil("}");
+            out.println();
         }
     }
 

Modified: 
tomcat/tc5.5.x/trunk/jasper/src/share/org/apache/jasper/compiler/JspUtil.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/jasper/src/share/org/apache/jasper/compiler/JspUtil.java?rev=1157000&r1=1156999&r2=1157000&view=diff
==============================================================================
--- 
tomcat/tc5.5.x/trunk/jasper/src/share/org/apache/jasper/compiler/JspUtil.java 
(original)
+++ 
tomcat/tc5.5.x/trunk/jasper/src/share/org/apache/jasper/compiler/JspUtil.java 
Fri Aug 12 08:13:09 2011
@@ -979,6 +979,32 @@ public class JspUtil {
      * @return Legal Java identifier corresponding to the given identifier
      */
     public static final String makeJavaIdentifier(String identifier) {
+        return makeJavaIdentifier(identifier, true);
+    }
+
+    /**
+     * Converts the given identifier to a legal Java identifier
+     * to be used for JSP Tag file attribute names. 
+     * 
+     * @param identifier
+     *            Identifier to convert
+     * 
+     * @return Legal Java identifier corresponding to the given identifier
+     */
+    public static final String makeJavaIdentifierForAttribute(String 
identifier) {
+        return makeJavaIdentifier(identifier, false);
+    }
+
+    /**
+     * Converts the given identifier to a legal Java identifier.
+     * 
+     * @param identifier
+     *            Identifier to convert
+     * 
+     * @return Legal Java identifier corresponding to the given identifier
+     */
+    private static final String makeJavaIdentifier(String identifier,
+            boolean periodToUnderscore) {
         StringBuffer modifiedIdentifier = 
             new StringBuffer(identifier.length());
         if (!Character.isJavaIdentifierStart(identifier.charAt(0))) {
@@ -986,9 +1012,10 @@ public class JspUtil {
         }
         for (int i = 0; i < identifier.length(); i++) {
             char ch = identifier.charAt(i);
-            if (Character.isJavaIdentifierPart(ch) && ch != '_') {
+            if (Character.isJavaIdentifierPart(ch) &&
+                    (ch != '_' || !periodToUnderscore)) {
                 modifiedIdentifier.append(ch);
-            } else if (ch == '.') {
+            } else if (ch == '.' && periodToUnderscore) {
                 modifiedIdentifier.append('_');
             } else {
                 modifiedIdentifier.append(mangleChar(ch));



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to