From fc04495aa2bf8bbb7880da6c4cbd62445b864b7e Mon Sep 17 00:00:00 2001 From: markt Date: Sat, 16 Jun 2007 15:39:21 +0000 Subject: [PATCH] Port fix bug 42643. Prevent creation of duplicate function mapper variables. Fix various compiler warnings. git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@547932 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/jasper/compiler/ELFunctionMapper.java | 382 ++++++++++----------- webapps/docs/changelog.xml | 12 + 2 files changed, 202 insertions(+), 192 deletions(-) diff --git a/java/org/apache/jasper/compiler/ELFunctionMapper.java b/java/org/apache/jasper/compiler/ELFunctionMapper.java index 6c57efc43..f2df33dc0 100644 --- a/java/org/apache/jasper/compiler/ELFunctionMapper.java +++ b/java/org/apache/jasper/compiler/ELFunctionMapper.java @@ -31,8 +31,7 @@ import org.apache.jasper.JasperException; */ public class ELFunctionMapper { - static private int currFunc = 0; - private ErrorDispatcher err; + private int currFunc = 0; StringBuffer ds; // Contains codes to initialize the functions mappers. StringBuffer ss; // Contains declarations of the functions mappers. @@ -43,23 +42,21 @@ public class ELFunctionMapper { * @param page The current compilation unit. */ public static void map(Compiler compiler, Node.Nodes page) - throws JasperException { - - currFunc = 0; - ELFunctionMapper map = new ELFunctionMapper(); - map.err = compiler.getErrorDispatcher(); - map.ds = new StringBuffer(); - map.ss = new StringBuffer(); - - page.visit(map.new ELFunctionVisitor()); - - // Append the declarations to the root node - String ds = map.ds.toString(); - if (ds.length() > 0) { - Node root = page.getRoot(); - new Node.Declaration(map.ss.toString(), null, root); - new Node.Declaration("static {\n" + ds + "}\n", null, root); - } + throws JasperException { + + ELFunctionMapper map = new ELFunctionMapper(); + map.ds = new StringBuffer(); + map.ss = new StringBuffer(); + + page.visit(map.new ELFunctionVisitor()); + + // Append the declarations to the root node + String ds = map.ds.toString(); + if (ds.length() > 0) { + Node root = page.getRoot(); + new Node.Declaration(map.ss.toString(), null, root); + new Node.Declaration("static {\n" + ds + "}\n", null, root); + } } /** @@ -67,182 +64,183 @@ public class ELFunctionMapper { * for functions, and if found functions mappers are created. */ class ELFunctionVisitor extends Node.Visitor { - - /** - * Use a global name map to facilitate reuse of function maps. - * The key used is prefix:function:uri. - */ - private HashMap gMap = new HashMap(); - - public void visit(Node.ParamAction n) throws JasperException { - doMap(n.getValue()); - visitBody(n); - } - - public void visit(Node.IncludeAction n) throws JasperException { - doMap(n.getPage()); - visitBody(n); - } - - public void visit(Node.ForwardAction n) throws JasperException { - doMap(n.getPage()); - visitBody(n); - } + + /** + * Use a global name map to facilitate reuse of function maps. + * The key used is prefix:function:uri. + */ + private HashMap gMap = new HashMap(); + + public void visit(Node.ParamAction n) throws JasperException { + doMap(n.getValue()); + visitBody(n); + } + + public void visit(Node.IncludeAction n) throws JasperException { + doMap(n.getPage()); + visitBody(n); + } + + public void visit(Node.ForwardAction n) throws JasperException { + doMap(n.getPage()); + visitBody(n); + } public void visit(Node.SetProperty n) throws JasperException { - doMap(n.getValue()); - visitBody(n); - } + doMap(n.getValue()); + visitBody(n); + } public void visit(Node.UseBean n) throws JasperException { - doMap(n.getBeanName()); - visitBody(n); - } + doMap(n.getBeanName()); + visitBody(n); + } public void visit(Node.PlugIn n) throws JasperException { - doMap(n.getHeight()); - doMap(n.getWidth()); - visitBody(n); - } + doMap(n.getHeight()); + doMap(n.getWidth()); + visitBody(n); + } public void visit(Node.JspElement n) throws JasperException { - Node.JspAttribute[] attrs = n.getJspAttributes(); - for (int i = 0; attrs != null && i < attrs.length; i++) { - doMap(attrs[i]); - } - doMap(n.getNameAttribute()); - visitBody(n); - } + Node.JspAttribute[] attrs = n.getJspAttributes(); + for (int i = 0; attrs != null && i < attrs.length; i++) { + doMap(attrs[i]); + } + doMap(n.getNameAttribute()); + visitBody(n); + } public void visit(Node.UninterpretedTag n) throws JasperException { - Node.JspAttribute[] attrs = n.getJspAttributes(); - for (int i = 0; attrs != null && i < attrs.length; i++) { - doMap(attrs[i]); - } - visitBody(n); - } + Node.JspAttribute[] attrs = n.getJspAttributes(); + for (int i = 0; attrs != null && i < attrs.length; i++) { + doMap(attrs[i]); + } + visitBody(n); + } public void visit(Node.CustomTag n) throws JasperException { - Node.JspAttribute[] attrs = n.getJspAttributes(); - for (int i = 0; attrs != null && i < attrs.length; i++) { - doMap(attrs[i]); - } - visitBody(n); - } + Node.JspAttribute[] attrs = n.getJspAttributes(); + for (int i = 0; attrs != null && i < attrs.length; i++) { + doMap(attrs[i]); + } + visitBody(n); + } public void visit(Node.ELExpression n) throws JasperException { - doMap(n.getEL()); - } + doMap(n.getEL()); + } - private void doMap(Node.JspAttribute attr) - throws JasperException { - if (attr != null) { - doMap(attr.getEL()); - } - } + private void doMap(Node.JspAttribute attr) + throws JasperException { + if (attr != null) { + doMap(attr.getEL()); + } + } /** * Creates function mappers, if needed, from ELNodes */ - private void doMap(ELNode.Nodes el) - throws JasperException { + private void doMap(ELNode.Nodes el) + throws JasperException { // Only care about functions in ELNode's - class Fvisitor extends ELNode.Visitor { - ArrayList funcs = new ArrayList(); - HashMap keyMap = new HashMap(); - public void visit(ELNode.Function n) throws JasperException { - String key = n.getPrefix() + ":" + n.getName(); - if (! keyMap.containsKey(key)) { - keyMap.put(key,""); - funcs.add(n); - } - } - } - - if (el == null) { - return; - } - - // First locate all unique functions in this EL - Fvisitor fv = new Fvisitor(); - el.visit(fv); - ArrayList functions = fv.funcs; - - if (functions.size() == 0) { - return; - } - - // Reuse a previous map if possible - String decName = matchMap(functions); - if (decName != null) { - el.setMapName(decName); - return; - } - - // Generate declaration for the map statically - decName = getMapName(); - ss.append("static private org.apache.jasper.runtime.ProtectedFunctionMapper " + decName + ";\n"); - - ds.append(" " + decName + "= "); - ds.append("org.apache.jasper.runtime.ProtectedFunctionMapper"); - - // Special case if there is only one function in the map - String funcMethod = null; - if (functions.size() == 1) { - funcMethod = ".getMapForFunction"; - } else { - ds.append(".getInstance();\n"); - funcMethod = " " + decName + ".mapFunction"; - } + class Fvisitor extends ELNode.Visitor { + ArrayList funcs = + new ArrayList(); + HashMap keyMap = new HashMap(); + public void visit(ELNode.Function n) throws JasperException { + String key = n.getPrefix() + ":" + n.getName(); + if (! keyMap.containsKey(key)) { + keyMap.put(key,""); + funcs.add(n); + } + } + } + + if (el == null) { + return; + } + + // First locate all unique functions in this EL + Fvisitor fv = new Fvisitor(); + el.visit(fv); + ArrayList functions = fv.funcs; + + if (functions.size() == 0) { + return; + } + + // Reuse a previous map if possible + String decName = matchMap(functions); + if (decName != null) { + el.setMapName(decName); + return; + } + + // Generate declaration for the map statically + decName = getMapName(); + ss.append("static private org.apache.jasper.runtime.ProtectedFunctionMapper " + decName + ";\n"); + + ds.append(" " + decName + "= "); + ds.append("org.apache.jasper.runtime.ProtectedFunctionMapper"); + + // Special case if there is only one function in the map + String funcMethod = null; + if (functions.size() == 1) { + funcMethod = ".getMapForFunction"; + } else { + ds.append(".getInstance();\n"); + funcMethod = " " + decName + ".mapFunction"; + } // Setup arguments for either getMapForFunction or mapFunction - for (int i = 0; i < functions.size(); i++) { - ELNode.Function f = (ELNode.Function)functions.get(i); - FunctionInfo funcInfo = f.getFunctionInfo(); - String key = f.getPrefix()+ ":" + f.getName(); - ds.append(funcMethod + "(\"" + key + "\", " + - funcInfo.getFunctionClass() + ".class, " + - '\"' + f.getMethodName() + "\", " + - "new Class[] {"); - String params[] = f.getParameters(); - for (int k = 0; k < params.length; k++) { - if (k != 0) { - ds.append(", "); - } - int iArray = params[k].indexOf('['); - if (iArray < 0) { - ds.append(params[k] + ".class"); - } - else { - String baseType = params[k].substring(0, iArray); - ds.append("java.lang.reflect.Array.newInstance("); - ds.append(baseType); - ds.append(".class,"); - - // Count the number of array dimension - int aCount = 0; - for (int jj = iArray; jj < params[k].length(); jj++ ) { - if (params[k].charAt(jj) == '[') { - aCount++; - } - } - if (aCount == 1) { - ds.append("0).getClass()"); - } else { - ds.append("new int[" + aCount + "]).getClass()"); - } - } - } - ds.append("});\n"); - // Put the current name in the global function map - gMap.put(f.getPrefix() + ':' + f.getName() + ':' + f.getUri(), - decName); - } - el.setMapName(decName); - } + for (int i = 0; i < functions.size(); i++) { + ELNode.Function f = (ELNode.Function)functions.get(i); + FunctionInfo funcInfo = f.getFunctionInfo(); + String key = f.getPrefix()+ ":" + f.getName(); + ds.append(funcMethod + "(\"" + key + "\", " + + funcInfo.getFunctionClass() + ".class, " + + '\"' + f.getMethodName() + "\", " + + "new Class[] {"); + String params[] = f.getParameters(); + for (int k = 0; k < params.length; k++) { + if (k != 0) { + ds.append(", "); + } + int iArray = params[k].indexOf('['); + if (iArray < 0) { + ds.append(params[k] + ".class"); + } + else { + String baseType = params[k].substring(0, iArray); + ds.append("java.lang.reflect.Array.newInstance("); + ds.append(baseType); + ds.append(".class,"); + + // Count the number of array dimension + int aCount = 0; + for (int jj = iArray; jj < params[k].length(); jj++ ) { + if (params[k].charAt(jj) == '[') { + aCount++; + } + } + if (aCount == 1) { + ds.append("0).getClass()"); + } else { + ds.append("new int[" + aCount + "]).getClass()"); + } + } + } + ds.append("});\n"); + // Put the current name in the global function map + gMap.put(f.getPrefix() + ':' + f.getName() + ':' + f.getUri(), + decName); + } + el.setMapName(decName); + } /** * Find the name of the function mapper for an EL. Reuse a @@ -252,32 +250,32 @@ public class ELFunctionMapper { * @return A previous generated function mapper name that can be used * by this EL; null if none found. */ - private String matchMap(ArrayList functions) { - - String mapName = null; - for (int i = 0; i < functions.size(); i++) { - ELNode.Function f = (ELNode.Function)functions.get(i); - String temName = (String) gMap.get(f.getPrefix() + ':' + - f.getName() + ':' + f.getUri()); - if (temName == null) { - return null; - } - if (mapName == null) { - mapName = temName; - } else if (!temName.equals(mapName)) { - // If not all in the previous match, then no match. - return null; - } - } - return mapName; - } + private String matchMap(ArrayList functions) { + + String mapName = null; + for (int i = 0; i < functions.size(); i++) { + ELNode.Function f = (ELNode.Function)functions.get(i); + String temName = (String) gMap.get(f.getPrefix() + ':' + + f.getName() + ':' + f.getUri()); + if (temName == null) { + return null; + } + if (mapName == null) { + mapName = temName; + } else if (!temName.equals(mapName)) { + // If not all in the previous match, then no match. + return null; + } + } + return mapName; + } /* * @return An unique name for a function mapper. */ - private String getMapName() { - return "_jspx_fnmap_" + currFunc++; - } + private String getMapName() { + return "_jspx_fnmap_" + currFunc++; + } } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 74fffdf84..997977d90 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -47,6 +47,10 @@ 42497: Ensure ETag header is present in a 304 response. Patch provided by Len Popp. (markt) + + Fix XSS security vulnerability (CVE-2007-2450) in the Manager and Host + Manager. Reported by Daiki Fukumori. (markt) + @@ -60,6 +64,10 @@ jsp:attribute was used in conjunction with custom tags. Patch provided by Brian Lenz. (markt) + + 42643 Prevent creation of duplicate JSP function mapper + variables. (markt) + @@ -67,6 +75,10 @@ 42459: Tomcat Web Application Manager table error (rjung) + + Fix XSS security vulnerabilities (CVE-2007-2449) in the examples. + Reported by Toshiharu Sugiyama. (markt) + -- 2.11.0