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

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


The following commit(s) were added to refs/heads/10.1.x by this push:
     new 87c62a5672 Review "Convert numeric and character values in the JMX 
proxy ..."
87c62a5672 is described below

commit 87c62a5672032ef5462a1d6a22b8bf7f46dc7935
Author: Mark Thomas <[email protected]>
AuthorDate: Tue Nov 3 18:49:08 2026 +0000

    Review "Convert numeric and character values in the JMX proxy ..."
    
    Throw NumberFormatException consistently for invalid input
    Throw rather than silently fix invalid char values.
---
 .../tomcat/util/modeler/LocalStrings.properties    |  2 ++
 java/org/apache/tomcat/util/modeler/Registry.java  | 26 +++++++++++++++++-----
 .../util/modeler/TestRegistryConvertValue.java     | 24 +++++++++-----------
 3 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/java/org/apache/tomcat/util/modeler/LocalStrings.properties 
b/java/org/apache/tomcat/util/modeler/LocalStrings.properties
index fe3238e3e9..ed806f5a5b 100644
--- a/java/org/apache/tomcat/util/modeler/LocalStrings.properties
+++ b/java/org/apache/tomcat/util/modeler/LocalStrings.properties
@@ -47,12 +47,14 @@ registry.createdServer=Created MBeanServer
 registry.existingServer=Using existing MBeanServer
 registry.initError=Error initializing [{0}]
 registry.invalidArguments=Invalid arguments, bean and beanClass cannot both be 
null
+registry.invalidCharValue=The value [{0}] is not a single character
 registry.invalidSource=Invalid source specified, must be either URL, File, 
Class or InputStream
 registry.loadError=Error loading descriptors from [{0}]
 registry.noDisable=The MBean registry cannot be disabled because it has 
already been initialised
 registry.noMetadata=Cannot find metadata for object [{0}]
 registry.noTypeMetadata=Cannot find metadata for type [{0}]
 registry.nullBean=Cannot register null bean for [{0}]
+registry.nullValue=Cannot convert a null value to type [{0}]
 registry.objectNameCreateError=Error creating object name
 registry.registerError=Error registering MBean
 registry.unregisterError=Error unregistering MBean
diff --git a/java/org/apache/tomcat/util/modeler/Registry.java 
b/java/org/apache/tomcat/util/modeler/Registry.java
index 41152a3993..6a47fd6bfc 100644
--- a/java/org/apache/tomcat/util/modeler/Registry.java
+++ b/java/org/apache/tomcat/util/modeler/Registry.java
@@ -536,6 +536,8 @@ public class Registry implements RegistryMBean, 
MBeanRegistration {
      * @param value String value to be converted
      *
      * @return Converted value
+     *
+     * @throws NumberFormatException If the value is null or is not valid for 
a numeric or character type
      */
     public Object convertValue(String type, String value) {
         Object objValue = value;
@@ -555,22 +557,36 @@ public class Registry implements RegistryMBean, 
MBeanRegistration {
         } else if ("java.lang.Boolean".equals(type) || "boolean".equals(type)) 
{
             objValue = Boolean.valueOf(value);
         } else if ("java.lang.Double".equals(type) || "double".equals(type)) {
-            objValue = Double.valueOf(value);
+            objValue = Double.valueOf(requireValue(type, value));
         } else if ("java.lang.Float".equals(type) || "float".equals(type)) {
-            objValue = Float.valueOf(value);
+            objValue = Float.valueOf(requireValue(type, value));
         } else if ("java.lang.Short".equals(type) || "short".equals(type)) {
             objValue = Short.valueOf(value);
         } else if ("java.lang.Byte".equals(type) || "byte".equals(type)) {
             objValue = Byte.valueOf(value);
-        } else if (("java.lang.Character".equals(type) || "char".equals(type)) 
&&
-                value != null && !value.isEmpty()) {
-            // A null or empty string cannot be converted to a character
+        } else if ("java.lang.Character".equals(type) || "char".equals(type)) {
+            requireValue(type, value);
+            if (value.length() != 1) {
+                throw new 
NumberFormatException(sm.getString("registry.invalidCharValue", value));
+            }
             objValue = Character.valueOf(value.charAt(0));
         }
         return objValue;
     }
 
 
+    /*
+     * Double.valueOf() and Float.valueOf() throw a NullPointerException for a 
null value. Report it the same way as
+     * the integral types do.
+     */
+    private String requireValue(String type, String value) {
+        if (value == null) {
+            throw new NumberFormatException(sm.getString("registry.nullValue", 
type));
+        }
+        return value;
+    }
+
+
     /**
      * Load descriptors.
      *
diff --git a/test/org/apache/tomcat/util/modeler/TestRegistryConvertValue.java 
b/test/org/apache/tomcat/util/modeler/TestRegistryConvertValue.java
index bf3ffce1fb..03b7ac2e50 100644
--- a/test/org/apache/tomcat/util/modeler/TestRegistryConvertValue.java
+++ b/test/org/apache/tomcat/util/modeler/TestRegistryConvertValue.java
@@ -62,23 +62,19 @@ public class TestRegistryConvertValue {
     }
 
     @Test
-    public void testConvertEmptyStringToCharacterIsNotConverted() {
-        // An empty string has no character to convert to
-        Object result = registry.convertValue("char", "");
-        Assert.assertEquals("", result);
+    public void testConvertCharacterTypeRejectsOtherLengths() {
+        // Exactly one character is required, anything else is an error rather 
than being truncated or ignored
+        Assert.assertThrows(NumberFormatException.class, () -> 
registry.convertValue("char", ""));
+        Assert.assertThrows(NumberFormatException.class, () -> 
registry.convertValue("char", "xy"));
+        Assert.assertThrows(NumberFormatException.class, () -> 
registry.convertValue("java.lang.Character", "xy"));
     }
 
     @Test
-    public void testConvertCharacterTypeTruncatesLongerString() {
-        // The first character is the only one that can be converted
-        Assert.assertEquals(Character.valueOf('x'), 
registry.convertValue("char", "xy"));
-    }
-
-    @Test
-    public void testConvertNullValueIsNotConvertedForCharacter() {
-        // Only the character type leaves a null value unconverted rather than
-        // throwing, matching the historical behavior for this branch
-        Assert.assertNull(registry.convertValue("char", null));
+    public void testConvertNullValueThrowsForNumericAndCharacterTypes() {
+        for (String type : new String[] { "int", "long", "short", "byte", 
"double", "float", "char",
+                "java.lang.Double", "java.lang.Float", "java.lang.Character" 
}) {
+            Assert.assertThrows(type, NumberFormatException.class, () -> 
registry.convertValue(type, null));
+        }
     }
 
     @Test


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

Reply via email to