kinman 2003/07/29 16:22:23 Modified: jasper2/src/share/org/apache/jasper JspCompilationContext.java jasper2/src/share/org/apache/jasper/compiler JspUtil.java Log: - Fix bug 21978: Certain tag file pathnames lead to compile errors Patch submitted by [EMAIL PROTECTED] (Eric Carmichael), with my added check for Java keywords in package names. Revision Changes Path 1.41 +20 -78 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/JspCompilationContext.java Index: JspCompilationContext.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/JspCompilationContext.java,v retrieving revision 1.40 retrieving revision 1.41 diff -u -r1.40 -r1.41 --- JspCompilationContext.java 21 May 2003 18:09:33 -0000 1.40 +++ JspCompilationContext.java 29 Jul 2003 23:22:23 -0000 1.41 @@ -61,19 +61,24 @@ package org.apache.jasper; -import java.io.*; -import java.net.*; -import java.util.*; -import java.util.jar.JarFile; +import java.io.File; +import java.io.FileNotFoundException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Hashtable; +import java.util.Set; + import javax.servlet.ServletContext; import javax.servlet.jsp.tagext.TagInfo; -import javax.servlet.jsp.tagext.TagData; -import org.apache.jasper.compiler.JspRuntimeContext; -import org.apache.jasper.compiler.ServletWriter; + import org.apache.jasper.compiler.Compiler; +import org.apache.jasper.compiler.JspRuntimeContext; +import org.apache.jasper.compiler.JspUtil; import org.apache.jasper.compiler.Localizer; -import org.apache.jasper.servlet.JspServletWrapper; +import org.apache.jasper.compiler.ServletWriter; import org.apache.jasper.servlet.JasperLoader; +import org.apache.jasper.servlet.JspServletWrapper; /** * A place holder for various things that are used through out the JSP @@ -128,19 +133,6 @@ private TagInfo tagInfo; private URL tagFileJarUrl; - private static final String javaKeywords[] = { - "abstract", "boolean", "break", "byte", "case", - "catch", "char", "class", "const", "continue", - "default", "do", "double", "else", "extends", - "final", "finally", "float", "for", "goto", - "if", "implements", "import", "instanceof", "int", - "interface", "long", "native", "new", "package", - "private", "protected", "public", "return", "short", - "static", "strictfp", "super", "switch", "synchronized", - "this", "throws", "transient", "try", "void", - "volatile", "while" }; - - // jspURI _must_ be relative to the context public JspCompilationContext(String jspUri, boolean isErrPage, @@ -343,25 +335,8 @@ } } else { int iSep = jspUri.lastIndexOf('/') + 1; - int iEnd = jspUri.length(); - StringBuffer modifiedClassName = - new StringBuffer(jspUri.length() - iSep); - if (!Character.isJavaIdentifierStart(jspUri.charAt(iSep))) { - modifiedClassName.append('_'); - } - for (int i = iSep; i < iEnd; i++) { - char ch = jspUri.charAt(i); - if (Character.isJavaIdentifierPart(ch) && ch != '_') { - modifiedClassName.append(ch); - } else if (ch == '.') { - modifiedClassName.append('_'); - } else { - modifiedClassName.append(mangleChar(ch)); - } - } - className = modifiedClassName.toString(); + className = JspUtil.makeJavaIdentifier(jspUri.substring(iSep)); } - return className; } @@ -436,17 +411,17 @@ if (Character.isJavaIdentifierPart(ch) && ch != '_') { modifiedPackageName.append(ch); } else if (ch == '/') { - if (isJavaKeyword(jspUri.substring(nameStart, i))) { + if (JspUtil.isJavaKeyword(jspUri.substring(nameStart, i))) { modifiedPackageName.append('_'); } nameStart = i+1; modifiedPackageName.append('.'); } else { - modifiedPackageName.append(mangleChar(ch)); + modifiedPackageName.append(JspUtil.mangleChar(ch)); } } if (nameStart < iSep - && isJavaKeyword(jspUri.substring(nameStart, iSep))) { + && JspUtil.isJavaKeyword(jspUri.substring(nameStart, iSep))) { modifiedPackageName.append('_'); } derivedPackageName = modifiedPackageName.toString(); @@ -670,20 +645,6 @@ } // ==================== Private methods ==================== - // Mangling, etc. - - /** - * Mangle the specified character to create a legal Java class name. - */ - private static final String mangleChar(char ch) { - char[] result = new char[5]; - result[0] = '_'; - result[1] = Character.forDigit((ch >> 12) & 0xf, 16); - result[2] = Character.forDigit((ch >> 8) & 0xf, 16); - result[3] = Character.forDigit((ch >> 4) & 0xf, 16); - result[4] = Character.forDigit(ch & 0xf, 16); - return new String(result); - } private static final boolean isPathSeparator(char c) { return (c == '/' || c == '\\'); @@ -747,24 +708,5 @@ } return result.toString(); } - - private static boolean isJavaKeyword(String key) { - int i = 0; - int j = javaKeywords.length; - while (i < j) { - int k = (i+j)/2; - int result = javaKeywords[k].compareTo(key); - if (result == 0) { - return true; - } - if (result < 0) { - i = k+1; - } else { - j = k; - } - } - return false; - } - } 1.39 +124 -33 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/JspUtil.java Index: JspUtil.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/JspUtil.java,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- JspUtil.java 25 Jun 2003 01:01:55 -0000 1.38 +++ JspUtil.java 29 Jul 2003 23:22:23 -0000 1.39 @@ -60,24 +60,24 @@ */ package org.apache.jasper.compiler; -import java.io.*; -import java.util.Enumeration; -import java.util.Hashtable; +import java.io.CharArrayWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; import java.util.Vector; import java.util.jar.JarFile; import java.util.zip.ZipEntry; -import org.apache.jasper.Constants; -import org.apache.jasper.JspCompilationContext; -import org.apache.jasper.JasperException; - -import org.xml.sax.Attributes; - -// EL interpreter (subject to change) -import javax.servlet.jsp.el.FunctionMapper; import javax.servlet.jsp.el.ELException; import javax.servlet.jsp.el.ELParseException; +import javax.servlet.jsp.el.FunctionMapper; + import org.apache.commons.el.ExpressionEvaluatorImpl; +import org.apache.jasper.Constants; +import org.apache.jasper.JasperException; +import org.apache.jasper.JspCompilationContext; +import org.xml.sax.Attributes; /** * This class has all the utility method(s). @@ -105,6 +105,18 @@ private static ExpressionEvaluatorImpl expressionEvaluator = new ExpressionEvaluatorImpl(); + private static final String javaKeywords[] = { + "abstract", "boolean", "break", "byte", "case", + "catch", "char", "class", "const", "continue", + "default", "do", "double", "else", "extends", + "final", "finally", "float", "for", "goto", + "if", "implements", "import", "instanceof", "int", + "interface", "long", "native", "new", "package", + "private", "protected", "public", "return", "short", + "static", "strictfp", "super", "switch", "synchronized", + "this", "throws", "transient", "try", "void", + "volatile", "while" }; + public static char[] removeQuotes(char []chars) { CharArrayWriter caw = new CharArrayWriter(); for (int i = 0; i < chars.length; i++) { @@ -885,23 +897,30 @@ ErrorDispatcher err) throws JasperException { - String className = null; - int begin = 0; - int index; - - // Remove ".tag" suffix - index = path.lastIndexOf(".tag"); - if (index != -1) { - path = path.substring(0, index); - } else { - err.jspError("jsp.error.tagfile.badSuffix", path); - } - - index = path.indexOf(WEB_INF_TAGS); - if (index != -1) { - className = "org.apache.jsp.tag.web."; - begin = index + WEB_INF_TAGS.length(); - } else { + String className = null; + int begin = 0; + int index; + + index = path.lastIndexOf(".tag"); + if (index == -1) { + err.jspError("jsp.error.tagfile.badSuffix", path); + } + + //It's tempting to remove the ".tag" suffix here, but we can't. + //If we remove it, the fully-qualified class name of this tag + //could conflict with the package name of other tags. + //For instance, the tag file + // /WEB-INF/tags/foo.tag + //would have fully-qualified class name + // org.apache.jsp.tag.web.foo + //which would conflict with the package name of the tag file + // /WEB-INF/tags/foo/bar.tag + + index = path.indexOf(WEB_INF_TAGS); + if (index != -1) { + className = "org.apache.jsp.tag.web."; + begin = index + WEB_INF_TAGS.length(); + } else { index = path.indexOf(META_INF_TAGS); if (index != -1) { className = "org.apache.jsp.tag.meta."; @@ -911,9 +930,81 @@ } } - className += path.substring(begin).replace('/', '.'); - + //Make sure the class name consists of legal Java identifiers + String classNameComponents[] = path.substring(begin).split("/"); + StringBuffer legalClassNames = new StringBuffer(); + for (int i = 0; i < classNameComponents.length; i++) { + legalClassNames.append(makeJavaIdentifier(classNameComponents[i])); + if (isJavaKeyword(classNameComponents[i])) { + legalClassNames.append('_'); + } + if (i < classNameComponents.length - 1) { + legalClassNames.append('.'); + } + } + className += legalClassNames.toString(); + return className; + } + + /** + * Converts the given identifier to a legal Java identifier + * + * @param identifier Identifier to convert + * + * @return Legal Java identifier corresponding to the given identifier + */ + public static final String makeJavaIdentifier(String identifier) { + StringBuffer modifiedIdentifier = + new StringBuffer(identifier.length()); + if (!Character.isJavaIdentifierStart(identifier.charAt(0))) { + modifiedIdentifier.append('_'); + } + for (int i = 0; i < identifier.length(); i++) { + char ch = identifier.charAt(i); + if (Character.isJavaIdentifierPart(ch) && ch != '_') { + modifiedIdentifier.append(ch); + } else if (ch == '.') { + modifiedIdentifier.append('_'); + } else { + modifiedIdentifier.append(mangleChar(ch)); + } + } + return modifiedIdentifier.toString(); + } + + /** + * Mangle the specified character to create a legal Java class name. + */ + public static final String mangleChar(char ch) { + char[] result = new char[5]; + result[0] = '_'; + result[1] = Character.forDigit((ch >> 12) & 0xf, 16); + result[2] = Character.forDigit((ch >> 8) & 0xf, 16); + result[3] = Character.forDigit((ch >> 4) & 0xf, 16); + result[4] = Character.forDigit(ch & 0xf, 16); + return new String(result); + } + + /** + * Test whether the argument is a Java keyword + */ + public static boolean isJavaKeyword(String key) { + int i = 0; + int j = javaKeywords.length; + while (i < j) { + int k = (i+j)/2; + int result = javaKeywords[k].compareTo(key); + if (result == 0) { + return true; + } + if (result < 0) { + i = k+1; + } else { + j = k; + } + } + return false; } static InputStreamReader getReader(String fname, String encoding,
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]