This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit cae17a52598393680952aa21cee0e27b13a73455
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Sep 12 15:31:26 2019 +0100

    Additional changes required to enable EnvironmentPropertySource
---
 .../org/apache/tomcat/util/IntrospectionUtils.java | 49 ++++++++++++++++++++--
 java/org/apache/tomcat/util/digester/Digester.java | 33 ++++++++++-----
 webapps/docs/changelog.xml                         |  4 +-
 3 files changed, 69 insertions(+), 17 deletions(-)

diff --git a/java/org/apache/tomcat/util/IntrospectionUtils.java 
b/java/org/apache/tomcat/util/IntrospectionUtils.java
index 3ffa702..f6ac737 100644
--- a/java/org/apache/tomcat/util/IntrospectionUtils.java
+++ b/java/org/apache/tomcat/util/IntrospectionUtils.java
@@ -26,6 +26,7 @@ import java.util.Hashtable;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.util.security.PermissionCheck;
 
 /**
  * Utils for introspection and reflection
@@ -224,9 +225,27 @@ public final class IntrospectionUtils {
      * @param staticProp Replacement properties
      * @param dynamicProp Replacement properties
      * @return the replacement value
+     * @deprecated Use {@link #replaceProperties(String, Hashtable, 
PropertySource[], ClassLoader)}
      */
+    @Deprecated
     public static String replaceProperties(String value,
             Hashtable<Object,Object> staticProp, PropertySource dynamicProp[]) 
{
+        return replaceProperties(value, staticProp, dynamicProp, null);
+    }
+
+    /**
+     * Replace ${NAME} with the property value.
+     * @param value The value
+     * @param staticProp Replacement properties
+     * @param dynamicProp Replacement properties
+     * @param classLoader Class loader associated with the code requesting the
+     *                    property
+     * @return the replacement value
+     */
+    public static String replaceProperties(String value,
+            Hashtable<Object,Object> staticProp, PropertySource dynamicProp[],
+            ClassLoader classLoader) {
+
         if (value.indexOf('$') < 0) {
             return value;
         }
@@ -257,8 +276,12 @@ public final class IntrospectionUtils {
                     v = (String) staticProp.get(n);
                 }
                 if (v == null && dynamicProp != null) {
-                    for (int i = 0; i < dynamicProp.length; i++) {
-                        v = dynamicProp[i].getProperty(n);
+                    for (PropertySource propertySource : dynamicProp) {
+                        if (propertySource instanceof PropertySourceSecure) {
+                            v = ((PropertySourceSecure) 
propertySource).getProperty(n, classLoader);
+                        } else {
+                            v = propertySource.getProperty(n);
+                        }
                         if (v != null) {
                             break;
                         }
@@ -476,9 +499,27 @@ public final class IntrospectionUtils {
     // This provides a layer of abstraction
 
     public static interface PropertySource {
-
         public String getProperty(String key);
-
     }
 
+
+    public static interface PropertySourceSecure extends PropertySource {
+
+        /**
+         * Obtain a property value, checking that code associated with the
+         * provided class loader has permission to access the property. If the
+         * {@code classLoader} is {@code null} or if {@code classLoader} does
+         * not implement {@link PermissionCheck} then the property value will 
be
+         * looked up <b>without</b> a call to
+         * {@link PermissionCheck#check(java.security.Permission)}
+         *
+         * @param key               The key of the requested property
+         * @param classLoader   The class loader associated with the code that
+         *                      trigger the property lookup
+         * @return The property value or {@code null} if it could not be found
+         *         or if {@link 
PermissionCheck#check(java.security.Permission)}
+         *         fails
+         */
+        public String getProperty(String key, ClassLoader classLoader);
+    }
 }
diff --git a/java/org/apache/tomcat/util/digester/Digester.java 
b/java/org/apache/tomcat/util/digester/Digester.java
index 810274b..610e83c 100644
--- a/java/org/apache/tomcat/util/digester/Digester.java
+++ b/java/org/apache/tomcat/util/digester/Digester.java
@@ -123,13 +123,19 @@ public class Digester extends DefaultHandler2 {
     // --------------------------------------------------- Instance Variables
 
 
-    private class SystemPropertySource implements 
IntrospectionUtils.PropertySource {
+    private static class SystemPropertySource implements 
IntrospectionUtils.PropertySourceSecure {
+
         @Override
         public String getProperty(String key) {
-            ClassLoader cl = getClassLoader();
-            if (cl instanceof PermissionCheck) {
+            // For backward compatibility
+            return getProperty(key, null);
+        }
+
+        @Override
+        public String getProperty(String key, ClassLoader classLoader) {
+            if (classLoader instanceof PermissionCheck) {
                 Permission p = new PropertyPermission(key, "read");
-                if (!((PermissionCheck) cl).check(p)) {
+                if (!((PermissionCheck) classLoader).check(p)) {
                     return null;
                 }
             }
@@ -138,13 +144,18 @@ public class Digester extends DefaultHandler2 {
     }
 
 
-    public class EnvironmentPropertySource implements 
IntrospectionUtils.PropertySource {
+    public static class EnvironmentPropertySource implements 
IntrospectionUtils.PropertySourceSecure {
+
         @Override
         public String getProperty(String key) {
-            ClassLoader cl = getClassLoader();
-            if (cl instanceof PermissionCheck) {
+            return null;
+        }
+
+        @Override
+        public String getProperty(String key, ClassLoader classLoader) {
+            if (classLoader instanceof PermissionCheck) {
                 Permission p = new RuntimePermission("getenv." + key, null);
-                if (!((PermissionCheck) cl).check(p)) {
+                if (!((PermissionCheck) classLoader).check(p)) {
                     return null;
                 }
             }
@@ -351,7 +362,7 @@ public class Digester extends DefaultHandler2 {
                 String value = System.getProperty(name);
                 if (value != null) {
                     try {
-                        String newValue = 
IntrospectionUtils.replaceProperties(value, null, propertySources);
+                        String newValue = 
IntrospectionUtils.replaceProperties(value, null, propertySources, null);
                         if (!value.equals(newValue)) {
                             System.setProperty(name, newValue);
                         }
@@ -1933,7 +1944,7 @@ public class Digester extends DefaultHandler2 {
         for (int i = 0; i < nAttributes; ++i) {
             String value = newAttrs.getValue(i);
             try {
-                newAttrs.setValue(i, 
IntrospectionUtils.replaceProperties(value, null, source).intern());
+                newAttrs.setValue(i, 
IntrospectionUtils.replaceProperties(value, null, source, 
getClassLoader()).intern());
             } catch (Exception e) {
                 log.warn(sm.getString("digester.failedToUpdateAttributes", 
newAttrs.getLocalName(i), value), e);
             }
@@ -1952,7 +1963,7 @@ public class Digester extends DefaultHandler2 {
         String in = bodyText.toString();
         String out;
         try {
-            out = IntrospectionUtils.replaceProperties(in, null, source);
+            out = IntrospectionUtils.replaceProperties(in, null, source, 
getClassLoader());
         } catch (Exception e) {
             return bodyText; // return unchanged data
         }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index e89ca90..bec625b 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -69,8 +69,8 @@
       <add>
         Add a new <code>PropertySource</code> implementation,
         <code>EnvironmentPropertySource</code>, that can be used to do property
-        replacement in configuration files with environment variables. Pull
-        request provided by Thomas Meyer. (markt)
+        replacement in configuration files with environment variables. Based on
+        a pull request provided by Thomas Meyer. (markt)
       </add>
     </changelog>
   </subsection>


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

Reply via email to