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 99ce7849d8a1ff2dfa4c7c1626046c98d53710a3
Author: opencode <[email protected]>
AuthorDate: Sun Oct 25 17:01:05 2026 +0100

    Do not apply JNDI reference metadata as bean properties in the naming 
factory
    
    GenericNamingResourcesFactory applied every RefAddr of the Reference,
    without filtering, as a bean property of the target object. For a
    <Resource>, Tomcat's ResourceRef always carries a 'singleton' address
    and conditionally 'description', 'scope' and 'auth', and the Digester
    routes the 'factory' attribute through the resource property bag so it
    also arrives as a plain address. A target exposing the generic
    setProperty(name, value) fallback therefore received JNDI plumbing
    values such as singleton=true, auth=Container, scope=Shareable and
    factory=org.apache.tomcat.jdbc.naming.GenericNamingResourcesFactory as
    if they were configuration, entries which may then be forwarded to a
    driver or resource adapter, and any setFactory/setScope/... setter was
    fed those values too.
    
    Skip the reserved address types factory, singleton, scope, auth,
    description and forceString, the same list that the container's
    org.apache.naming.factory.BeanFactory has always excluded. The
    addresses stay in the Reference, so container semantics implemented
    from the ResourceRef, such as the singleton lookup behaviour in
    NamingContext, are unaffected. A null address type is skipped as well,
    since no bean property can be derived from it.
    
    Add a regression test that checks only genuine properties reach a
    target's generic setProperty(name, value) method.
---
 .../jdbc/naming/GenericNamingResourcesFactory.java | 19 +++++++++++
 .../tomcat/jdbc/naming/TestNamingFactory.java      | 39 ++++++++++++++++++++++
 2 files changed, 58 insertions(+)

diff --git 
a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java
 
b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java
index 525b0f84eb..4925319abb 100644
--- 
a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java
+++ 
b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java
@@ -20,8 +20,12 @@ import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.Hashtable;
+import java.util.Set;
 
 import javax.naming.Context;
 import javax.naming.Name;
@@ -57,6 +61,17 @@ public class GenericNamingResourcesFactory implements 
ObjectFactory {
 
     private static final Log log = 
LogFactory.getLog(GenericNamingResourcesFactory.class);
 
+    /**
+     * Reference metadata that Tomcat attaches to a {@code ResourceRef}; these
+     * are not bean properties of the target object. Mirrors the list excluded
+     * by {@code org.apache.naming.factory.BeanFactory}. Inlined because
+     * tomcat-jdbc.jar does not depend on catalina.jar.
+     */
+    private static final Set<String> RESERVED_ADDR_TYPES =
+            Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
+                    "factory", "singleton", "scope", "auth", "description",
+                    "forceString")));
+
     @Override
     public Object getObjectInstance(Object obj, Name name, Context nameCtx, 
Hashtable<?, ?> environment) throws Exception {
         if ((obj == null) || !(obj instanceof Reference)) {
@@ -75,6 +90,10 @@ public class GenericNamingResourcesFactory implements 
ObjectFactory {
         while (refs.hasMoreElements()) {
             RefAddr addr = refs.nextElement();
             String param = addr.getType();
+            if (param == null || RESERVED_ADDR_TYPES.contains(param)) {
+                // reference metadata, not a configuration property
+                continue;
+            }
             String value = null;
             if (addr.getContent()!=null) {
                 value = addr.getContent().toString();
diff --git 
a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/naming/TestNamingFactory.java
 
b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/naming/TestNamingFactory.java
index 367ced9e8a..e01ed2b79a 100644
--- 
a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/naming/TestNamingFactory.java
+++ 
b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/naming/TestNamingFactory.java
@@ -187,6 +187,45 @@ class TestNamingFactory extends JdbcPoolBaseTest {
         }
     }
 
+    @Test
+    void reservedReferenceAddressesAreNotAppliedAsProperties()
+            throws Exception {
+        Reference ref = new Reference(BagTarget.class.getName(), null, null);
+        // addresses a ResourceRef carries for a <Resource> element
+        ref.add(new StringRefAddr("singleton", "true"));
+        ref.add(new StringRefAddr("auth", "Container"));
+        ref.add(new StringRefAddr("scope", "Shareable"));
+        ref.add(new StringRefAddr("description", "my pool"));
+        ref.add(new StringRefAddr("forceString", "ignored"));
+        // the factory attribute is routed through the resource property bag
+        // by the Digester and arrives as a plain address
+        ref.add(new StringRefAddr("factory",
+                GenericNamingResourcesFactory.class.getName()));
+        // genuine configuration property
+        ref.add(new StringRefAddr("databaseName", "sample"));
+
+        Object result = new GenericNamingResourcesFactory().getObjectInstance(
+                ref, new CompositeName("test/bag"), null, null);
+        assertInstanceOf(BagTarget.class, result);
+        BagTarget target = (BagTarget) result;
+        assertEquals(java.util.Collections.singletonMap("databaseName", 
"sample"),
+                target.getBag(),
+                "reference metadata must not be applied as bean properties");
+    }
+
+    /** Target with a generic setProperty(name, value) fallback. */
+    public static class BagTarget {
+        private final java.util.Map<String, String> bag =
+                new java.util.LinkedHashMap<>();
+
+        public void setProperty(String name, String value) {
+            bag.put(name, value);
+        }
+        public java.util.Map<String, String> getBag() {
+            return bag;
+        }
+    }
+
     /** Plain configuration target for the generic naming factory. */
     public static class NamingTarget {
         private String name;


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

Reply via email to