This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 400a0e28b559f05330bf258690099d48d6f7075f 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]
