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

rmaucher pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit aa3bdb0c76c83ff8bb2133eb30a3ac976dc407a4
Author: opencode <[email protected]>
AuthorDate: Thu Oct 8 15:32:02 2026 +0200

    Fall back to classpath defaults when catalina.properties is corrupt
    
    loadProperties() assigned the fresh Properties object to the static
    field before loading it, so a parse failure left the field pointing at
    a partially populated (or empty) object. Because the stream had been
    opened successfully, both the fallback to the default properties
    shipped in the class path and the failure warning were skipped. The
    common, server and shared loader settings were then missing, Bootstrap
    created class loaders without the configured entries and Tomcat failed
    with a confusing ClassNotFoundException for the Catalina class instead
    of anything pointing at the corrupt file.
    
    Loading now happens into a local object that is only published once
    the whole stream has been parsed. When the configured source is
    missing or cannot be parsed, the defaults from the class path are
    loaded instead; only when even that fails is the warning logged and an
    empty set used. This also keeps the partially parsed values from being
    registered as system properties.
---
 .../catalina/startup/CatalinaProperties.java       | 57 +++++++++++++++-------
 1 file changed, 40 insertions(+), 17 deletions(-)

diff --git a/java/org/apache/catalina/startup/CatalinaProperties.java 
b/java/org/apache/catalina/startup/CatalinaProperties.java
index cb9673a5a3..19bfd2d4ab 100644
--- a/java/org/apache/catalina/startup/CatalinaProperties.java
+++ b/java/org/apache/catalina/startup/CatalinaProperties.java
@@ -95,31 +95,24 @@ public class CatalinaProperties {
             }
         }
 
-        if (is == null) {
-            try {
-                is = 
CatalinaProperties.class.getResourceAsStream("/org/apache/catalina/startup/catalina.properties");
-            } catch (Throwable t) {
-                handleThrowable(t);
-            }
+        if (is != null) {
+            properties = load(is);
         }
 
-        if (is != null) {
+        if (properties == null) {
+            // The configured file could not be opened or could not be parsed.
+            // Fall back to the defaults from the class path.
             try {
-                properties = new Properties();
-                properties.load(is);
+                is = 
CatalinaProperties.class.getResourceAsStream("/org/apache/catalina/startup/catalina.properties");
             } catch (Throwable t) {
                 handleThrowable(t);
-                log.warn(t.getMessage(), t);
-            } finally {
-                try {
-                    is.close();
-                } catch (IOException ioe) {
-                    log.warn("Could not close catalina properties file", ioe);
-                }
+            }
+            if (is != null) {
+                properties = load(is);
             }
         }
 
-        if ((is == null)) {
+        if (properties == null) {
             log.warn("Failed to load catalina properties file");
             // That's fine - we have reasonable defaults.
             properties = new Properties();
@@ -137,6 +130,36 @@ public class CatalinaProperties {
     }
 
 
+    /**
+     * Loads properties from the specified stream, closing the stream when 
done.
+     *
+     * @param is The stream to read
+     *
+     * @return the loaded properties, or {@code null} if the stream could not
+     *         be parsed completely
+     */
+    private static Properties load(InputStream is) {
+        try {
+            Properties loaded = new Properties();
+            loaded.load(is);
+            // Publish the properties only once the whole stream has been
+            // parsed, so a corrupt file cannot silently replace the defaults
+            // with partially parsed values.
+            return loaded;
+        } catch (Throwable t) {
+            handleThrowable(t);
+            log.warn(t.getMessage(), t);
+            return null;
+        } finally {
+            try {
+                is.close();
+            } catch (IOException ioe) {
+                log.warn("Could not close catalina properties file", ioe);
+            }
+        }
+    }
+
+
     private static boolean isSchemeChar(char c) {
         return Character.isLetterOrDigit(c) || c == '+' || c == '-' || c == 
'.';
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to