From 17f21c8eee2633c3759ad2051e9f8940b898b644 Mon Sep 17 00:00:00 2001 From: Arjan Tijms Date: Tue, 20 Aug 2024 18:17:47 +0200 Subject: [PATCH] Remove security manager support and other deprecated items. Addressed some compile warnings, yet many still remain. Signed-off-by: Arjan Tijms --- pom.xml | 2 +- .../java/org/glassfish/wasp/Constants.java | 7 +- src/main/java/org/glassfish/wasp/JspC.java | 23 +-- .../glassfish/wasp/JspCompilationContext.java | 13 +- .../wasp/compiler/JspDocumentParser.java | 40 +--- .../wasp/compiler/JspRuntimeContext.java | 137 +------------- .../wasp/compiler/TagLibraryInfoImpl.java | 75 ++++---- .../wasp/compiler/TagPluginManager.java | 15 +- .../org/glassfish/wasp/runtime/Classpath.java | 72 +++---- .../wasp/runtime/JspFactoryImpl.java | 23 +-- .../wasp/runtime/JspRuntimeLibrary.java | 56 +++--- .../glassfish/wasp/runtime/JspWriterImpl.java | 16 +- .../wasp/runtime/PageContextImpl.java | 175 ++++-------------- .../wasp/runtime/ProtectedFunctionMapper.java | 61 ++---- .../wasp/runtime/TagHandlerPool.java | 15 +- .../wasp/security/SecurityClassLoad.java | 65 ------- .../glassfish/wasp/security/SecurityUtil.java | 42 ----- .../wasp/servlet/JspServletWrapper.java | 38 ++-- .../glassfish/wasp/servlet/WaspLoader.java | 67 +------ .../standard/lang/jstl/ArraySuffix.java | 7 +- .../standard/lang/jstl/BeanInfoManager.java | 23 +-- .../lang/jstl/BinaryOperatorExpression.java | 4 +- .../taglibs/standard/lang/jstl/Coercions.java | 29 +-- .../standard/lang/jstl/ComplexValue.java | 4 +- .../standard/lang/jstl/ELEvaluator.java | 48 ++--- .../taglibs/standard/lang/jstl/Evaluator.java | 8 +- .../standard/lang/jstl/Expression.java | 4 +- .../standard/lang/jstl/ExpressionString.java | 8 +- .../lang/jstl/FloatingPointLiteral.java | 3 +- .../lang/jstl/FunctionInvocation.java | 7 +- .../taglibs/standard/lang/jstl/Literal.java | 4 +- .../standard/lang/jstl/NamedValue.java | 9 +- .../standard/lang/jstl/PropertySuffix.java | 4 +- .../lang/jstl/UnaryOperatorExpression.java | 5 +- .../standard/lang/jstl/ValueSuffix.java | 4 +- .../lang/support/ExpressionEvaluator.java | 6 +- .../support/ExpressionEvaluatorManager.java | 17 +- .../tag/common/core/ForEachSupport.java | 45 ++--- .../standard/tag/common/core/SetSupport.java | 29 +-- .../tag/common/fmt/FormatNumberSupport.java | 44 +---- .../tag/common/sql/DataSourceWrapper.java | 12 +- .../standard/tag/common/xml/ParseSupport.java | 3 +- .../glassfish/wasp/xmlparser/ParserUtils.java | 74 +++----- 43 files changed, 437 insertions(+), 906 deletions(-) delete mode 100644 src/main/java/org/glassfish/wasp/security/SecurityClassLoad.java delete mode 100644 src/main/java/org/glassfish/wasp/security/SecurityUtil.java diff --git a/pom.xml b/pom.xml index 89328eb..eb3c378 100644 --- a/pom.xml +++ b/pom.xml @@ -166,7 +166,7 @@ 3.13.0 17 - -Xlint:unchecked + -Xlint:all diff --git a/src/main/java/org/glassfish/wasp/Constants.java b/src/main/java/org/glassfish/wasp/Constants.java index 7281c3b..19af875 100644 --- a/src/main/java/org/glassfish/wasp/Constants.java +++ b/src/main/java/org/glassfish/wasp/Constants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2022 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -187,11 +187,6 @@ public class Constants { // other modules, and therefore requires special caution whenever it is changed. public static final String JSP_ERROR_HANDLED = "org.glassfish.jsp.error_handled"; - /** - * Has security been turned on? - */ - public static final boolean IS_SECURITY_ENABLED = System.getSecurityManager() != null; - /** * The name of the JSP engine. Used for X-Powered-By identification in the response header */ diff --git a/src/main/java/org/glassfish/wasp/JspC.java b/src/main/java/org/glassfish/wasp/JspC.java index 47f086f..198e7ae 100644 --- a/src/main/java/org/glassfish/wasp/JspC.java +++ b/src/main/java/org/glassfish/wasp/JspC.java @@ -1,8 +1,7 @@ /* - * Copyright (c) 2022, 2022 Contributors to the Eclipse Foundation + * Copyright (c) 2021, 2024 Contributors to the Eclipse Foundation * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation - * Copyright (c) 2021 Contributors to the Eclipse Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +18,9 @@ package org.glassfish.wasp; +// START GlassFish 750 +import jakarta.servlet.jsp.tagext.TagLibraryInfo; + import java.io.BufferedReader; import java.io.CharArrayWriter; import java.io.File; @@ -59,9 +61,6 @@ import org.glassfish.wasp.servlet.JspCServletContext; import org.glassfish.wasp.xmlparser.ParserUtils; -// START GlassFish 750 -import jakarta.servlet.jsp.tagext.TagLibraryInfo; - /** * Shell for the jspc compiler. Handles all options associated with the command line and creates compilation contexts @@ -217,8 +216,6 @@ public class JspC implements Options { private HashMap jspErrors = new HashMap<>(); - private static String myJavaVersion = System.getProperty("java.specification.version"); - private boolean ignoreJspFragmentErrors = false; private Set dependents = new HashSet<>(); @@ -550,7 +547,7 @@ public File getScratchDir() { return scratchDir; } - public Class getJspCompilerPlugin() { + public Class getJspCompilerPlugin() { // we don't compile, so this is meaningless return null; } @@ -1388,7 +1385,7 @@ private void initClassLoader(JspCompilationContext clctxt) throws IOException { String path = tokenizer.nextToken(); try { File libFile = new File(path); - urls.add(libFile.toURL()); + urls.add(libFile.toURI().toURL()); } catch (IOException ioe) { // Failing a toCanonicalPath on a file that // exists() should be a JVM regression test, @@ -1403,7 +1400,7 @@ private void initClassLoader(JspCompilationContext clctxt) throws IOException { try { if (classes.exists()) { classPath = classPath + File.pathSeparator + classes.getCanonicalPath(); - urls.add(classes.getCanonicalFile().toURL()); + urls.add(classes.getCanonicalFile().toURI().toURL()); } } catch (IOException ioe) { // failing a toCanonicalPath on a file that @@ -1428,7 +1425,7 @@ private void initClassLoader(JspCompilationContext clctxt) throws IOException { try { File libFile = new File(lib, libs[i]); classPath = classPath + File.pathSeparator + libFile.getCanonicalPath(); - urls.add(libFile.getCanonicalFile().toURL()); + urls.add(libFile.getCanonicalFile().toURI().toURL()); } catch (IOException ioe) { // failing a toCanonicalPath on a file that // exists() should be a JVM regression test, @@ -1440,7 +1437,7 @@ private void initClassLoader(JspCompilationContext clctxt) throws IOException { } // What is this ?? - urls.add(new File(clctxt.getRealPath("/")).getCanonicalFile().toURL()); + urls.add(new File(clctxt.getRealPath("/")).getCanonicalFile().toURI().toURL()); URL urlsA[] = new URL[urls.size()]; urls.toArray(urlsA); @@ -1519,7 +1516,7 @@ private ClassLoader initSystemClassLoader() throws IOException { ArrayList urls = new ArrayList<>(); StringTokenizer tokenizer = new StringTokenizer(sysClassPath, File.pathSeparator); while (tokenizer.hasMoreTokens()) { - urls.add(new File(tokenizer.nextToken()).toURL()); + urls.add(new File(tokenizer.nextToken()).toURI().toURL()); } if (urls.size() == 0) { diff --git a/src/main/java/org/glassfish/wasp/JspCompilationContext.java b/src/main/java/org/glassfish/wasp/JspCompilationContext.java index 58810b6..a3e0122 100644 --- a/src/main/java/org/glassfish/wasp/JspCompilationContext.java +++ b/src/main/java/org/glassfish/wasp/JspCompilationContext.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,6 +18,9 @@ package org.glassfish.wasp; +import jakarta.servlet.ServletContext; +import jakarta.servlet.jsp.tagext.TagInfo; + import java.io.File; import java.io.FileNotFoundException; import java.io.InputStream; @@ -32,11 +36,8 @@ import org.glassfish.wasp.compiler.Localizer; import org.glassfish.wasp.compiler.ServletWriter; import org.glassfish.wasp.compiler.TagLibraryInfoImpl; -import org.glassfish.wasp.servlet.WaspLoader; import org.glassfish.wasp.servlet.JspServletWrapper; - -import jakarta.servlet.ServletContext; -import jakarta.servlet.jsp.tagext.TagInfo; +import org.glassfish.wasp.servlet.WaspLoader; /** * A place holder for various things that are used through out the JSP engine. This is a per-request/per-context data @@ -602,7 +603,7 @@ public Class load() throws WaspException, ClassNotFoundException { } public ClassLoader getJspLoader() { - return new WaspLoader(new URL[] { baseUrl }, getClassLoader(), rctxt.getPermissionCollection(), rctxt.getCodeSource(), rctxt.getBytecodes()); + return new WaspLoader(new URL[] { baseUrl }, getClassLoader(), rctxt.getBytecodes()); } public void makeOutputDir(String outdir) { @@ -631,7 +632,7 @@ private void createOutputDir() { // Append servlet or tag handler path to scratch dir File f = new File(options.getScratchDir(), path); makeOutputDir(f.getPath() + File.separator); - baseUrl = options.getScratchDir().toURL(); + baseUrl = options.getScratchDir().toURI().toURL(); } catch (Exception e) { throw new IllegalStateException("No output directory: " + e.getMessage()); } diff --git a/src/main/java/org/glassfish/wasp/compiler/JspDocumentParser.java b/src/main/java/org/glassfish/wasp/compiler/JspDocumentParser.java index ecd0b82..7fc9d91 100644 --- a/src/main/java/org/glassfish/wasp/compiler/JspDocumentParser.java +++ b/src/main/java/org/glassfish/wasp/compiler/JspDocumentParser.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,26 +18,24 @@ package org.glassfish.wasp.compiler; +import jakarta.servlet.jsp.tagext.TagFileInfo; +import jakarta.servlet.jsp.tagext.TagInfo; +import jakarta.servlet.jsp.tagext.TagLibraryInfo; + import java.io.CharArrayWriter; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.security.AccessController; -// START GlassFish 750 import java.util.Iterator; import java.util.List; -// START GlassFish 750 import java.util.concurrent.ConcurrentHashMap; import java.util.jar.JarFile; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; -import org.glassfish.wasp.Constants; -import org.glassfish.wasp.WaspException; import org.glassfish.wasp.JspCompilationContext; -import org.glassfish.wasp.security.PrivilegedGetTccl; -import org.glassfish.wasp.security.PrivilegedSetTccl; +import org.glassfish.wasp.WaspException; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.Locator; @@ -47,10 +46,6 @@ import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.DefaultHandler; -import jakarta.servlet.jsp.tagext.TagFileInfo; -import jakarta.servlet.jsp.tagext.TagInfo; -import jakarta.servlet.jsp.tagext.TagLibraryInfo; - /** * Class implementing a parser for a JSP document, that is, a JSP page in XML syntax. * @@ -996,20 +991,10 @@ private void checkPrefix(String uri, String qName) { */ private static SAXParser getSAXParser(boolean validating, JspDocumentParser jspDocParser) throws Exception { - ClassLoader original; - if (Constants.IS_SECURITY_ENABLED) { - PrivilegedGetTccl pa = new PrivilegedGetTccl(); - original = AccessController.doPrivileged(pa); - } else { - original = Thread.currentThread().getContextClassLoader(); - } + ClassLoader original = Thread.currentThread().getContextClassLoader(); + try { - if (Constants.IS_SECURITY_ENABLED) { - PrivilegedSetTccl pa = new PrivilegedSetTccl(JspDocumentParser.class.getClassLoader()); - AccessController.doPrivileged(pa); - } else { - Thread.currentThread().setContextClassLoader(JspDocumentParser.class.getClassLoader()); - } + Thread.currentThread().setContextClassLoader(JspDocumentParser.class.getClassLoader()); SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(true); @@ -1026,12 +1011,7 @@ private static SAXParser getSAXParser(boolean validating, JspDocumentParser jspD return saxParser; } finally { - if (Constants.IS_SECURITY_ENABLED) { - PrivilegedSetTccl pa = new PrivilegedSetTccl(original); - AccessController.doPrivileged(pa); - } else { - Thread.currentThread().setContextClassLoader(original); - } + Thread.currentThread().setContextClassLoader(original); } } diff --git a/src/main/java/org/glassfish/wasp/compiler/JspRuntimeContext.java b/src/main/java/org/glassfish/wasp/compiler/JspRuntimeContext.java index 7bdaedf..0343649 100644 --- a/src/main/java/org/glassfish/wasp/compiler/JspRuntimeContext.java +++ b/src/main/java/org/glassfish/wasp/compiler/JspRuntimeContext.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,22 +18,15 @@ package org.glassfish.wasp.compiler; -import static java.util.logging.Level.SEVERE; -import static org.glassfish.wasp.Constants.IS_SECURITY_ENABLED; +import jakarta.servlet.ServletContext; +import jakarta.servlet.jsp.JspFactory; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.io.FilePermission; import java.io.IOException; import java.io.UnsupportedEncodingException; -import java.net.URL; -import java.net.URLClassLoader; import java.net.URLDecoder; -import java.security.CodeSource; -import java.security.PermissionCollection; -import java.security.Policy; -import java.security.cert.Certificate; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; @@ -45,12 +39,10 @@ import org.glassfish.wasp.JspCompilationContext; import org.glassfish.wasp.Options; import org.glassfish.wasp.runtime.JspFactoryImpl; -import org.glassfish.wasp.security.SecurityClassLoad; import org.glassfish.wasp.servlet.JspCServletContext; import org.glassfish.wasp.servlet.JspServletWrapper; -import jakarta.servlet.ServletContext; -import jakarta.servlet.jsp.JspFactory; +import static java.util.logging.Level.SEVERE; /** * Class for tracking JSP compile time file dependencies when the <@include file="..."> directive is used. @@ -74,26 +66,8 @@ public final class JspRuntimeContext implements Runnable { */ private AtomicInteger jspReloadCount = new AtomicInteger(0); - /** - * Preload classes required at runtime by a JSP servlet so that we don't get a defineClassInPackage security exception. - */ static { - JspFactoryImpl factory = new JspFactoryImpl(); - SecurityClassLoad.securityClassLoad(factory.getClass().getClassLoader()); - if (System.getSecurityManager() != null) { - String basePackage = "org.glassfish.wasp."; - try { - factory.getClass().getClassLoader().loadClass(basePackage + "runtime.JspFactoryImpl$PrivilegedGetPageContext"); - factory.getClass().getClassLoader().loadClass(basePackage + "runtime.JspFactoryImpl$PrivilegedReleasePageContext"); - factory.getClass().getClassLoader().loadClass(basePackage + "runtime.JspRuntimeLibrary"); - factory.getClass().getClassLoader().loadClass(basePackage + "runtime.ServletResponseWrapperInclude"); - factory.getClass().getClassLoader().loadClass(basePackage + "servlet.JspServletWrapper"); - } catch (ClassNotFoundException ex) { - log.log(SEVERE, "Wasp JspRuntimeContext preload of class failed: " + ex.getMessage(), ex); - } - } - - JspFactory.setDefaultFactory(factory); + JspFactory.setDefaultFactory(new JspFactoryImpl()); } // ----------------------------------------------------------- Constructors @@ -132,10 +106,6 @@ public JspRuntimeContext(ServletContext context, Options options) { return; } - if (IS_SECURITY_ENABLED) { - initSecurity(); - } - // If this web application context is running from a // directory, start the background compilation thread String appBase = context.getRealPath("/"); @@ -156,8 +126,6 @@ public JspRuntimeContext(ServletContext context, Options options) { */ private ServletContext context; private Options options; - private PermissionCollection permissionCollection; - private CodeSource codeSource; private String classpath; /** @@ -233,15 +201,6 @@ public int getJspCount() { return jsps.size(); } - /** - * Get the SecurityManager Policy CodeSource for this web applicaiton context. - * - * @return CodeSource for JSP - */ - public CodeSource getCodeSource() { - return codeSource; - } - /** * Get the parent class loader. * @@ -255,15 +214,6 @@ public ClassLoader getParentClassLoader() { return parentClassLoader; } - /** - * Get the SecurityManager PermissionCollection for this web application context. - * - * @return PermissionCollection permissions - */ - public PermissionCollection getPermissionCollection() { - return permissionCollection; - } - /** * Process a "destory" event for this web application context. */ @@ -450,83 +400,6 @@ private void initClassPath() { // END GlassFish Issue 845 } - /** - * Method used to initialize SecurityManager data. - */ - private void initSecurity() { - - // Setup the PermissionCollection for this web app context - // based on the permissions configured for the root of the - // web app context directory, then add a file read permission - // for that directory. - Policy policy = Policy.getPolicy(); - if (policy != null) { - try { - // Get the permissions for the web app context - String docBase = context.getRealPath("/"); - if (docBase == null) { - docBase = options.getScratchDir().toString(); - } - String codeBase = docBase; - if (!codeBase.endsWith(File.separator)) { - codeBase = codeBase + File.separator; - } - File contextDir = new File(codeBase); - URL url = contextDir.getCanonicalFile().toURL(); - codeSource = new CodeSource(url, (Certificate[]) null); - permissionCollection = policy.getPermissions(codeSource); - - // Create a file read permission for web app context directory - if (!docBase.endsWith(File.separator)) { - permissionCollection.add(new FilePermission(docBase, "read")); - docBase = docBase + File.separator; - } else { - permissionCollection.add(new FilePermission(docBase.substring(0, docBase.length() - 1), "read")); - } - docBase = docBase + "-"; - permissionCollection.add(new FilePermission(docBase, "read")); - - // Create a file read permission for web app tempdir (work) - // directory - String workDir = options.getScratchDir().toString(); - if (!workDir.endsWith(File.separator)) { - permissionCollection.add(new FilePermission(workDir, "read")); - workDir = workDir + File.separator; - } - workDir = workDir + "-"; - permissionCollection.add(new FilePermission(workDir, "read")); - - // Allow the JSP to access org.glassfish.wasp.runtime.HttpJspBase - permissionCollection.add(new RuntimePermission("accessClassInPackage.org.glassfish.wasp.runtime")); - - ClassLoader parentClassLoader = getParentClassLoader(); - if (parentClassLoader instanceof URLClassLoader) { - URL[] urls = ((URLClassLoader) parentClassLoader).getURLs(); - String jarUrl = null; - String jndiUrl = null; - for (int i = 0; i < urls.length; i++) { - if (jndiUrl == null && urls[i].toString().startsWith("jndi:")) { - jndiUrl = urls[i].toString() + "-"; - } - if (jarUrl == null && urls[i].toString().startsWith("jar:jndi:")) { - jarUrl = urls[i].toString(); - jarUrl = jarUrl.substring(0, jarUrl.length() - 2); - jarUrl = jarUrl.substring(0, jarUrl.lastIndexOf('/')) + "/-"; - } - } - if (jarUrl != null) { - permissionCollection.add(new FilePermission(jarUrl, "read")); - permissionCollection.add(new FilePermission(jarUrl.substring(4), "read")); - } - if (jndiUrl != null) { - permissionCollection.add(new FilePermission(jndiUrl, "read")); - } - } - } catch (Exception e) { - context.log("Security Init for context failed", e); - } - } - } // -------------------------------------------------------- Thread Support diff --git a/src/main/java/org/glassfish/wasp/compiler/TagLibraryInfoImpl.java b/src/main/java/org/glassfish/wasp/compiler/TagLibraryInfoImpl.java index 0bff9c1..acb8497 100644 --- a/src/main/java/org/glassfish/wasp/compiler/TagLibraryInfoImpl.java +++ b/src/main/java/org/glassfish/wasp/compiler/TagLibraryInfoImpl.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,6 +18,18 @@ package org.glassfish.wasp.compiler; +import jakarta.servlet.jsp.tagext.FunctionInfo; +import jakarta.servlet.jsp.tagext.PageData; +import jakarta.servlet.jsp.tagext.TagAttributeInfo; +import jakarta.servlet.jsp.tagext.TagExtraInfo; +import jakarta.servlet.jsp.tagext.TagFileInfo; +import jakarta.servlet.jsp.tagext.TagInfo; +import jakarta.servlet.jsp.tagext.TagLibraryInfo; +import jakarta.servlet.jsp.tagext.TagLibraryValidator; +import jakarta.servlet.jsp.tagext.TagVariableInfo; +import jakarta.servlet.jsp.tagext.ValidationMessage; +import jakarta.servlet.jsp.tagext.VariableInfo; + import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; @@ -34,24 +47,12 @@ import java.util.zip.ZipEntry; import org.glassfish.wasp.Constants; -import org.glassfish.wasp.WaspException; import org.glassfish.wasp.JspCompilationContext; +import org.glassfish.wasp.WaspException; import org.glassfish.wasp.runtime.TldScanner; import org.glassfish.wasp.xmlparser.ParserUtils; import org.glassfish.wasp.xmlparser.TreeNode; -import jakarta.servlet.jsp.tagext.FunctionInfo; -import jakarta.servlet.jsp.tagext.PageData; -import jakarta.servlet.jsp.tagext.TagAttributeInfo; -import jakarta.servlet.jsp.tagext.TagExtraInfo; -import jakarta.servlet.jsp.tagext.TagFileInfo; -import jakarta.servlet.jsp.tagext.TagInfo; -import jakarta.servlet.jsp.tagext.TagLibraryInfo; -import jakarta.servlet.jsp.tagext.TagLibraryValidator; -import jakarta.servlet.jsp.tagext.TagVariableInfo; -import jakarta.servlet.jsp.tagext.ValidationMessage; -import jakarta.servlet.jsp.tagext.VariableInfo; - /** * Implementation of the TagLibraryInfo class from the JSP spec. * @@ -276,10 +277,10 @@ private void parseTLD(JspCompilationContext ctxt, String uri, InputStream in, UR this.jspversion = tld.findAttribute("version"); // Process each child element of our element - Iterator list = tld.findChildren(); + Iterator list = tld.findChildren(); while (list.hasNext()) { - TreeNode element = (TreeNode) list.next(); + TreeNode element = list.next(); String tname = element.getName(); if ("tlibversion".equals(tname) // JSP 1.1 @@ -453,8 +454,8 @@ private TagInfo createTagInfo(TreeNode elem, String jspVersion) throws WaspExcep TagExtraInfo tei = null; if (teiClassName != null && !teiClassName.equals("")) { try { - Class teiClass = ctxt.getClassLoader().loadClass(teiClassName); - tei = (TagExtraInfo) teiClass.newInstance(); + Class teiClass = ctxt.getClassLoader().loadClass(teiClassName); + tei = (TagExtraInfo) teiClass.getDeclaredConstructor().newInstance(); } catch (Exception e) { err.jspError("jsp.error.teiclass.instantiation", teiClassName, e); } @@ -488,9 +489,9 @@ private TagFileInfo createTagFileInfo(TreeNode elem, String uri, URL jarFileUrl) String icon = null; boolean checkConflict = false; - Iterator list = elem.findChildren(); + Iterator list = elem.findChildren(); while (list.hasNext()) { - TreeNode child = (TreeNode) list.next(); + TreeNode child = list.next(); String tname = child.getName(); if ("name".equals(tname)) { name = child.getBody(); @@ -553,9 +554,9 @@ private TagAttributeInfo createAttribute(TreeNode elem, String jspVersion) throw String methodSignature = "void method()"; String description = null; - Iterator list = elem.findChildren(); + Iterator list = elem.findChildren(); while (list.hasNext()) { - TreeNode element = (TreeNode) list.next(); + TreeNode element = list.next(); String tname = element.getName(); if ("name".equals(tname)) { @@ -586,9 +587,9 @@ private TagAttributeInfo createAttribute(TreeNode elem, String jspVersion) throw description = element.getBody(); } else if ("deferred-value".equals(tname)) { deferredValue = true; - Iterator iter = element.findChildren(); + Iterator iter = element.findChildren(); if (iter.hasNext()) { - TreeNode element2 = (TreeNode) iter.next(); + TreeNode element2 = iter.next(); tname = element2.getName(); if ("type".equals(tname)) { String s = element2.getBody(); @@ -601,9 +602,9 @@ private TagAttributeInfo createAttribute(TreeNode elem, String jspVersion) throw } } else if ("deferred-method".equals(tname)) { deferredMethod = true; - Iterator iter = element.findChildren(); + Iterator iter = element.findChildren(); if (iter.hasNext()) { - TreeNode element2 = (TreeNode) iter.next(); + TreeNode element2 = iter.next(); tname = element2.getName(); if ("method-signature".equals(tname)) { String s = element2.getBody(); @@ -646,9 +647,9 @@ private TagVariableInfo createVariable(TreeNode elem) throws WaspException { boolean declare = true; int scope = VariableInfo.NESTED; - Iterator list = elem.findChildren(); + Iterator list = elem.findChildren(); while (list.hasNext()) { - TreeNode element = (TreeNode) list.next(); + TreeNode element = list.next(); String tname = element.getName(); if ("name-given".equals(tname)) { nameGiven = element.getBody(); @@ -686,9 +687,9 @@ private TagLibraryValidator createValidator(TreeNode elem) throws WaspException String validatorClass = null; Map initParams = new HashMap<>(); - Iterator list = elem.findChildren(); + Iterator list = elem.findChildren(); while (list.hasNext()) { - TreeNode element = (TreeNode) list.next(); + TreeNode element = list.next(); String tname = element.getName(); if ("validator-class".equals(tname)) { validatorClass = element.getBody(); @@ -705,8 +706,11 @@ private TagLibraryValidator createValidator(TreeNode elem) throws WaspException TagLibraryValidator tlv = null; if (validatorClass != null && !validatorClass.equals("")) { try { - Class tlvClass = ctxt.getClassLoader().loadClass(validatorClass); - tlv = (TagLibraryValidator) tlvClass.newInstance(); + tlv = (TagLibraryValidator) + ctxt.getClassLoader() + .loadClass(validatorClass) + .getDeclaredConstructor() + .newInstance(); } catch (Exception e) { err.jspError("jsp.error.tlvclass.instantiation", validatorClass, e); } @@ -714,6 +718,7 @@ private TagLibraryValidator createValidator(TreeNode elem) throws WaspException if (tlv != null) { tlv.setInitParameters(initParams); } + return tlv; } @@ -721,9 +726,9 @@ private String[] createInitParam(TreeNode elem) throws WaspException { String[] initParam = new String[2]; - Iterator list = elem.findChildren(); + Iterator list = elem.findChildren(); while (list.hasNext()) { - TreeNode element = (TreeNode) list.next(); + TreeNode element = list.next(); String tname = element.getName(); if ("param-name".equals(tname)) { initParam[0] = element.getBody(); @@ -744,9 +749,9 @@ private FunctionInfo createFunctionInfo(TreeNode elem) throws WaspException { String klass = null; String signature = null; - Iterator list = elem.findChildren(); + Iterator list = elem.findChildren(); while (list.hasNext()) { - TreeNode element = (TreeNode) list.next(); + TreeNode element = list.next(); String tname = element.getName(); if ("name".equals(tname)) { diff --git a/src/main/java/org/glassfish/wasp/compiler/TagPluginManager.java b/src/main/java/org/glassfish/wasp/compiler/TagPluginManager.java index 355930d..b6a4d1f 100644 --- a/src/main/java/org/glassfish/wasp/compiler/TagPluginManager.java +++ b/src/main/java/org/glassfish/wasp/compiler/TagPluginManager.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,6 +18,8 @@ package org.glassfish.wasp.compiler; +import jakarta.servlet.ServletContext; + import java.io.InputStream; import java.util.HashMap; import java.util.Iterator; @@ -28,8 +31,6 @@ import org.glassfish.wasp.xmlparser.ParserUtils; import org.glassfish.wasp.xmlparser.TreeNode; -import jakarta.servlet.ServletContext; - /** * Manages tag plugin optimizations. * @@ -90,9 +91,9 @@ private void init(ErrorDispatcher err) throws WaspException { } tagPlugins = new HashMap<>(); - Iterator pluginList = root.findChildren("tag-plugin"); + Iterator pluginList = root.findChildren("tag-plugin"); while (pluginList.hasNext()) { - TreeNode pluginNode = (TreeNode) pluginList.next(); + TreeNode pluginNode = pluginList.next(); TreeNode tagClassNode = pluginNode.findChild("tag-class"); if (tagClassNode == null) { // Error @@ -108,8 +109,10 @@ private void init(ErrorDispatcher err) throws WaspException { String pluginClassStr = pluginClassNode.getBody(); TagPlugin tagPlugin = null; try { - Class pluginClass = Class.forName(pluginClassStr).asSubclass(TagPlugin.class); - tagPlugin = pluginClass.newInstance(); + tagPlugin = Class.forName(pluginClassStr) + .asSubclass(TagPlugin.class) + .getDeclaredConstructor() + .newInstance(); } catch (Exception e) { throw new WaspException(e); } diff --git a/src/main/java/org/glassfish/wasp/runtime/Classpath.java b/src/main/java/org/glassfish/wasp/runtime/Classpath.java index 78f1ce4..6623b5e 100644 --- a/src/main/java/org/glassfish/wasp/runtime/Classpath.java +++ b/src/main/java/org/glassfish/wasp/runtime/Classpath.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the @@ -16,10 +17,6 @@ package org.glassfish.wasp.runtime; -import static java.util.Arrays.asList; -import static org.glassfish.wasp.runtime.Classpath.SearchAdvice.AllMatches; -import static org.glassfish.wasp.runtime.Classpath.SearchAdvice.FirstMatchOnly; - import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -37,6 +34,10 @@ import java.util.zip.ZipException; import java.util.zip.ZipInputStream; +import static java.util.Arrays.asList; +import static org.glassfish.wasp.runtime.Classpath.SearchAdvice.AllMatches; +import static org.glassfish.wasp.runtime.Classpath.SearchAdvice.FirstMatchOnly; + /** * @author Jacob Hookom * @author Roland Huss @@ -64,13 +65,13 @@ public static URL[] search(ClassLoader cl, String prefix, String suffix) throws public static URL[] search(ClassLoader classLoader, String prefix, String suffix, SearchAdvice advice) throws IOException { List> urlResources = asList(classLoader.getResources(prefix), classLoader.getResources(prefix + "MANIFEST.MF")); Set allUrls = new LinkedHashSet(); - + for (Enumeration urlResource : urlResources) { while (urlResource.hasMoreElements()) { URL url = urlResource.nextElement(); - + // Due to issue 13045 this collection can contain URLs that have their spaces incorrectly escaped - // by having %20 replaced with %2520. + // by having %20 replaced with %2520. // This quick conditional check catches this particular case and averts it. String str = url.getPath(); if (-1 != str.indexOf("%2520")) { @@ -78,14 +79,14 @@ public static URL[] search(ClassLoader classLoader, String prefix, String suffix str = str.replace("%2520", "%20"); url = new URL(str); } - + JarFile jarFile = getJarFile(url); - + if (jarFile != null) { // Strategy 1: search in jar archive searchJar(classLoader, allUrls, jarFile, prefix, suffix, advice); } else { - // Strategy 2: search in file system directory + // Strategy 2: search in file system directory boolean searchDone = searchDir(allUrls, new File(URLDecoder.decode(url.getFile(), "UTF-8")), suffix); if (!searchDone) { // Strategy 3: search in URL @@ -94,21 +95,21 @@ public static URL[] search(ClassLoader classLoader, String prefix, String suffix } } } - + return allUrls.toArray(new URL[allUrls.size()]); } - + private static JarFile getJarFile(URL url) throws IOException { URLConnection urlConnection = url.openConnection(); urlConnection.setUseCaches(false); - + if (urlConnection instanceof JarURLConnection) { return ((JarURLConnection) urlConnection).getJarFile(); } - + return getAlternativeJarFile(url); } - + /** * For URLs to JARs that do not use JarURLConnection - allowed by the servlet spec - attempt to produce a JarFile object * all the same. Known servlet engines that function like this include Weblogic and OC4J. This is not a full solution, @@ -120,10 +121,10 @@ private static JarFile getAlternativeJarFile(URL url) throws IOException { static JarFile getAlternativeJarFile(String urlFile) throws IOException { JarFile alternativeJarFile = null; - + // Trim off any suffix - which is prefixed by "!/" on Weblogic int bangSlash = urlFile.indexOf("!/"); - + // Try the less safe "!", used on OC4J int bang = urlFile.indexOf('!'); int separatorIndex = -1; @@ -136,19 +137,19 @@ static JarFile getAlternativeJarFile(String urlFile) throws IOException { separatorIndex = bang; } } - + if (separatorIndex == -1) { return null; } String jarFileUrl = urlFile.substring(0, separatorIndex); - + // And trim off any "file:" prefix. if (jarFileUrl.startsWith("file:")) { jarFileUrl = jarFileUrl.substring("file:".length()); jarFileUrl = URLDecoder.decode(jarFileUrl, "UTF-8"); } - + boolean foundExclusion = false; for (int i = 0; i < PREFIXES_TO_EXCLUDE.length; i++) { if (jarFileUrl.startsWith(PREFIXES_TO_EXCLUDE[i]) || jarFileUrl.endsWith(EXTENSIONS_TO_EXCLUDE[i])) { @@ -156,7 +157,7 @@ static JarFile getAlternativeJarFile(String urlFile) throws IOException { break; } } - + if (!foundExclusion) { try { alternativeJarFile = new JarFile(jarFileUrl); @@ -167,18 +168,18 @@ static JarFile getAlternativeJarFile(String urlFile) throws IOException { return alternativeJarFile; } - + private static void searchJar(ClassLoader classLoader, Set urls, JarFile file, String prefix, String suffix, SearchAdvice advice) throws IOException { Enumeration jarEntries = file.entries(); - + while (jarEntries.hasMoreElements()) { JarEntry entry; try { - entry = (JarEntry) jarEntries.nextElement(); + entry = jarEntries.nextElement(); } catch (Throwable t) { continue; } - + String name = entry.getName(); if (name.startsWith(prefix) && name.endsWith(suffix)) { Enumeration resourcesFromClassLoader = classLoader.getResources(name); @@ -195,7 +196,7 @@ private static void searchJar(ClassLoader classLoader, Set urls, JarFile fi private static boolean searchDir(Set result, File directory, String suffix) throws IOException { if (directory.exists() && directory.isDirectory()) { File[] filesInDir = directory.listFiles(); - + // Protect against Windows JDK bugs for listFiles - // If it's null (even though it shouldn't be) return false if (filesInDir == null) { @@ -206,13 +207,12 @@ private static boolean searchDir(Set result, File directory, String suffix) if (fileInDir.isDirectory()) { searchDir(result, fileInDir, suffix); } else if (fileInDir.getAbsolutePath().endsWith(suffix)) { - // result.add(new URL("file:/" + path)); - result.add(fileInDir.toURL()); + result.add(fileInDir.toURI().toURL()); } } return true; } - + return false; } @@ -228,12 +228,12 @@ private static boolean searchDir(Set result, File directory, String suffix) */ private static void searchFromURL(Set result, String prefix, String suffix, URL url) throws IOException { boolean done = false; - + InputStream urlInputStream = getInputStream(url); if (urlInputStream != null) { try (ZipInputStream zipInputStream = urlInputStream instanceof ZipInputStream ? (ZipInputStream) urlInputStream : new ZipInputStream(urlInputStream)) { ZipEntry entry = zipInputStream.getNextEntry(); - + // Initial entry should not be null if we assume this is some inner jar done = entry != null; while (entry != null) { @@ -246,9 +246,9 @@ private static void searchFromURL(Set result, String prefix, String suffix, } } } - + if (!done && prefix.length() > 0) { - + // we add '/' at the end since join adds it as well String urlString = url.toExternalForm() + "/"; String[] split = prefix.split("/"); @@ -266,7 +266,7 @@ private static void searchFromURL(Set result, String prefix, String suffix, return; } } - + searchFromURL(result, prefix, suffix, new URL(urlString)); } } @@ -302,8 +302,8 @@ private static InputStream getInputStream(URL url) { } } - - + + } diff --git a/src/main/java/org/glassfish/wasp/runtime/JspFactoryImpl.java b/src/main/java/org/glassfish/wasp/runtime/JspFactoryImpl.java index be0315d..2665877 100644 --- a/src/main/java/org/glassfish/wasp/runtime/JspFactoryImpl.java +++ b/src/main/java/org/glassfish/wasp/runtime/JspFactoryImpl.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,7 +18,6 @@ package org.glassfish.wasp.runtime; -import java.security.AccessController; import java.security.PrivilegedAction; import java.util.LinkedList; import java.util.logging.Level; @@ -45,7 +45,7 @@ public class JspFactoryImpl extends JspFactory { // Logger private static Logger log = Logger.getLogger(JspFactoryImpl.class.getName()); - private static final String SPEC_VERSION = "2.1"; + private static final String SPEC_VERSION = "4.0"; // Pooling PageContextImpl intances are known to leak memories, see // https://glassfish.dev.java.net/issues/show_bug.cgi?id=8601 @@ -65,25 +65,16 @@ protected synchronized LinkedList initialValue() { public PageContext getPageContext(Servlet servlet, ServletRequest request, ServletResponse response, String errorPageURL, boolean needsSession, int bufferSize, boolean autoflush) { - if (Constants.IS_SECURITY_ENABLED) { - PrivilegedGetPageContext dp = new PrivilegedGetPageContext(this, servlet, request, response, errorPageURL, needsSession, bufferSize, autoflush); - return AccessController.doPrivileged(dp); - } else { - return internalGetPageContext(servlet, request, response, errorPageURL, needsSession, bufferSize, autoflush); - } + return internalGetPageContext(servlet, request, response, errorPageURL, needsSession, bufferSize, autoflush); } @Override - public void releasePageContext(PageContext pc) { - if (pc == null) { + public void releasePageContext(PageContext pageContext) { + if (pageContext == null) { return; } - if (Constants.IS_SECURITY_ENABLED) { - PrivilegedReleasePageContext dp = new PrivilegedReleasePageContext(this, pc); - AccessController.doPrivileged(dp); - } else { - internalReleasePageContext(pc); - } + + internalReleasePageContext(pageContext); } @Override diff --git a/src/main/java/org/glassfish/wasp/runtime/JspRuntimeLibrary.java b/src/main/java/org/glassfish/wasp/runtime/JspRuntimeLibrary.java index 7bb3a00..e1e2ec1 100644 --- a/src/main/java/org/glassfish/wasp/runtime/JspRuntimeLibrary.java +++ b/src/main/java/org/glassfish/wasp/runtime/JspRuntimeLibrary.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,6 +18,17 @@ package org.glassfish.wasp.runtime; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.jsp.JspWriter; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.BodyContent; + +import java.beans.BeanInfo; +import java.beans.Introspector; import java.beans.PropertyEditor; import java.beans.PropertyEditorManager; import java.io.IOException; @@ -28,15 +40,6 @@ import org.glassfish.wasp.WaspException; import org.glassfish.wasp.compiler.Localizer; -import jakarta.servlet.RequestDispatcher; -import jakarta.servlet.ServletException; -import jakarta.servlet.ServletRequest; -import jakarta.servlet.ServletResponse; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.jsp.JspWriter; -import jakarta.servlet.jsp.PageContext; -import jakarta.servlet.jsp.tagext.BodyContent; - /** * Bunch of util methods that are used by code generated for useBean, getProperty and setProperty. * @@ -204,7 +207,7 @@ public static T coerce(String s, Class target) { } // __begin convertMethod - public static Object convert(String propertyName, String s, Class t, Class propertyEditorClass) throws WaspException { + public static Object convert(String propertyName, String s, Class t, Class propertyEditorClass) throws WaspException { try { if (s == null) { if (t.equals(Boolean.class) || t.equals(Boolean.TYPE)) { @@ -252,9 +255,9 @@ public static Object convert(String propertyName, String s, Class t, Class prope // __begin introspectMethod public static void introspect(Object bean, ServletRequest request) throws WaspException { - Enumeration e = request.getParameterNames(); + Enumeration e = request.getParameterNames(); while (e.hasMoreElements()) { - String name = (String) e.nextElement(); + String name = e.nextElement(); String value = request.getParameter(name); introspecthelper(bean, name, value, request, name, true); } @@ -265,8 +268,9 @@ public static void introspect(Object bean, ServletRequest request) throws WaspEx public static void introspecthelper(Object bean, String prop, String value, ServletRequest request, String param, boolean ignoreMethodNF) throws WaspException { Method method = null; - Class type = null; - Class propertyEditorClass = null; + Class type = null; + Class propertyEditorClass = null; + try { java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean.getClass()); if (info != null) { @@ -285,12 +289,14 @@ public static void introspecthelper(Object bean, String prop, String value, Serv if (request == null) { throw new WaspException(Localizer.getMessage("jsp.error.beans.setproperty.noindexset")); } - Class t = type.getComponentType(); + Class t = type.getComponentType(); String[] values = request.getParameterValues(param); + // XXX Please check. if (values == null) { return; } + if (t.equals(String.class)) { method.invoke(bean, new Object[] { values }); } else { @@ -363,7 +369,7 @@ public static String toString(char c) { /** * Create a typed array. This is a special case where params are passed through the request and the property is indexed. */ - public static void createTypedArray(String propertyName, Object bean, Method method, String[] values, Class t, Class propertyEditorClass) + public static void createTypedArray(String propertyName, Object bean, Method method, String[] values, Class t, Class propertyEditorClass) throws WaspException { try { @@ -623,11 +629,11 @@ public static void handleSetProperty(Object bean, String prop, boolean value) th } } - public static Method getWriteMethod(Class beanClass, String prop) throws WaspException { + public static Method getWriteMethod(Class beanClass, String prop) throws WaspException { Method method = null; - Class type = null; + Class type = null; try { - java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(beanClass); + BeanInfo info = Introspector.getBeanInfo(beanClass); if (info != null) { java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors(); for (int i = 0; i < pd.length; i++) { @@ -644,6 +650,7 @@ public static Method getWriteMethod(Class beanClass, String prop) throws WaspExc } catch (Exception ex) { throw new WaspException(ex); } + if (method == null) { if (type == null) { throw new WaspException(Localizer.getMessage("jsp.error.beans.noproperty", prop, beanClass.getName())); @@ -654,10 +661,10 @@ public static Method getWriteMethod(Class beanClass, String prop) throws WaspExc return method; } - public static Method getReadMethod(Class beanClass, String prop) throws WaspException { + public static Method getReadMethod(Class beanClass, String prop) throws WaspException { Method method = null; - Class type = null; + Class type = null; try { java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(beanClass); if (info != null) { @@ -676,6 +683,7 @@ public static Method getReadMethod(Class beanClass, String prop) throws WaspExce } catch (Exception ex) { throw new WaspException(ex); } + if (method == null) { if (type == null) { throw new WaspException(Localizer.getMessage("jsp.error.beans.noproperty", prop, beanClass.getName())); @@ -690,10 +698,10 @@ public static Method getReadMethod(Class beanClass, String prop) throws WaspExce // ********************************************************************* // PropertyEditor Support - public static Object getValueFromBeanInfoPropertyEditor(Class attrClass, String attrName, String attrValue, Class propertyEditorClass) + public static Object getValueFromBeanInfoPropertyEditor(Class attrClass, String attrName, String attrValue, Class propertyEditorClass) throws WaspException { try { - PropertyEditor pe = (PropertyEditor) propertyEditorClass.newInstance(); + PropertyEditor pe = (PropertyEditor) propertyEditorClass.getDeclaredConstructor().newInstance(); pe.setAsText(attrValue); return pe.getValue(); } catch (Exception ex) { @@ -701,7 +709,7 @@ public static Object getValueFromBeanInfoPropertyEditor(Class attrClass, String } } - public static Object getValueFromPropertyEditorManager(Class attrClass, String attrName, String attrValue) throws WaspException { + public static Object getValueFromPropertyEditorManager(Class attrClass, String attrName, String attrValue) throws WaspException { try { PropertyEditor propEditor = PropertyEditorManager.findEditor(attrClass); if (propEditor != null) { diff --git a/src/main/java/org/glassfish/wasp/runtime/JspWriterImpl.java b/src/main/java/org/glassfish/wasp/runtime/JspWriterImpl.java index 0ef71ed..8e737d3 100644 --- a/src/main/java/org/glassfish/wasp/runtime/JspWriterImpl.java +++ b/src/main/java/org/glassfish/wasp/runtime/JspWriterImpl.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,18 +18,15 @@ package org.glassfish.wasp.runtime; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.jsp.JspWriter; + import java.io.IOException; import java.io.Writer; -import java.security.AccessController; -import java.security.PrivilegedAction; import org.glassfish.jsp.api.ByteWriter; import org.glassfish.wasp.Constants; import org.glassfish.wasp.compiler.Localizer; -import org.glassfish.wasp.security.SecurityUtil; - -import jakarta.servlet.ServletResponse; -import jakarta.servlet.jsp.JspWriter; /** * Write text to a character-output stream, buffering characters so as to provide for the efficient writing of single @@ -147,11 +145,7 @@ private void initOut() throws IOException { } private String getLocalizeMessage(final String message) { - if (SecurityUtil.isPackageProtectionEnabled()) { - return AccessController.doPrivileged((PrivilegedAction) () -> Localizer.getMessage(message)); - } else { - return Localizer.getMessage(message); - } + return Localizer.getMessage(message); } /** diff --git a/src/main/java/org/glassfish/wasp/runtime/PageContextImpl.java b/src/main/java/org/glassfish/wasp/runtime/PageContextImpl.java index 2145f99..270ab7d 100644 --- a/src/main/java/org/glassfish/wasp/runtime/PageContextImpl.java +++ b/src/main/java/org/glassfish/wasp/runtime/PageContextImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation. + * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation. * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -18,24 +18,6 @@ package org.glassfish.wasp.runtime; -import static java.lang.Boolean.TRUE; - -import java.io.IOException; -import java.io.Writer; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.logging.Logger; - -import org.glassfish.wasp.Constants; -import org.glassfish.wasp.compiler.Localizer; -import org.glassfish.wasp.security.SecurityUtil; - import jakarta.el.ArrayELResolver; import jakarta.el.BeanELResolver; import jakarta.el.CompositeELResolver; @@ -70,6 +52,19 @@ import jakarta.servlet.jsp.el.ScopedAttributeELResolver; import jakarta.servlet.jsp.tagext.BodyContent; +import java.io.IOException; +import java.io.Writer; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.logging.Logger; + +import org.glassfish.wasp.Constants; +import org.glassfish.wasp.compiler.Localizer; + +import static java.lang.Boolean.TRUE; + /** * Implementation of the PageContext class from the JSP spec. * @@ -206,17 +201,11 @@ public void release() { @Override public Object getAttribute(final String name) { - if (name == null) { throw new NullPointerException(Localizer.getMessage("jsp.error.attribute.null_name")); } - if (SecurityUtil.isPackageProtectionEnabled()) { - return AccessController.doPrivileged((PrivilegedAction) () -> doGetAttribute(name)); - } else { - return doGetAttribute(name); - } - + return doGetAttribute(name); } private Object doGetAttribute(String name) { @@ -228,17 +217,11 @@ private Object doGetAttribute(String name) { @Override public Object getAttribute(final String name, final int scope) { - if (name == null) { throw new NullPointerException(Localizer.getMessage("jsp.error.attribute.null_name")); } - if (SecurityUtil.isPackageProtectionEnabled()) { - return AccessController.doPrivileged((PrivilegedAction) () -> doGetAttribute(name, scope)); - } else { - return doGetAttribute(name, scope); - } - + return doGetAttribute(name, scope); } private Object doGetAttribute(String name, int scope) { @@ -268,19 +251,11 @@ private Object doGetAttribute(String name, int scope) { @Override public void setAttribute(final String name, final Object attribute) { - if (name == null) { throw new NullPointerException(Localizer.getMessage("jsp.error.attribute.null_name")); } - if (SecurityUtil.isPackageProtectionEnabled()) { - AccessController.doPrivileged((PrivilegedAction) () -> { - doSetAttribute(name, attribute); - return null; - }); - } else { - doSetAttribute(name, attribute); - } + doSetAttribute(name, attribute); } private void doSetAttribute(String name, Object attribute) { @@ -296,20 +271,11 @@ private void doSetAttribute(String name, Object attribute) { @Override public void setAttribute(final String name, final Object o, final int scope) { - if (name == null) { throw new NullPointerException(Localizer.getMessage("jsp.error.attribute.null_name")); } - if (SecurityUtil.isPackageProtectionEnabled()) { - AccessController.doPrivileged((PrivilegedAction) () -> { - doSetAttribute(name, o, scope); - return null; - }); - } else { - doSetAttribute(name, o, scope); - } - + doSetAttribute(name, o, scope); } private void doSetAttribute(String name, Object o, int scope) { @@ -347,18 +313,11 @@ private void doSetAttribute(String name, Object o, int scope) { @Override public void removeAttribute(final String name, final int scope) { - if (name == null) { throw new NullPointerException(Localizer.getMessage("jsp.error.attribute.null_name")); } - if (SecurityUtil.isPackageProtectionEnabled()) { - AccessController.doPrivileged((PrivilegedAction) () -> { - doRemoveAttribute(name, scope); - return null; - }); - } else { - doRemoveAttribute(name, scope); - } + + doRemoveAttribute(name, scope); } private void doRemoveAttribute(String name, int scope) { @@ -392,16 +351,11 @@ private void doRemoveAttribute(String name, int scope) { @Override public int getAttributesScope(final String name) { - if (name == null) { throw new NullPointerException(Localizer.getMessage("jsp.error.attribute.null_name")); } - if (SecurityUtil.isPackageProtectionEnabled()) { - return AccessController.doPrivileged((PrivilegedAction) () -> doGetAttributeScope(name)); - } else { - return doGetAttributeScope(name); - } + return doGetAttributeScope(name); } private int doGetAttributeScope(String name) { @@ -438,25 +392,14 @@ private int doGetAttributeScope(String name) { @Override public Object findAttribute(final String name) { - if (SecurityUtil.isPackageProtectionEnabled()) { - return AccessController.doPrivileged((PrivilegedAction) () -> { - if (name == null) { - throw new NullPointerException(Localizer.getMessage("jsp.error.attribute.null_name")); - } - - return doFindAttribute(name); - }); - } else { - if (name == null) { - throw new NullPointerException(Localizer.getMessage("jsp.error.attribute.null_name")); - } - - return doFindAttribute(name); + if (name == null) { + throw new NullPointerException(Localizer.getMessage("jsp.error.attribute.null_name")); } + + return doFindAttribute(name); } private Object doFindAttribute(String name) { - if (!isNametableInitialized) { initializePageScopeNameTable(); } @@ -489,11 +432,7 @@ private Object doFindAttribute(String name) { @Override public Enumeration getAttributeNamesInScope(final int scope) { - if (SecurityUtil.isPackageProtectionEnabled()) { - return AccessController.doPrivileged((PrivilegedAction>) () -> doGetAttributeNamesInScope(scope)); - } else { - return doGetAttributeNamesInScope(scope); - } + return doGetAttributeNamesInScope(scope); } private Enumeration doGetAttributeNamesInScope(int scope) { @@ -523,19 +462,11 @@ private Enumeration doGetAttributeNamesInScope(int scope) { @Override public void removeAttribute(final String name) { - if (name == null) { throw new NullPointerException(Localizer.getMessage("jsp.error.attribute.null_name")); } - if (SecurityUtil.isPackageProtectionEnabled()) { - AccessController.doPrivileged((PrivilegedAction) () -> { - doRemoveAttribute(name); - return null; - }); - } else { - doRemoveAttribute(name); - } + doRemoveAttribute(name); } private void doRemoveAttribute(String name) { @@ -794,24 +725,7 @@ public void handlePageException(final Throwable t) throws IOException, ServletEx throw new NullPointerException("null Throwable"); } - if (SecurityUtil.isPackageProtectionEnabled()) { - try { - AccessController.doPrivileged((PrivilegedExceptionAction) () -> { - doHandlePageException(t); - return null; - }); - } catch (PrivilegedActionException e) { - Exception ex = e.getException(); - if (ex instanceof IOException) { - throw (IOException) ex; - } else { - throw (ServletException) ex; - } - } - } else { - doHandlePageException(t); - } - + doHandlePageException(t); } private void doHandlePageException(Throwable t) throws IOException, ServletException { @@ -894,35 +808,12 @@ private static ExpressionFactory getExpressionFactory(PageContext pageContext) { * @return The result of the evaluation */ public static Object evaluateExpression(final String expression, final Class expectedType, final PageContext pageContext, final ProtectedFunctionMapper functionMap) throws ELException { - Object retValue; - if (SecurityUtil.isPackageProtectionEnabled()) { - try { - retValue = AccessController.doPrivileged((PrivilegedExceptionAction) () -> { - ELContext elContext = pageContext.getELContext(); - toELContextImpl(elContext).setFunctionMapper(functionMap); - - return getExpressionFactory(pageContext) - .createValueExpression(elContext, expression, expectedType) - .getValue(elContext); - }); - } catch (PrivilegedActionException ex) { - Exception realEx = ex.getException(); - if (realEx instanceof ELException) { - throw (ELException) realEx; - } - - throw new ELException(realEx); - } - } else { - ELContext elContext = pageContext.getELContext(); - toELContextImpl(elContext).setFunctionMapper(functionMap); - - retValue = getExpressionFactory(pageContext) - .createValueExpression(elContext, expression, expectedType) - .getValue(elContext); - } + ELContext elContext = pageContext.getELContext(); + toELContextImpl(elContext).setFunctionMapper(functionMap); - return retValue; + return getExpressionFactory(pageContext) + .createValueExpression(elContext, expression, expectedType) + .getValue(elContext); } public static ValueExpression getValueExpression(String expression, PageContext pageContext, Class expectedType, FunctionMapper functionMap) { diff --git a/src/main/java/org/glassfish/wasp/runtime/ProtectedFunctionMapper.java b/src/main/java/org/glassfish/wasp/runtime/ProtectedFunctionMapper.java index 41ed706..b3b8949 100644 --- a/src/main/java/org/glassfish/wasp/runtime/ProtectedFunctionMapper.java +++ b/src/main/java/org/glassfish/wasp/runtime/ProtectedFunctionMapper.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,17 +18,11 @@ package org.glassfish.wasp.runtime; +import jakarta.el.FunctionMapper; + import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.HashMap; -import org.glassfish.wasp.security.SecurityUtil; - -import jakarta.el.FunctionMapper; - /** * Maps EL functions to their Java method counterparts. Keeps the actual Method objects protected so that JSP pages * can't indirectly do reflection. @@ -61,12 +56,8 @@ private ProtectedFunctionMapper() { * @return A new protected function mapper. */ public static ProtectedFunctionMapper getInstance() { - ProtectedFunctionMapper funcMapper; - if (SecurityUtil.isPackageProtectionEnabled()) { - funcMapper = AccessController.doPrivileged((PrivilegedAction) ProtectedFunctionMapper::new); - } else { - funcMapper = new ProtectedFunctionMapper(); - } + ProtectedFunctionMapper funcMapper = new ProtectedFunctionMapper(); + funcMapper.fnmap = new java.util.HashMap<>(); return funcMapper; } @@ -82,18 +73,11 @@ public static ProtectedFunctionMapper getInstance() { */ public void mapFunction(String fnQName, final Class c, final String methodName, final Class[] args) { java.lang.reflect.Method method; - if (SecurityUtil.isPackageProtectionEnabled()) { - try { - method = AccessController.doPrivileged((PrivilegedExceptionAction) () -> c.getDeclaredMethod(methodName, args)); - } catch (PrivilegedActionException ex) { - throw new RuntimeException("Invalid function mapping - no such method: " + ex.getException().getMessage()); - } - } else { - try { - method = c.getDeclaredMethod(methodName, args); - } catch (NoSuchMethodException e) { - throw new RuntimeException("Invalid function mapping - no such method: " + e.getMessage()); - } + + try { + method = c.getDeclaredMethod(methodName, args); + } catch (NoSuchMethodException e) { + throw new RuntimeException("Invalid function mapping - no such method: " + e.getMessage()); } this.fnmap.put(fnQName, method); @@ -110,24 +94,15 @@ public void mapFunction(String fnQName, final Class c, final String methodNam * @throws RuntimeException if no method with the given signature could be found. */ public static ProtectedFunctionMapper getMapForFunction(String fnQName, final Class c, final String methodName, final Class[] args) { - java.lang.reflect.Method method; - ProtectedFunctionMapper funcMapper; - if (SecurityUtil.isPackageProtectionEnabled()) { - funcMapper = AccessController.doPrivileged((PrivilegedAction) ProtectedFunctionMapper::new); - - try { - method = AccessController.doPrivileged((PrivilegedExceptionAction) () -> c.getDeclaredMethod(methodName, args)); - } catch (PrivilegedActionException ex) { - throw new RuntimeException("Invalid function mapping - no such method: " + ex.getException().getMessage()); - } - } else { - funcMapper = new ProtectedFunctionMapper(); - try { - method = c.getDeclaredMethod(methodName, args); - } catch (NoSuchMethodException e) { - throw new RuntimeException("Invalid function mapping - no such method: " + e.getMessage()); - } + Method method; + ProtectedFunctionMapper funcMapper = new ProtectedFunctionMapper(); + + try { + method = c.getDeclaredMethod(methodName, args); + } catch (NoSuchMethodException e) { + throw new RuntimeException("Invalid function mapping - no such method: " + e.getMessage()); } + funcMapper.theMethod = method; return funcMapper; } diff --git a/src/main/java/org/glassfish/wasp/runtime/TagHandlerPool.java b/src/main/java/org/glassfish/wasp/runtime/TagHandlerPool.java index 24ddbc6..ef82ef2 100644 --- a/src/main/java/org/glassfish/wasp/runtime/TagHandlerPool.java +++ b/src/main/java/org/glassfish/wasp/runtime/TagHandlerPool.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,14 +18,14 @@ package org.glassfish.wasp.runtime; -import org.glassfish.jsp.api.ResourceInjector; -import org.glassfish.wasp.Constants; - import jakarta.servlet.ServletConfig; import jakarta.servlet.jsp.JspException; import jakarta.servlet.jsp.tagext.JspTag; import jakarta.servlet.jsp.tagext.Tag; +import org.glassfish.jsp.api.ResourceInjector; +import org.glassfish.wasp.Constants; + /** * Pool of tag handlers that can be reused. * @@ -47,8 +48,10 @@ public static TagHandlerPool getTagHandlerPool(ServletConfig config) { String tpClassName = getOption(config, OPTION_TAGPOOL, null); if (tpClassName != null) { try { - Class c = Class.forName(tpClassName).asSubclass(TagHandlerPool.class); - result = c.newInstance(); + result = Class.forName(tpClassName) + .asSubclass(TagHandlerPool.class) + .getDeclaredConstructor() + .newInstance(); } catch (Exception e) { e.printStackTrace(); result = null; @@ -124,7 +127,7 @@ public JspTag get(Class handlerClass) throws JspException if (resourceInjector != null) { tagHandler = resourceInjector.createTagHandlerInstance(handlerClass); } else { - tagHandler = handlerClass.newInstance(); + tagHandler = handlerClass.getDeclaredConstructor().newInstance(); } } catch (Exception e) { throw new JspException(e.getMessage(), e); diff --git a/src/main/java/org/glassfish/wasp/security/SecurityClassLoad.java b/src/main/java/org/glassfish/wasp/security/SecurityClassLoad.java deleted file mode 100644 index d7c79b1..0000000 --- a/src/main/java/org/glassfish/wasp/security/SecurityClassLoad.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. - * Copyright 2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.glassfish.wasp.security; - -import static java.util.Arrays.asList; -import static java.util.logging.Level.SEVERE; - -import java.util.List; -import java.util.logging.Logger; - -/** - * Static class used to preload java classes when using the Java SecurityManager so that the defineClassInPackage - * RuntimePermission does not trigger an AccessControlException. - * - * @author Jean-Francois Arcand - */ - -public final class SecurityClassLoad { - - private static Logger log = Logger.getLogger(SecurityClassLoad.class.getName()); - - public static void securityClassLoad(ClassLoader loader) { - if (System.getSecurityManager() == null) { - return; - } - - List classNames = asList( - "org.glassfish.wasp.runtime.JspFactoryImpl$PrivilegedGetPageContext", - "org.glassfish.wasp.runtime.JspFactoryImpl$PrivilegedReleasePageContext", - "org.glassfish.wasp.runtime.JspRuntimeLibrary", - "org.glassfish.wasp.runtime.ServletResponseWrapperInclude", - "org.glassfish.wasp.runtime.TagHandlerPool", - "org.glassfish.wasp.runtime.JspFragmentHelper", - "org.glassfish.wasp.runtime.ProtectedFunctionMapper", - "org.glassfish.wasp.runtime.PageContextImpl", - "org.glassfish.wasp.runtime.JspContextWrapper", - "org.glassfish.wasp.servlet.JspServletWrapper", - "org.glassfish.wasp.runtime.JspWriterImpl" - ); - - for (String className : classNames) { - try { - loader.loadClass(className); - } catch (ClassNotFoundException ex) { - log.log(SEVERE, "SecurityClassLoad", ex); - } - } - - } -} diff --git a/src/main/java/org/glassfish/wasp/security/SecurityUtil.java b/src/main/java/org/glassfish/wasp/security/SecurityUtil.java deleted file mode 100644 index 7cd5d12..0000000 --- a/src/main/java/org/glassfish/wasp/security/SecurityUtil.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. - * Copyright 2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.glassfish.wasp.security; - -import org.glassfish.wasp.Constants; - -/** - * Util class for Security related operations. - * - * @author Jean-Francois Arcand - */ - -public final class SecurityUtil { - - private static boolean packageDefinitionEnabled = System.getProperty("package.definition") == null ? false : true; - - /** - * Return the SecurityManager only if Security is enabled AND package protection mechanism is enabled. - */ - public static boolean isPackageProtectionEnabled() { - if (packageDefinitionEnabled && Constants.IS_SECURITY_ENABLED) { - return true; - } - return false; - } - -} diff --git a/src/main/java/org/glassfish/wasp/servlet/JspServletWrapper.java b/src/main/java/org/glassfish/wasp/servlet/JspServletWrapper.java index 3c82489..cb5e905 100644 --- a/src/main/java/org/glassfish/wasp/servlet/JspServletWrapper.java +++ b/src/main/java/org/glassfish/wasp/servlet/JspServletWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Contributors to Eclipse Foundation. + * Copyright (c) 2021, 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -18,9 +18,14 @@ package org.glassfish.wasp.servlet; -import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND; -import static jakarta.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; -import static java.util.logging.Level.SEVERE; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.UnavailableException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.jsp.tagext.TagInfo; import java.io.File; import java.io.FileNotFoundException; @@ -37,14 +42,9 @@ import org.glassfish.wasp.compiler.Localizer; import org.glassfish.wasp.runtime.JspSourceDependent; -import jakarta.servlet.Servlet; -import jakarta.servlet.ServletConfig; -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; -import jakarta.servlet.UnavailableException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.servlet.jsp.tagext.TagInfo; +import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND; +import static jakarta.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; +import static java.util.logging.Level.SEVERE; /** * The JSP engine (a.k.a WaSP). @@ -132,11 +132,9 @@ public Servlet getServlet() throws ServletException, IOException, ClassNotFoundE try { servletClass = ctxt.load(); - theServlet = (Servlet) servletClass.newInstance(); - } catch (IllegalAccessException ex1) { + theServlet = (Servlet) servletClass.getDeclaredConstructor().newInstance(); + } catch (ReflectiveOperationException ex1) { throw new WaspException(ex1); - } catch (InstantiationException ex) { - throw new WaspException(ex); } theServlet.init(config); @@ -240,7 +238,7 @@ public List getDependants() { if (reload) { tagHandlerClass = ctxt.load(); } - target = tagHandlerClass.newInstance(); + target = tagHandlerClass.getDeclaredConstructor().newInstance(); } else { target = getServlet(); } @@ -323,15 +321,15 @@ public void service(HttpServletRequest request, HttpServletResponse response, bo // Throw an exception as a response.sendError() will be ignored by the servlet engine. throw ex; } - + int unavailableSeconds = ex.getUnavailableSeconds(); if (unavailableSeconds <= 0) { unavailableSeconds = 60; // Arbitrary default } - + available = System.currentTimeMillis() + unavailableSeconds * 1000L; response.sendError(SC_SERVICE_UNAVAILABLE, ex.getMessage()); - + } catch (ServletException | IOException | IllegalStateException ex) { throw ex; } catch (Exception ex) { diff --git a/src/main/java/org/glassfish/wasp/servlet/WaspLoader.java b/src/main/java/org/glassfish/wasp/servlet/WaspLoader.java index f61691f..2364760 100644 --- a/src/main/java/org/glassfish/wasp/servlet/WaspLoader.java +++ b/src/main/java/org/glassfish/wasp/servlet/WaspLoader.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -21,15 +22,9 @@ import java.io.InputStream; import java.net.URL; import java.net.URLClassLoader; -import java.security.AccessController; -import java.security.CodeSource; -import java.security.PermissionCollection; -import java.security.PrivilegedAction; -import java.security.ProtectionDomain; import java.util.Map; import org.glassfish.wasp.Constants; -import org.glassfish.wasp.security.SecurityUtil; /** * Class loader for loading servlet class files (corresponding to JSP files) and tag handler class files (corresponding @@ -42,18 +37,12 @@ */ public class WaspLoader extends URLClassLoader { - private PermissionCollection permissionCollection; - private CodeSource codeSource; private ClassLoader parent; - private SecurityManager securityManager; private Map bytecodes; - public WaspLoader(URL[] urls, ClassLoader parent, PermissionCollection permissionCollection, CodeSource codeSource, Map bytecodes) { + public WaspLoader(URL[] urls, ClassLoader parent, Map bytecodes) { super(urls, parent); - this.permissionCollection = permissionCollection; - this.codeSource = codeSource; this.parent = parent; - this.securityManager = System.getSecurityManager(); this.bytecodes = bytecodes; } @@ -91,7 +80,6 @@ public Class loadClass(String name) throws ClassNotFoundException { */ @Override public synchronized Class loadClass(final String name, boolean resolve) throws ClassNotFoundException { - Class clazz; // (0) Check our previously loaded class cache @@ -103,23 +91,6 @@ public synchronized Class loadClass(final String name, boolean resolve) throw return clazz; } - // (.5) Permission to access this class when using a SecurityManager - if (securityManager != null) { - int dot = name.lastIndexOf('.'); - if (dot >= 0) { - try { - // Do not call the security manager since by default, we grant that package. - if (!"org.glassfish.wasp.runtime".equalsIgnoreCase(name.substring(0, dot))) { - securityManager.checkPackageAccess(name.substring(0, dot)); - } - } catch (SecurityException se) { - String error = "Security Violation, attempt to use " + "Restricted Class: " + name; - se.printStackTrace(); - throw new ClassNotFoundException(error); - } - } - } - if (!name.startsWith(Constants.JSP_PACKAGE_NAME)) { // Class is not in org.apache.jsp, therefore, have our parent load it clazz = parent.loadClass(name); @@ -132,7 +103,6 @@ public synchronized Class loadClass(final String name, boolean resolve) throw return findClass(name); } - // START OF IASRI 4709374 @Override public Class findClass(String className) throws ClassNotFoundException { @@ -149,17 +119,8 @@ public Class findClass(String className) throws ClassNotFoundException { } // Preprocess the loaded byte code - - Class clazz = null; - if (securityManager != null) { - ProtectionDomain pd = new ProtectionDomain(codeSource, permissionCollection); - clazz = defineClass(className, cdata, 0, cdata.length, pd); - } else { - clazz = defineClass(className, cdata, 0, cdata.length); - } - return clazz; + return defineClass(className, cdata, 0, cdata.length); } - // END OF IASRI 4709374 /* * Load JSP class data from file. @@ -167,13 +128,7 @@ public Class findClass(String className) throws ClassNotFoundException { private byte[] loadClassDataFromFile(final String fileName) { byte[] classBytes = null; try { - InputStream in = null; - - if (SecurityUtil.isPackageProtectionEnabled()) { - in = AccessController.doPrivileged((PrivilegedAction) () -> getResourceAsStream(fileName)); - } else { - in = getResourceAsStream(fileName); - } + InputStream in = getResourceAsStream(fileName); if (in == null) { return null; @@ -193,18 +148,4 @@ private byte[] loadClassDataFromFile(final String fileName) { } return classBytes; } - - /** - * Get the Permissions for a CodeSource. - * - * Since this ClassLoader is only used for a JSP page in a web application context, we just return our preset - * PermissionCollection for the web app context. - * - * @param codeSource Code source where the code was loaded from - * @return PermissionCollection for CodeSource - */ - @Override - public final PermissionCollection getPermissions(CodeSource codeSource) { - return permissionCollection; - } } diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ArraySuffix.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ArraySuffix.java index 5cbd75c..aada341 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ArraySuffix.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ArraySuffix.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -19,6 +20,7 @@ import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.List; import java.util.Map; @@ -106,7 +108,7 @@ public ArraySuffix(Expression pIndex) { * * Gets the value of the index **/ - Object evaluateIndex(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException { + Object evaluateIndex(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException { return mIndex.evaluate(pContext, pResolver, functions, defaultPrefix, pLogger); } @@ -137,11 +139,10 @@ public String getExpressionString() { * Evaluates the expression in the given context, operating on the given value. **/ @Override - public Object evaluate(Object pValue, Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException { + public Object evaluate(Object pValue, Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException { Object indexVal; String indexStr; BeanInfoProperty property; - BeanInfoIndexedProperty ixproperty; // Check for null value if (pValue == null) { diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/BeanInfoManager.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/BeanInfoManager.java index 86878a4..47ee92e 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/BeanInfoManager.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/BeanInfoManager.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * Copyright (c) 2020 Payara Services Ltd. @@ -77,7 +78,7 @@ public Class getBeanClass() { * * Constructor **/ - BeanInfoManager(Class pBeanClass) { + BeanInfoManager(Class pBeanClass) { mBeanClass = pBeanClass; } @@ -130,7 +131,7 @@ public static BeanInfoProperty getBeanInfoProperty(Class pClass, String pProp * * Returns the BeanInfoIndexedProperty for the specified property in the given class, or null if not found. **/ - public static BeanInfoIndexedProperty getBeanInfoIndexedProperty(Class pClass, String pIndexedPropertyName, Logger pLogger) + public static BeanInfoIndexedProperty getBeanInfoIndexedProperty(Class pClass, String pIndexedPropertyName, Logger pLogger) throws ELException { return getBeanInfoManager(pClass).getIndexedProperty(pIndexedPropertyName, pLogger); } @@ -272,19 +273,11 @@ static Method getPublicMethod(Method pMethod) { * If the given class is public and has a Method that declares the same name and arguments as the given method, then * that method is returned. Otherwise the superclass and interfaces are searched recursively. **/ - static Method getPublicMethod(Class pClass, Method pMethod) { + static Method getPublicMethod(Class pClass, Method pMethod) { // See if this is a public class declaring the method if (Modifier.isPublic(pClass.getModifiers())) { try { - Method m; - try { - m = pClass.getDeclaredMethod(pMethod.getName(), pMethod.getParameterTypes()); - } catch (java.security.AccessControlException ex) { - // kludge to accommodate J2EE RI's default settings - // TODO: see if we can simply replace - // getDeclaredMethod() with getMethod() ...? - m = pClass.getMethod(pMethod.getName(), pMethod.getParameterTypes()); - } + Method m = pClass.getDeclaredMethod(pMethod.getName(), pMethod.getParameterTypes()); if (Modifier.isPublic(m.getModifiers())) { return m; } @@ -294,9 +287,9 @@ static Method getPublicMethod(Class pClass, Method pMethod) { // Search the interfaces { - Class[] interfaces = pClass.getInterfaces(); + Class[] interfaces = pClass.getInterfaces(); if (interfaces != null) { - for (Class element : interfaces) { + for (Class element : interfaces) { Method m = getPublicMethod(element, pMethod); if (m != null) { return m; @@ -307,7 +300,7 @@ static Method getPublicMethod(Class pClass, Method pMethod) { // Search the superclass { - Class superclass = pClass.getSuperclass(); + Class superclass = pClass.getSuperclass(); if (superclass != null) { Method m = getPublicMethod(superclass, pMethod); if (m != null) { diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/BinaryOperatorExpression.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/BinaryOperatorExpression.java index 2224fa8..42a0d83 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/BinaryOperatorExpression.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/BinaryOperatorExpression.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * Copyright (c) 2020 Payara Services Ltd. @@ -18,6 +19,7 @@ package org.glassfish.wasp.taglibs.standard.lang.jstl; +import java.lang.reflect.Method; import java.util.List; import java.util.Map; @@ -115,7 +117,7 @@ public String getExpressionString() { * Evaluates to the literal value **/ @Override - public Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) + public Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException { Object value = mExpression.evaluate(pContext, pResolver, functions, defaultPrefix, pLogger); for (int i = 0; i < mOperators.size(); i++) { diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Coercions.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Coercions.java index 58cc6a1..af21fca 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Coercions.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Coercions.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * Copyright (c) 2020 Payara Services Ltd. @@ -240,7 +241,7 @@ public class Coercions { * * Coerces the given value to the specified class. **/ - public static Object coerce(Object pValue, Class pClass, Logger pLogger) throws ELException { + public static Object coerce(Object pValue, Class pClass, Logger pLogger) throws ELException { if (pClass == String.class) { return coerceToString(pValue, pLogger); } else if (isPrimitiveNumberClass(pClass)) { @@ -259,7 +260,7 @@ public static Object coerce(Object pValue, Class pClass, Logger pLogger) throws * * Returns true if the given class is Byte, Short, Integer, Long, Float, Double **/ - static boolean isPrimitiveNumberClass(Class pClass) { + static boolean isPrimitiveNumberClass(Class pClass) { return pClass == Byte.class || pClass == Byte.TYPE || pClass == Short.class || pClass == Short.TYPE || pClass == Integer.class || pClass == Integer.TYPE || pClass == Long.class || pClass == Long.TYPE || pClass == Float.class || pClass == Float.TYPE || pClass == Double.class || pClass == Double.TYPE; @@ -292,7 +293,7 @@ public static String coerceToString(Object pValue, Logger pLogger) throws ELExce * * Coerces a value to the given primitive number class **/ - public static Number coerceToPrimitiveNumber(Object pValue, Class pClass, Logger pLogger) throws ELException { + public static Number coerceToPrimitiveNumber(Object pValue, Class pClass, Logger pLogger) throws ELException { if (pValue == null || "".equals(pValue)) { return coerceToPrimitiveNumber(0, pClass); } else if (pValue instanceof Character) { @@ -365,7 +366,7 @@ public static Integer coerceToInteger(Object pValue, Logger pLogger) throws ELEx * * Coerces a long to the given primitive number class **/ - static Number coerceToPrimitiveNumber(long pValue, Class pClass) throws ELException { + static Number coerceToPrimitiveNumber(long pValue, Class pClass) throws ELException { if (pClass == Byte.class || pClass == Byte.TYPE) { return PrimitiveObjects.getByte((byte) pValue); } else if (pClass == Short.class || pClass == Short.TYPE) { @@ -388,7 +389,7 @@ static Number coerceToPrimitiveNumber(long pValue, Class pClass) throws ELExcept * * Coerces a double to the given primitive number class **/ - static Number coerceToPrimitiveNumber(double pValue, Class pClass) throws ELException { + static Number coerceToPrimitiveNumber(double pValue, Class pClass) throws ELException { if (pClass == Byte.class || pClass == Byte.TYPE) { return PrimitiveObjects.getByte((byte) pValue); } else if (pClass == Short.class || pClass == Short.TYPE) { @@ -411,7 +412,7 @@ static Number coerceToPrimitiveNumber(double pValue, Class pClass) throws ELExce * * Coerces a Number to the given primitive number class **/ - static Number coerceToPrimitiveNumber(Number pValue, Class pClass) throws ELException { + static Number coerceToPrimitiveNumber(Number pValue, Class pClass) throws ELException { if (pClass == Byte.class || pClass == Byte.TYPE) { return PrimitiveObjects.getByte(pValue.byteValue()); } else if (pClass == Short.class || pClass == Short.TYPE) { @@ -434,7 +435,7 @@ static Number coerceToPrimitiveNumber(Number pValue, Class pClass) throws ELExce * * Coerces a String to the given primitive number class **/ - static Number coerceToPrimitiveNumber(String pValue, Class pClass) throws ELException { + static Number coerceToPrimitiveNumber(String pValue, Class pClass) throws ELException { if (pClass == Byte.class || pClass == Byte.TYPE) { return Byte.valueOf(pValue); } else if (pClass == Short.class || pClass == Short.TYPE) { @@ -607,9 +608,10 @@ else if (pLeft instanceof String || pRight instanceof String) { return PrimitiveObjects.getBoolean(pOperator.apply(left, right, pLogger)); } - else if (pLeft instanceof Comparable) { + else if (pLeft instanceof Comparable comparable) { try { - int result = ((Comparable) pLeft).compareTo(pRight); + @SuppressWarnings("unchecked") + int result = comparable.compareTo(pRight); return PrimitiveObjects.getBoolean(pOperator.apply(result, -result, pLogger)); } catch (Exception exc) { if (pLogger.isLoggingError()) { @@ -620,9 +622,10 @@ else if (pLeft instanceof Comparable) { } } - else if (pRight instanceof Comparable) { + else if (pRight instanceof Comparable comparable) { try { - int result = ((Comparable) pRight).compareTo(pLeft); + @SuppressWarnings("unchecked") + int result = comparable.compareTo(pLeft); return PrimitiveObjects.getBoolean(pOperator.apply(-result, result, pLogger)); } catch (Exception exc) { if (pLogger.isLoggingError()) { @@ -707,7 +710,7 @@ public static boolean isFloatingPointType(Object pObject) { * * Returns true if the given class is of a floating point type **/ - public static boolean isFloatingPointType(Class pClass) { + public static boolean isFloatingPointType(Class pClass) { return pClass == Float.class || pClass == Float.TYPE || pClass == Double.class || pClass == Double.TYPE; } @@ -746,7 +749,7 @@ public static boolean isIntegerType(Object pObject) { * * Returns true if the given class is of an integer type **/ - public static boolean isIntegerType(Class pClass) { + public static boolean isIntegerType(Class pClass) { return pClass == Byte.class || pClass == Byte.TYPE || pClass == Short.class || pClass == Short.TYPE || pClass == Character.class || pClass == Character.TYPE || pClass == Integer.class || pClass == Integer.TYPE || pClass == Long.class || pClass == Long.TYPE; diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ComplexValue.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ComplexValue.java index c1c7409..34caaab 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ComplexValue.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ComplexValue.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * Copyright (c) 2020 Payara Services Ltd. @@ -18,6 +19,7 @@ package org.glassfish.wasp.taglibs.standard.lang.jstl; +import java.lang.reflect.Method; import java.util.List; import java.util.Map; @@ -97,7 +99,7 @@ public String getExpressionString() { * Evaluates by evaluating the prefix, then applying the suffixes **/ @Override - public Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) + public Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException { Object ret = mPrefix.evaluate(pContext, pResolver, functions, defaultPrefix, pLogger); diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ELEvaluator.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ELEvaluator.java index 3e42f98..a996972 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ELEvaluator.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ELEvaluator.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * Copyright (c) 2020 Payara Services Ltd. @@ -20,6 +21,7 @@ import java.io.Reader; import java.io.StringReader; +import java.lang.reflect.Method; import java.text.MessageFormat; import java.util.Collections; import java.util.HashMap; @@ -86,7 +88,7 @@ public class ELEvaluator { /** * The mapping from ExpectedType to Maps mapping literal String to parsed value **/ - static Map sCachedExpectedTypes = new HashMap<>(); + static Map, Map> sCachedExpectedTypes = new HashMap<>(); /** The static Logger **/ static Logger sLogger = new Logger(System.out); @@ -134,7 +136,7 @@ public ELEvaluator(VariableResolver pResolver, boolean pBypassCache) { * @param pExpectedType the type to which the evaluated expression should be coerced * @return the expression String evaluated to the given expected type **/ - public Object evaluate(String pExpressionString, Object pContext, Class pExpectedType, Map functions, String defaultPrefix) + public Object evaluate(String pExpressionString, Object pContext, Class pExpectedType, Map functions, String defaultPrefix) throws ELException { return evaluate(pExpressionString, pContext, pExpectedType, functions, defaultPrefix, sLogger); } @@ -144,7 +146,7 @@ public Object evaluate(String pExpressionString, Object pContext, Class pExpecte * * Evaluates the given expression string **/ - Object evaluate(String pExpressionString, Object pContext, Class pExpectedType, Map functions, String defaultPrefix, Logger pLogger) + Object evaluate(String pExpressionString, Object pContext, Class pExpectedType, Map functions, String defaultPrefix, Logger pLogger) throws ELException { // Check for null expression strings if (pExpressionString == null) { @@ -155,28 +157,25 @@ Object evaluate(String pExpressionString, Object pContext, Class pExpectedType, Object parsedValue = parseExpressionString(pExpressionString); // Evaluate differently based on the parsed type - if (parsedValue instanceof String) { + if (parsedValue instanceof String stringValue) { // Convert the String, and cache the conversion - String strValue = (String) parsedValue; - return convertStaticValueToExpectedType(strValue, pExpectedType, pLogger); + return convertStaticValueToExpectedType(stringValue, pExpectedType, pLogger); } - else if (parsedValue instanceof Expression) { + if (parsedValue instanceof Expression expression) { // Evaluate the expression and convert - Object value = ((Expression) parsedValue).evaluate(pContext, mResolver, functions, defaultPrefix, pLogger); + Object value = expression.evaluate(pContext, mResolver, functions, defaultPrefix, pLogger); return convertToExpectedType(value, pExpectedType, pLogger); } - else if (parsedValue instanceof ExpressionString) { + if (parsedValue instanceof ExpressionString expressionString) { // Evaluate the expression/string list and convert - String strValue = ((ExpressionString) parsedValue).evaluate(pContext, mResolver, functions, defaultPrefix, pLogger); + String strValue = expressionString.evaluate(pContext, mResolver, functions, defaultPrefix, pLogger); return convertToExpectedType(strValue, pExpectedType, pLogger); } - else { - // This should never be reached - return null; - } + // This should never be reached + return null; } // ------------------------------------- @@ -220,7 +219,7 @@ public Object parseExpressionString(String pExpressionString) throws ELException * * Converts the given value to the specified expected type. **/ - Object convertToExpectedType(Object pValue, Class pExpectedType, Logger pLogger) throws ELException { + Object convertToExpectedType(Object pValue, Class pExpectedType, Logger pLogger) throws ELException { return Coercions.coerce(pValue, pExpectedType, pLogger); } @@ -230,22 +229,23 @@ Object convertToExpectedType(Object pValue, Class pExpectedType, Logger pLogger) * Converts the given String, specified as a static expression string, to the given expected type. The conversion is * cached. **/ - Object convertStaticValueToExpectedType(String pValue, Class pExpectedType, Logger pLogger) throws ELException { + Object convertStaticValueToExpectedType(String pValue, Class pExpectedType, Logger pLogger) throws ELException { // See if the value is already of the expected type if (pExpectedType == String.class || pExpectedType == Object.class) { return pValue; } // Find the cached value - Map valueByString = getOrCreateExpectedTypeMap(pExpectedType); + Map valueByString = getOrCreateExpectedTypeMap(pExpectedType); if (!mBypassCache && valueByString.containsKey(pValue)) { return valueByString.get(pValue); - } else { - // Convert from a String - Object ret = Coercions.coerce(pValue, pExpectedType, pLogger); - valueByString.put(pValue, ret); - return ret; } + + // Convert from a String + Object ret = Coercions.coerce(pValue, pExpectedType, pLogger); + valueByString.put(pValue, ret); + + return ret; } // ------------------------------------- @@ -253,9 +253,9 @@ Object convertStaticValueToExpectedType(String pValue, Class pExpectedType, Logg * * Creates or returns the Map that maps string literals to parsed values for the specified expected type. **/ - static Map getOrCreateExpectedTypeMap(Class pExpectedType) { + static Map getOrCreateExpectedTypeMap(Class pExpectedType) { synchronized (sCachedExpectedTypes) { - Map ret = sCachedExpectedTypes.get(pExpectedType); + Map ret = sCachedExpectedTypes.get(pExpectedType); if (ret == null) { ret = Collections.synchronizedMap(new HashMap<>()); sCachedExpectedTypes.put(pExpectedType, ret); diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Evaluator.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Evaluator.java index 6a63aea..c36b2bb 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Evaluator.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Evaluator.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,6 +18,7 @@ package org.glassfish.wasp.taglibs.standard.lang.jstl; +import java.lang.reflect.Method; import java.text.MessageFormat; import java.util.Map; @@ -74,8 +76,8 @@ public String validate(String pAttributeName, String pAttributeValue) { * * Evaluates the expression at request time **/ - public Object evaluate(String pAttributeName, String pAttributeValue, Class pExpectedType, Tag pTag, PageContext pPageContext, - Map functions, String defaultPrefix) throws JspException { + public Object evaluate(String pAttributeName, String pAttributeValue, Class pExpectedType, Tag pTag, PageContext pPageContext, + Map functions, String defaultPrefix) throws JspException { try { return sEvaluator.evaluate(pAttributeValue, pPageContext, pExpectedType, functions, defaultPrefix); } catch (ELException exc) { @@ -88,7 +90,7 @@ public Object evaluate(String pAttributeName, String pAttributeValue, Class pExp /** Conduit to old-style call for convenience. */ @Override - public Object evaluate(String pAttributeName, String pAttributeValue, Class pExpectedType, Tag pTag, PageContext pPageContext) + public Object evaluate(String pAttributeName, String pAttributeValue, Class pExpectedType, Tag pTag, PageContext pPageContext) throws JspException { return evaluate(pAttributeName, pAttributeValue, pExpectedType, pTag, pPageContext, null, null); } diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Expression.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Expression.java index 6e294fc..c77dce3 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Expression.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Expression.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,6 +18,7 @@ package org.glassfish.wasp.taglibs.standard.lang.jstl; +import java.lang.reflect.Method; import java.util.Map; /** @@ -46,7 +48,7 @@ public abstract class Expression { * * Evaluates the expression in the given context **/ - public abstract Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) + public abstract Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException; // ------------------------------------- diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ExpressionString.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ExpressionString.java index 3fc2887..735999f 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ExpressionString.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ExpressionString.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * Copyright (c) 2020 Payara Services Ltd. @@ -18,6 +19,7 @@ package org.glassfish.wasp.taglibs.standard.lang.jstl; +import java.lang.reflect.Method; import java.util.Map; /** @@ -61,14 +63,14 @@ public ExpressionString(Object[] pElements) { * Evaluates the expression string by evaluating each element, converting it to a String (using toString, or "" for null * values) and concatenating the results into a single String. **/ - public String evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) + public String evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException { StringBuilder buf = new StringBuilder(); for (Object elem : mElements) { if (elem instanceof String) { buf.append((String) elem); - } else if (elem instanceof Expression) { - Object val = ((Expression) elem).evaluate(pContext, pResolver, functions, defaultPrefix, pLogger); + } else if (elem instanceof Expression expression) { + Object val = expression.evaluate(pContext, pResolver, functions, defaultPrefix, pLogger); if (val != null) { buf.append(val.toString()); } diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/FloatingPointLiteral.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/FloatingPointLiteral.java index 9517fcb..52b75bb 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/FloatingPointLiteral.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/FloatingPointLiteral.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -42,7 +43,7 @@ public FloatingPointLiteral(String pToken) { * Parses the given token into the literal value **/ static Object getValueFromToken(String pToken) { - return new Double(pToken); + return Double.parseDouble(pToken); } // ------------------------------------- diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/FunctionInvocation.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/FunctionInvocation.java index beca1c6..f8971f1 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/FunctionInvocation.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/FunctionInvocation.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * Copyright (c) 2020 Payara Services Ltd. @@ -95,7 +96,7 @@ public String getExpressionString() { * Evaluates by looking up the name in the VariableResolver **/ @Override - public Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) + public Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException { // if the Map is null, then the function is invalid @@ -113,13 +114,13 @@ public Object evaluate(Object pContext, VariableResolver pResolver, Map function } // ensure that the function's name is mapped - Method target = (Method) functions.get(functionName); + Method target = functions.get(functionName); if (target == null) { pLogger.logError(Constants.UNKNOWN_FUNCTION, functionName); } // ensure that the number of arguments matches the number of parameters - Class[] params = target.getParameterTypes(); + Class[] params = target.getParameterTypes(); if (params.length != argumentList.size()) { pLogger.logError(Constants.INAPPROPRIATE_FUNCTION_ARG_COUNT, Integer.valueOf(params.length), Integer.valueOf(argumentList.size())); diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Literal.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Literal.java index c9ed328..96479fe 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Literal.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/Literal.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,6 +18,7 @@ package org.glassfish.wasp.taglibs.standard.lang.jstl; +import java.lang.reflect.Method; import java.util.Map; /** @@ -62,7 +64,7 @@ public Literal(Object pValue) { * Evaluates to the literal value **/ @Override - public Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) + public Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException { return mValue; } diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/NamedValue.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/NamedValue.java index 1225f1e..db987e8 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/NamedValue.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/NamedValue.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,6 +18,7 @@ package org.glassfish.wasp.taglibs.standard.lang.jstl; +import java.lang.reflect.Method; import java.util.Map; /** @@ -72,13 +74,12 @@ public String getExpressionString() { * Evaluates by looking up the name in the VariableResolver **/ @Override - public Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) - throws ELException { + public Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException { if (pResolver == null) { return null; - } else { - return pResolver.resolveVariable(mName, pContext); } + + return pResolver.resolveVariable(mName, pContext); } // ------------------------------------- diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/PropertySuffix.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/PropertySuffix.java index 91f60f6..87319e9 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/PropertySuffix.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/PropertySuffix.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,6 +18,7 @@ package org.glassfish.wasp.taglibs.standard.lang.jstl; +import java.lang.reflect.Method; import java.util.Map; /** @@ -62,7 +64,7 @@ public PropertySuffix(String pName) { * Gets the value of the index **/ @Override - Object evaluateIndex(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) + Object evaluateIndex(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException { return mName; } diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/UnaryOperatorExpression.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/UnaryOperatorExpression.java index 5bfbc2f..0d36c7b 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/UnaryOperatorExpression.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/UnaryOperatorExpression.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * Copyright (c) 2020 Payara Services Ltd. @@ -18,6 +19,7 @@ package org.glassfish.wasp.taglibs.standard.lang.jstl; +import java.lang.reflect.Method; import java.util.List; import java.util.Map; @@ -117,7 +119,7 @@ public String getExpressionString() { * Evaluates to the literal value **/ @Override - public Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) + public Object evaluate(Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException { Object value = mExpression.evaluate(pContext, pResolver, functions, defaultPrefix, pLogger); if (mOperator != null) { @@ -128,6 +130,7 @@ public Object evaluate(Object pContext, VariableResolver pResolver, Map function value = operator.apply(value, pContext, pLogger); } } + return value; } diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ValueSuffix.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ValueSuffix.java index 2f76501..a9729a9 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ValueSuffix.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/jstl/ValueSuffix.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,6 +18,7 @@ package org.glassfish.wasp.taglibs.standard.lang.jstl; +import java.lang.reflect.Method; import java.util.Map; /** @@ -43,7 +45,7 @@ public abstract class ValueSuffix { * * Evaluates the expression in the given context, operating on the given value. **/ - public abstract Object evaluate(Object pValue, Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, + public abstract Object evaluate(Object pValue, Object pContext, VariableResolver pResolver, Map functions, String defaultPrefix, Logger pLogger) throws ELException; // ------------------------------------- diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/support/ExpressionEvaluator.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/support/ExpressionEvaluator.java index 8523b82..cb33164 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/support/ExpressionEvaluator.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/support/ExpressionEvaluator.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -48,11 +49,10 @@ public interface ExpressionEvaluator { * Translation time validation of an expression. This method will return a null String if the expression is valid; * otherwise an error message. */ - public String validate(String attributeName, String expression); + String validate(String attributeName, String expression); /** * Evaluates the expression at request time. */ - public Object evaluate(String attributeName, String expression, Class expectedType, Tag tag, PageContext pageContext) - throws JspException; + Object evaluate(String attributeName, String expression, Class expectedType, Tag tag, PageContext pageContext) throws JspException; } diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/support/ExpressionEvaluatorManager.java b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/support/ExpressionEvaluatorManager.java index eacd757..ac41cff 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/lang/support/ExpressionEvaluatorManager.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/lang/support/ExpressionEvaluatorManager.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * Copyright (c) 2020 Payara Services Ltd. @@ -18,16 +19,16 @@ package org.glassfish.wasp.taglibs.standard.lang.support; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.Tag; + import java.util.HashMap; import org.glassfish.wasp.taglibs.standard.lang.jstl.Coercions; import org.glassfish.wasp.taglibs.standard.lang.jstl.ELException; import org.glassfish.wasp.taglibs.standard.lang.jstl.Logger; -import jakarta.servlet.jsp.JspException; -import jakarta.servlet.jsp.PageContext; -import jakarta.servlet.jsp.tagext.Tag; - /** *

* A conduit to the JSTL EL. Based on... @@ -62,7 +63,7 @@ public class ExpressionEvaluatorManager { /** * Invokes the evaluate() method on the "active" ExpressionEvaluator for the given pageContext. */ - public static Object evaluate(String attributeName, String expression, Class expectedType, Tag tag, PageContext pageContext) + public static Object evaluate(String attributeName, String expression, Class expectedType, Tag tag, PageContext pageContext) throws JspException { // the evaluator we'll use @@ -75,7 +76,7 @@ public static Object evaluate(String attributeName, String expression, Class exp /** * Invokes the evaluate() method on the "active" ExpressionEvaluator for the given pageContext. */ - public static Object evaluate(String attributeName, String expression, Class expectedType, PageContext pageContext) + public static Object evaluate(String attributeName, String expression, Class expectedType, PageContext pageContext) throws JspException { // the evaluator we'll use @@ -101,7 +102,7 @@ public static ExpressionEvaluator getEvaluatorByName(String name) throws JspExce if (oEvaluator != null) { return ((ExpressionEvaluator) oEvaluator); } - ExpressionEvaluator e = (ExpressionEvaluator) Class.forName(name).newInstance(); + ExpressionEvaluator e = (ExpressionEvaluator) Class.forName(name).getDeclaredConstructor().newInstance(); nameMap.put(name, e); return (e); } @@ -112,7 +113,7 @@ public static ExpressionEvaluator getEvaluatorByName(String name) throws JspExce throw new JspException("couldn't find ExpressionEvaluator: " + ex.toString(), ex); } catch (IllegalAccessException ex) { throw new JspException("couldn't access ExpressionEvaluator: " + ex.toString(), ex); - } catch (InstantiationException ex) { + } catch (ReflectiveOperationException ex) { throw new JspException("couldn't instantiate ExpressionEvaluator: " + ex.toString(), ex); } } diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/core/ForEachSupport.java b/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/core/ForEachSupport.java index f2dc6ef..6046dfb 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/core/ForEachSupport.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/core/ForEachSupport.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,6 +18,10 @@ package org.glassfish.wasp.taglibs.standard.tag.common.core; +import jakarta.el.ValueExpression; +import jakarta.servlet.jsp.JspTagException; +import jakarta.servlet.jsp.jstl.core.LoopTagSupport; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -27,10 +32,6 @@ import org.glassfish.wasp.taglibs.standard.resources.Resources; -import jakarta.el.ValueExpression; -import jakarta.servlet.jsp.JspTagException; -import jakarta.servlet.jsp.jstl.core.LoopTagSupport; - /** *

* Support for tag handlers for <forEach>, the core iteration tag in JSTL 1.0. This class extends LoopTagSupport @@ -67,6 +68,8 @@ public abstract class ForEachSupport extends LoopTagSupport { // ********************************************************************* // Internal, supporting classes and interfaces + private static final long serialVersionUID = -2094020134956069089L; + /* * Acts as a focal point for converting the various types we support. It would have been ideal to use Iterator here * except for one problem: Iterator.hasNext() and Iterator.next() can't throw the JspTagException we want to throw. So @@ -88,9 +91,9 @@ protected static interface ForEachIterator { * and next() don't need to throw JspTagException. Such cases are common.core. */ protected class SimpleForEachIterator implements ForEachIterator { - private Iterator i; + private Iterator i; - public SimpleForEachIterator(Iterator i) { + public SimpleForEachIterator(Iterator i) { this.i = i; } @@ -132,12 +135,12 @@ protected void prepare() throws JspTagException { if (rawItems != null) { // If this is a deferred expression, make a note and get // the 'items' instance. - if (rawItems instanceof ValueExpression) { - deferredExpression = (ValueExpression) rawItems; + if (rawItems instanceof ValueExpression valueExpression) { + deferredExpression = valueExpression; rawItems = deferredExpression.getValue(pageContext.getELContext()); if (rawItems == null) { // Simulate an empty list - rawItems = new ArrayList(); + rawItems = new ArrayList<>(); } } // extract an iterator over the 'items' we've got @@ -201,16 +204,16 @@ protected ForEachIterator supportedTypeForEachIterator(Object o) throws JspTagEx items = toForEachIterator((float[]) o); } else if (o instanceof double[]) { items = toForEachIterator((double[]) o); - } else if (o instanceof Collection) { - items = toForEachIterator((Collection) o); - } else if (o instanceof Iterator) { - items = toForEachIterator((Iterator) o); - } else if (o instanceof Enumeration) { - items = toForEachIterator((Enumeration) o); - } else if (o instanceof Map) { - items = toForEachIterator((Map) o); - } else if (o instanceof String) { - items = toForEachIterator((String) o); + } else if (o instanceof Collection collection) { + items = toForEachIterator(collection); + } else if (o instanceof Iterator iterator) { + items = toForEachIterator(iterator); + } else if (o instanceof Enumeration enumeration) { + items = toForEachIterator(enumeration); + } else if (o instanceof Map map) { + items = toForEachIterator(map); + } else if (o instanceof String string) { + items = toForEachIterator(string); } else { items = toForEachIterator(o); } @@ -309,7 +312,7 @@ protected ForEachIterator toForEachIterator(long[] a) { protected ForEachIterator toForEachIterator(float[] a) { Float[] wrapped = new Float[a.length]; for (int i = 0; i < a.length; i++) { - wrapped[i] = new Float(a[i]); + wrapped[i] = Float.valueOf(a[i]); } return new SimpleForEachIterator(Arrays.asList(wrapped).iterator()); } @@ -318,7 +321,7 @@ protected ForEachIterator toForEachIterator(float[] a) { protected ForEachIterator toForEachIterator(double[] a) { Double[] wrapped = new Double[a.length]; for (int i = 0; i < a.length; i++) { - wrapped[i] = new Double(a[i]); + wrapped[i] = Double.valueOf(a[i]); } return new SimpleForEachIterator(Arrays.asList(wrapped).iterator()); } diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/core/SetSupport.java b/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/core/SetSupport.java index 6f62acd..409e829 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/core/SetSupport.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/core/SetSupport.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,15 +18,6 @@ package org.glassfish.wasp.taglibs.standard.tag.common.core; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Map; - -import org.glassfish.wasp.taglibs.standard.resources.Resources; - import jakarta.el.ExpressionFactory; import jakarta.el.ValueExpression; import jakarta.el.VariableMapper; @@ -36,6 +28,15 @@ import jakarta.servlet.jsp.PageContext; import jakarta.servlet.jsp.tagext.BodyTagSupport; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; + +import org.glassfish.wasp.taglibs.standard.resources.Resources; + /** *

* Support for handlers of the <set> tag. @@ -48,6 +49,7 @@ public class SetSupport extends BodyTagSupport { // ********************************************************************* // Internal state + private static final long serialVersionUID = -4884188197847179830L; protected Object value; // tag attribute protected boolean valueSpecified; // status protected Object target; // tag attribute @@ -85,6 +87,7 @@ public void release() { // ********************************************************************* // Tag logic + @SuppressWarnings("unchecked") @Override public int doEndTag() throws JspException { @@ -151,12 +154,12 @@ public int doEndTag() throws JspException { } else if (target != null) { // save the result to target.property - if (target instanceof Map) { + if (target instanceof Map mapEntry) { // ... treating it as a Map entry if (result == null) { - ((Map) target).remove(property); + mapEntry.remove(property); } else { - ((Map) target).put(property, result); + mapEntry.put(property, result); } } else { // ... treating it as a bean property @@ -203,7 +206,7 @@ public int doEndTag() throws JspException { /** * Convert an object to an expected type according to the conversion rules of the Expression Language. */ - private Object convertToExpectedType(final Object value, Class expectedType) { + private Object convertToExpectedType(final Object value, Class expectedType) { JspFactory jspFactory = JspFactory.getDefaultFactory(); JspApplicationContext jspAppContext = jspFactory.getJspApplicationContext(pageContext.getServletContext()); diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/fmt/FormatNumberSupport.java b/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/fmt/FormatNumberSupport.java index b846fbd..bdccfb7 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/fmt/FormatNumberSupport.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/fmt/FormatNumberSupport.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997-2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * Copyright (c) 2020 Payara Services Ltd. @@ -18,21 +19,21 @@ package org.glassfish.wasp.taglibs.standard.tag.common.fmt; +import jakarta.servlet.jsp.JspException; +import jakarta.servlet.jsp.JspTagException; +import jakarta.servlet.jsp.PageContext; +import jakarta.servlet.jsp.tagext.BodyTagSupport; + import java.io.IOException; -import java.lang.reflect.Method; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; +import java.util.Currency; import java.util.Locale; import org.glassfish.wasp.taglibs.standard.resources.Resources; import org.glassfish.wasp.taglibs.standard.tag.common.core.Util; -import jakarta.servlet.jsp.JspException; -import jakarta.servlet.jsp.JspTagException; -import jakarta.servlet.jsp.PageContext; -import jakarta.servlet.jsp.tagext.BodyTagSupport; - /** * Support for tag handlers for <formatNumber>, the number formatting tag in JSTL 1.0. * @@ -44,7 +45,7 @@ public abstract class FormatNumberSupport extends BodyTagSupport { // ********************************************************************* // Private constants - private static final Class[] GET_INSTANCE_PARAM_TYPES = new Class[] { String.class }; + private static final long serialVersionUID = 1021830879024348617L; private static final String NUMBER = "number"; private static final String CURRENCY = "currency"; private static final String PERCENT = "percent"; @@ -74,19 +75,11 @@ public abstract class FormatNumberSupport extends BodyTagSupport { private String var; // 'var' attribute private int scope; // 'scope' attribute - private static Class currencyClass; + private static Class currencyClass = Currency.class; // ********************************************************************* // Constructor and initialization - static { - try { - currencyClass = Class.forName("java.util.Currency"); - // container's runtime is J2SE 1.4 or greater - } catch (Exception cnfe) { - } - } - public FormatNumberSupport() { super(); init(); @@ -289,24 +282,7 @@ private void setCurrency(NumberFormat formatter) throws Exception { } if (code != null) { - Object[] methodArgs = new Object[1]; - - /* - * java.util.Currency.getInstance() - */ - Method m = currencyClass.getMethod("getInstance", GET_INSTANCE_PARAM_TYPES); - methodArgs[0] = code; - Object currency = m.invoke(null, methodArgs); - - /* - * java.text.NumberFormat.setCurrency() - */ - Class[] paramTypes = new Class[1]; - paramTypes[0] = currencyClass; - Class numberFormatClass = Class.forName("java.text.NumberFormat"); - m = numberFormatClass.getMethod("setCurrency", paramTypes); - methodArgs[0] = currency; - m.invoke(formatter, methodArgs); + formatter.setCurrency(Currency.getInstance(code)); } else { /* * Let potential ClassCastException propagate up (will almost never happen) diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/sql/DataSourceWrapper.java b/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/sql/DataSourceWrapper.java index 330ea56..7b8f43e 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/sql/DataSourceWrapper.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/sql/DataSourceWrapper.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -42,11 +43,14 @@ public class DataSourceWrapper implements DataSource { private String userName; private String password; - public void setDriverClassName(String driverClassName) throws ClassNotFoundException, InstantiationException, IllegalAccessException { + public void setDriverClassName(String driverClassName) throws ReflectiveOperationException { + Object instance = Class.forName(driverClassName, true, Thread.currentThread() + .getContextClassLoader()) + .getDeclaredConstructor() + .newInstance(); - Object instance = Class.forName(driverClassName, true, Thread.currentThread().getContextClassLoader()).newInstance(); - if (instance instanceof Driver) { - driver = (Driver) instance; + if (instance instanceof Driver driverInstance) { + driver = driverInstance; } } diff --git a/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/xml/ParseSupport.java b/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/xml/ParseSupport.java index 5483071..83672f1 100644 --- a/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/xml/ParseSupport.java +++ b/src/main/java/org/glassfish/wasp/taglibs/standard/tag/common/xml/ParseSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation * Copyright (c) 1997-2020 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -61,6 +61,7 @@ public abstract class ParseSupport extends BodyTagSupport { // ********************************************************************* // Protected state + private static final long serialVersionUID = -7207472308673504103L; protected Object xml; // 'xml' attribute protected String systemId; // 'systemId' attribute protected XMLFilter filter; // 'filter' attribute diff --git a/src/main/java/org/glassfish/wasp/xmlparser/ParserUtils.java b/src/main/java/org/glassfish/wasp/xmlparser/ParserUtils.java index 77ffad3..a35aa95 100755 --- a/src/main/java/org/glassfish/wasp/xmlparser/ParserUtils.java +++ b/src/main/java/org/glassfish/wasp/xmlparser/ParserUtils.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Contributors to Eclipse Foundation. * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. * Copyright 2004 The Apache Software Foundation * @@ -17,10 +18,6 @@ package org.glassfish.wasp.xmlparser; -import static java.util.logging.Level.FINE; -import static org.glassfish.wasp.xmlparser.ParserUtils.CACHED_DTD_PUBLIC_IDS; -import static org.glassfish.wasp.xmlparser.ParserUtils.CACHED_DTD_RESOURCE_PATHS; - import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -29,7 +26,6 @@ import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLEncoder; -import java.security.AccessController; import java.util.HashMap; import java.util.StringTokenizer; import java.util.logging.Logger; @@ -46,8 +42,6 @@ import org.glassfish.wasp.Constants; import org.glassfish.wasp.WaspException; import org.glassfish.wasp.compiler.Localizer; -import org.glassfish.wasp.security.PrivilegedGetTccl; -import org.glassfish.wasp.security.PrivilegedSetTccl; import org.w3c.dom.Comment; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -63,6 +57,10 @@ import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; +import static java.util.logging.Level.FINE; +import static org.glassfish.wasp.xmlparser.ParserUtils.CACHED_DTD_PUBLIC_IDS; +import static org.glassfish.wasp.xmlparser.ParserUtils.CACHED_DTD_RESOURCE_PATHS; + /** * XML parsing utilities for processing web application deployment descriptor and tag library descriptor files. FIXME - * make these use a separate class loader for the parser to be used. @@ -101,26 +99,26 @@ public class ParserUtils { * List of the Public IDs that we cache, and their associated location. This is used by an EntityResolver to return the * location of the cached copy of a DTD. */ - static final String[] CACHED_DTD_PUBLIC_IDS = { - Constants.TAGLIB_DTD_PUBLIC_ID_11, - Constants.TAGLIB_DTD_PUBLIC_ID_12, + static final String[] CACHED_DTD_PUBLIC_IDS = { + Constants.TAGLIB_DTD_PUBLIC_ID_11, + Constants.TAGLIB_DTD_PUBLIC_ID_12, Constants.WEBAPP_DTD_PUBLIC_ID_22, Constants.WEBAPP_DTD_PUBLIC_ID_23, }; // START PWC 6386258 private static final String[] DEFAULT_DTD_RESOURCE_PATHS = { - Constants.TAGLIB_DTD_RESOURCE_PATH_11, + Constants.TAGLIB_DTD_RESOURCE_PATH_11, Constants.TAGLIB_DTD_RESOURCE_PATH_12, - Constants.WEBAPP_DTD_RESOURCE_PATH_22, + Constants.WEBAPP_DTD_RESOURCE_PATH_22, Constants.WEBAPP_DTD_RESOURCE_PATH_23, }; static final String[] CACHED_DTD_RESOURCE_PATHS = DEFAULT_DTD_RESOURCE_PATHS; - + private static final String[] DEFAULT_SCHEMA_RESOURCE_PATHS = { // not actually used it seems - Constants.TAGLIB_SCHEMA_RESOURCE_PATH_20, + Constants.TAGLIB_SCHEMA_RESOURCE_PATH_20, Constants.TAGLIB_SCHEMA_RESOURCE_PATH_21, - Constants.WEBAPP_SCHEMA_RESOURCE_PATH_24, + Constants.WEBAPP_SCHEMA_RESOURCE_PATH_24, Constants.WEBAPP_SCHEMA_RESOURCE_PATH_25, }; static final String[] CACHED_SCHEMA_RESOURCE_PATHS = DEFAULT_SCHEMA_RESOURCE_PATHS; // not actually used it seems @@ -240,27 +238,14 @@ public TreeNode parseXMLDocument(String uri, InputSource is, boolean validate) t // Perform an XML parse of this document, via JAXP - // START 6412405 - ClassLoader currentLoader; - if (Constants.IS_SECURITY_ENABLED) { - PrivilegedGetTccl pa = new PrivilegedGetTccl(); - currentLoader = AccessController.doPrivileged(pa); - } else { - currentLoader = Thread.currentThread().getContextClassLoader(); - } + ClassLoader currentLoader = Thread.currentThread().getContextClassLoader(); + try { - if (Constants.IS_SECURITY_ENABLED) { - PrivilegedSetTccl pa = new PrivilegedSetTccl(getClass().getClassLoader()); - AccessController.doPrivileged(pa); - } else { - Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - } - // END 6412405 + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); - /* - * See CR 6399139 factory.setFeature( "http://apache.org/xml/features/validation/dynamic", true); - */ + DocumentBuilder builder = factory.newDocumentBuilder(); builder.setEntityResolver(entityResolver); builder.setErrorHandler(errorHandler); @@ -272,9 +257,6 @@ public TreeNode parseXMLDocument(String uri, InputSource is, boolean validate) t // Validate TLD against specified schema schema.newValidator().validate(new DOMSource(document)); } - /* - * See CR 6399139 else { log.warning(Localizer.getMessage( "jsp.warning.dtdValidationNotSupported")); } - */ } } catch (ParserConfigurationException ex) { throw new WaspException(Localizer.getMessage("jsp.error.parse.xml", uri), ex); @@ -285,15 +267,9 @@ public TreeNode parseXMLDocument(String uri, InputSource is, boolean validate) t throw new WaspException(Localizer.getMessage("jsp.error.parse.xml", uri), sx); } catch (IOException io) { throw new WaspException(Localizer.getMessage("jsp.error.parse.xml", uri), io); - // START 6412405 } finally { - if (Constants.IS_SECURITY_ENABLED) { - AccessController.doPrivileged(new PrivilegedSetTccl(currentLoader)); - } else { - Thread.currentThread().setContextClassLoader(currentLoader); - } + Thread.currentThread().setContextClassLoader(currentLoader); } - // END 6412405 // Convert the resulting document to a graph of TreeNodes return convert(null, document.getDocumentElement()); @@ -488,7 +464,7 @@ public InputSource resolveEntity(String publicId, String systemId) throws SAXExc String cachedDtdPublicId = CACHED_DTD_PUBLIC_IDS[i]; if (cachedDtdPublicId.equals(publicId)) { String resourcePath = CACHED_DTD_RESOURCE_PATHS[i]; - + InputStream input = null; if (ParserUtils.isDtdResourcePrefixFileUrl) { try { @@ -501,7 +477,7 @@ public InputSource resolveEntity(String publicId, String systemId) throws SAXExc } } else { input = getClass().getResourceAsStream(resourcePath); - + if (input == null) { // Try fallback DTD int index = resourcePath.lastIndexOf('/'); @@ -510,13 +486,13 @@ public InputSource resolveEntity(String publicId, String systemId) throws SAXExc input = getClass().getResourceAsStream(fallBackResourcePath); } } - + } - + if (input == null) { throw new SAXException(Localizer.getMessage("jsp.error.internal.filenotfound", resourcePath)); } - + return new InputSource(input); } } @@ -530,7 +506,7 @@ public InputSource resolveEntity(String publicId, String systemId) throws SAXExc if (blockExternal) { throw new SAXException(Localizer.getMessage("jsp.error.parse.xml.invalidPublicId", publicId)); } - + return null; } }