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 42361f9fe45208106fcf2aca2caecf91cdc57136
Author: remm <[email protected]>
AuthorDate: Thu May 28 16:13:52 2026 +0200

    Fix various issues
    
    Of note an unintended double connection in proxy error report valve.
---
 .../valves/CrawlerSessionManagerValve.java         |   4 +-
 .../catalina/valves/JsonErrorReportValve.java      |   4 +-
 .../apache/catalina/valves/LocalStrings.properties |   1 +
 .../apache/catalina/valves/PersistentValve.java    |   6 +-
 .../catalina/valves/ProxyErrorReportValve.java     |   2 +-
 java/org/apache/catalina/valves/SSLValve.java      |   6 +-
 .../catalina/valves/rewrite/ResolverImpl.java      | 151 +++++++++++----------
 .../org/apache/coyote/ajp/AbstractAjpProtocol.java |   2 +-
 webapps/docs/changelog.xml                         |   3 +
 9 files changed, 97 insertions(+), 82 deletions(-)

diff --git a/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java 
b/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java
index 1492c2d21e..fd7d35b89f 100644
--- a/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java
+++ b/java/org/apache/catalina/valves/CrawlerSessionManagerValve.java
@@ -207,7 +207,7 @@ public class CrawlerSessionManagerValve extends ValveBase {
     protected void initInternal() throws LifecycleException {
         super.initInternal();
 
-        uaPattern = Pattern.compile(crawlerUserAgents);
+        setCrawlerUserAgents(crawlerUserAgents);
     }
 
 
@@ -248,7 +248,7 @@ public class CrawlerSessionManagerValve extends ValveBase {
                     log.trace(request.hashCode() + ": UserAgent=" + uaHeader);
                 }
 
-                if (uaPattern.matcher(uaHeader).matches()) {
+                if (uaPattern != null && 
uaPattern.matcher(uaHeader).matches()) {
                     isBot = true;
 
                     if (log.isTraceEnabled()) {
diff --git a/java/org/apache/catalina/valves/JsonErrorReportValve.java 
b/java/org/apache/catalina/valves/JsonErrorReportValve.java
index af6e4f1eec..a5b0a58747 100644
--- a/java/org/apache/catalina/valves/JsonErrorReportValve.java
+++ b/java/org/apache/catalina/valves/JsonErrorReportValve.java
@@ -95,6 +95,7 @@ public class JsonErrorReportValve extends ErrorReportValve {
 
             // Stack trace
             sb.append("  \"throwable\": [");
+            int loops = 0;
             boolean first = true;
             do {
                 if (!first) {
@@ -121,7 +122,8 @@ public class JsonErrorReportValve extends ErrorReportValve {
                 }
 
                 throwable = throwable.getCause();
-            } while (throwable != null);
+                loops++;
+            } while (throwable != null && (loops < 10));
             sb.append("]\n}");
 
         } else {
diff --git a/java/org/apache/catalina/valves/LocalStrings.properties 
b/java/org/apache/catalina/valves/LocalStrings.properties
index 86b82d7449..908cb6f3ab 100644
--- a/java/org/apache/catalina/valves/LocalStrings.properties
+++ b/java/org/apache/catalina/valves/LocalStrings.properties
@@ -167,6 +167,7 @@ requestFilterValve.configInvalid=One or more invalid 
configuration settings were
 requestFilterValve.deny=Denied request for [{0}] based on property [{1}]
 
 sslValve.certError=Failed to process certificate string [{0}] to create a 
java.security.cert.X509Certificate object
+sslValve.invalidHeader=Invalid value [{0}] for header [{1}]
 sslValve.invalidProvider=The SSL provider specified on the connector 
associated with this request of [{0}] is invalid. The certificate data could 
not be processed.
 
 stuckThreadDetectionValve.interrupted=Thread interrupted after the request is 
finished, ignoring
diff --git a/java/org/apache/catalina/valves/PersistentValve.java 
b/java/org/apache/catalina/valves/PersistentValve.java
index 22d7c2e011..de44fbaacd 100644
--- a/java/org/apache/catalina/valves/PersistentValve.java
+++ b/java/org/apache/catalina/valves/PersistentValve.java
@@ -38,6 +38,8 @@ import org.apache.catalina.Store;
 import org.apache.catalina.StoreManager;
 import org.apache.catalina.connector.Request;
 import org.apache.catalina.connector.Response;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
 
 /**
  * Valve that implements per-request session persistence. It is intended to be 
used with non-sticky load-balancers and a
@@ -68,6 +70,8 @@ import org.apache.catalina.connector.Response;
  */
 public class PersistentValve extends ValveBase {
 
+    private static final Log log = LogFactory.getLog(PersistentValve.class);
+
     // Saves a couple of calls to getClassLoader() on every request. Under high
     // load these calls took just long enough to appear as a hot spot (although
     // a very minor one) in a profiler.
@@ -348,7 +352,7 @@ public class PersistentValve extends ValveBase {
             try {
                 this.filter = Pattern.compile(filter);
             } catch (PatternSyntaxException pse) {
-                
container.getLogger().error(sm.getString("persistentValve.filter.failure", 
filter), pse);
+                log.error(sm.getString("persistentValve.filter.failure", 
filter), pse);
             }
         }
     }
diff --git a/java/org/apache/catalina/valves/ProxyErrorReportValve.java 
b/java/org/apache/catalina/valves/ProxyErrorReportValve.java
index 67e1b373c5..dd5f22e219 100644
--- a/java/org/apache/catalina/valves/ProxyErrorReportValve.java
+++ b/java/org/apache/catalina/valves/ProxyErrorReportValve.java
@@ -230,7 +230,7 @@ public class ProxyErrorReportValve extends ErrorReportValve 
{
                 response.setContentType(httpURLConnection.getContentType());
                 
response.setContentLength(httpURLConnection.getContentLength());
                 OutputStream outputStream = response.getOutputStream();
-                InputStream inputStream = url.openStream();
+                InputStream inputStream = httpURLConnection.getInputStream();
                 IOTools.flow(inputStream, outputStream);
             } catch (URISyntaxException | IOException | 
IllegalArgumentException e) {
                 if (log.isDebugEnabled()) {
diff --git a/java/org/apache/catalina/valves/SSLValve.java 
b/java/org/apache/catalina/valves/SSLValve.java
index 41cf7093d1..c252d9d6f5 100644
--- a/java/org/apache/catalina/valves/SSLValve.java
+++ b/java/org/apache/catalina/valves/SSLValve.java
@@ -248,7 +248,11 @@ public class SSLValve extends ValveBase {
         }
         headerValue = mygetHeader(request, sslCipherUserKeySizeHeader);
         if (headerValue != null) {
-            request.setAttribute(Globals.KEY_SIZE_ATTR, 
Integer.valueOf(headerValue));
+            try {
+                request.setAttribute(Globals.KEY_SIZE_ATTR, 
Integer.valueOf(headerValue));
+            } catch (NumberFormatException e) {
+                log.warn(sm.getString("sslValve.invalidHeader", headerValue, 
sslCipherUserKeySizeHeader));
+            }
         }
         getNext().invoke(request, response);
     }
diff --git a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java 
b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
index 89f3a4f86d..707fabf7fa 100644
--- a/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
+++ b/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
@@ -188,87 +188,88 @@ public class ResolverImpl extends Resolver {
 
     @Override
     public String resolveSsl(String key) {
-        SSLSupport sslSupport = (SSLSupport) 
request.getAttribute(SSLSupport.SESSION_MGR);
-        try {
-            // SSL_SRP_USER: no planned support for SRP
-            // SSL_SRP_USERINFO: no planned support for SRP
-            if (key.equals("HTTPS")) {
-                return String.valueOf(sslSupport != null);
-            } else if (key.equals("SSL_PROTOCOL")) {
-                return sslSupport.getProtocol();
-            } else if (key.equals("SSL_SESSION_ID")) {
-                return sslSupport.getSessionId();
-            } else if (key.equals("SSL_SESSION_RESUMED")) {
-                // FIXME session resumption state, not available anywhere
-            } else if (key.equals("SSL_SECURE_RENEG")) {
-                // FIXME available from SSLHostConfig
-            } else if (key.equals("SSL_COMPRESS_METHOD")) {
-                // FIXME available from SSLHostConfig
-            } else if (key.equals("SSL_TLS_SNI")) {
-                // FIXME from handshake SNI processing
-            } else if (key.equals("SSL_CIPHER")) {
-                return sslSupport.getCipherSuite();
-            } else if (key.equals("SSL_CIPHER_EXPORT")) {
-                String cipherSuite = sslSupport.getCipherSuite();
-                if (cipherSuite != null) {
-                    Set<Cipher> cipherList = 
OpenSSLCipherConfigurationParser.parse(cipherSuite);
-                    if (cipherList.size() == 1) {
-                        Cipher cipher = cipherList.iterator().next();
-                        if (cipher.getLevel().equals(EncryptionLevel.EXP40) ||
-                                
cipher.getLevel().equals(EncryptionLevel.EXP56)) {
-                            return "true";
-                        } else {
-                            return "false";
+        if (request.getAttribute(SSLSupport.SESSION_MGR) instanceof SSLSupport 
sslSupport) {
+            try {
+                // SSL_SRP_USER: no planned support for SRP
+                // SSL_SRP_USERINFO: no planned support for SRP
+                if (key.equals("HTTPS")) {
+                    return String.valueOf(sslSupport != null);
+                } else if (key.equals("SSL_PROTOCOL")) {
+                    return sslSupport.getProtocol();
+                } else if (key.equals("SSL_SESSION_ID")) {
+                    return sslSupport.getSessionId();
+                } else if (key.equals("SSL_SESSION_RESUMED")) {
+                    // FIXME session resumption state, not available anywhere
+                } else if (key.equals("SSL_SECURE_RENEG")) {
+                    // FIXME available from SSLHostConfig
+                } else if (key.equals("SSL_COMPRESS_METHOD")) {
+                    // FIXME available from SSLHostConfig
+                } else if (key.equals("SSL_TLS_SNI")) {
+                    // FIXME from handshake SNI processing
+                } else if (key.equals("SSL_CIPHER")) {
+                    return sslSupport.getCipherSuite();
+                } else if (key.equals("SSL_CIPHER_EXPORT")) {
+                    String cipherSuite = sslSupport.getCipherSuite();
+                    if (cipherSuite != null) {
+                        Set<Cipher> cipherList = 
OpenSSLCipherConfigurationParser.parse(cipherSuite);
+                        if (cipherList.size() == 1) {
+                            Cipher cipher = cipherList.iterator().next();
+                            if 
(cipher.getLevel().equals(EncryptionLevel.EXP40) ||
+                                    
cipher.getLevel().equals(EncryptionLevel.EXP56)) {
+                                return "true";
+                            } else {
+                                return "false";
+                            }
                         }
                     }
-                }
-            } else if (key.equals("SSL_CIPHER_ALGKEYSIZE")) {
-                String cipherSuite = sslSupport.getCipherSuite();
-                if (cipherSuite != null) {
-                    Set<Cipher> cipherList = 
OpenSSLCipherConfigurationParser.parse(cipherSuite);
-                    if (cipherList.size() == 1) {
-                        Cipher cipher = cipherList.iterator().next();
-                        return String.valueOf(cipher.getAlg_bits());
+                } else if (key.equals("SSL_CIPHER_ALGKEYSIZE")) {
+                    String cipherSuite = sslSupport.getCipherSuite();
+                    if (cipherSuite != null) {
+                        Set<Cipher> cipherList = 
OpenSSLCipherConfigurationParser.parse(cipherSuite);
+                        if (cipherList.size() == 1) {
+                            Cipher cipher = cipherList.iterator().next();
+                            return String.valueOf(cipher.getAlg_bits());
+                        }
                     }
-                }
-            } else if (key.equals("SSL_CIPHER_USEKEYSIZE")) {
-                Integer keySize = sslSupport.getKeySize();
-                return (keySize == null) ? null : 
sslSupport.getKeySize().toString();
-            } else if (key.startsWith("SSL_CLIENT_")) {
-                X509Certificate[] certificates = 
sslSupport.getPeerCertificateChain();
-                if (certificates != null && certificates.length > 0) {
-                    key = key.substring("SSL_CLIENT_".length());
-                    String result = resolveSslCertificates(key, certificates);
-                    if (result != null) {
-                        return result;
-                    } else if (key.startsWith("SAN_OTHER_msUPN_")) {
-                        // Type otherName, which is 0
-                        key = key.substring("SAN_OTHER_msUPN_".length());
-                        // FIXME OID from resolveAlternateName
-                    } else if (key.equals("CERT_RFC4523_CEA")) {
-                        // FIXME return certificate[0] format 
CertificateExactAssertion in RFC4523
-                    } else if (key.equals("VERIFY")) {
-                        // FIXME return verification state, not available 
anywhere
+                } else if (key.equals("SSL_CIPHER_USEKEYSIZE")) {
+                    Integer keySize = sslSupport.getKeySize();
+                    return (keySize == null) ? null : 
sslSupport.getKeySize().toString();
+                } else if (key.startsWith("SSL_CLIENT_")) {
+                    X509Certificate[] certificates = 
sslSupport.getPeerCertificateChain();
+                    if (certificates != null && certificates.length > 0) {
+                        key = key.substring("SSL_CLIENT_".length());
+                        String result = resolveSslCertificates(key, 
certificates);
+                        if (result != null) {
+                            return result;
+                        } else if (key.startsWith("SAN_OTHER_msUPN_")) {
+                            // Type otherName, which is 0
+                            key = key.substring("SAN_OTHER_msUPN_".length());
+                            // FIXME OID from resolveAlternateName
+                        } else if (key.equals("CERT_RFC4523_CEA")) {
+                            // FIXME return certificate[0] format 
CertificateExactAssertion in RFC4523
+                        } else if (key.equals("VERIFY")) {
+                            // FIXME return verification state, not available 
anywhere
+                        }
                     }
-                }
-            } else if (key.startsWith("SSL_SERVER_")) {
-                X509Certificate[] certificates = 
sslSupport.getLocalCertificateChain();
-                if (certificates != null && certificates.length > 0) {
-                    key = key.substring("SSL_SERVER_".length());
-                    String result = resolveSslCertificates(key, certificates);
-                    if (result != null) {
-                        return result;
-                    } else if (key.startsWith("SAN_OTHER_dnsSRV_")) {
-                        // Type otherName, which is 0
-                        key = key.substring("SAN_OTHER_dnsSRV_".length());
-                        // FIXME OID from resolveAlternateName
+                } else if (key.startsWith("SSL_SERVER_")) {
+                    X509Certificate[] certificates = 
sslSupport.getLocalCertificateChain();
+                    if (certificates != null && certificates.length > 0) {
+                        key = key.substring("SSL_SERVER_".length());
+                        String result = resolveSslCertificates(key, 
certificates);
+                        if (result != null) {
+                            return result;
+                        } else if (key.startsWith("SAN_OTHER_dnsSRV_")) {
+                            // Type otherName, which is 0
+                            key = key.substring("SAN_OTHER_dnsSRV_".length());
+                            // FIXME OID from resolveAlternateName
+                        }
                     }
                 }
-            }
-        } catch (IOException ioe) {
-            // TLS access error
-            if (containerLog.isDebugEnabled()) {
-                containerLog.debug(sm.getString("resolverImpl.tlsError"), ioe);
+            } catch (IOException ioe) {
+                // TLS access error
+                if (containerLog.isDebugEnabled()) {
+                    containerLog.debug(sm.getString("resolverImpl.tlsError"), 
ioe);
+                }
             }
         }
         return null;
diff --git a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java 
b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
index 337b0ce872..c930c4ccd9 100644
--- a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
+++ b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
@@ -245,7 +245,7 @@ public abstract class AbstractAjpProtocol<S> extends 
AbstractProtocol<S> {
      * @return the pattern string
      */
     public String getAllowedRequestAttributesPattern() {
-        return allowedRequestAttributesPattern.pattern();
+        return allowedRequestAttributesPattern != null ? 
allowedRequestAttributesPattern.pattern() : null;
     }
 
     /**
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 65705c6299..5404e04d0f 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -211,6 +211,9 @@
         than a <code>500</code> response. Pull request <pr>1012</pr> provided 
by
         Sahana Surendra Bogar. (markt)
       </fix>
+      <fix>
+        Fix connection leak in <code>ProxyErrorReportValve</code>. (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


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

Reply via email to