This is an automated email from the ASF dual-hosted git repository. markt-asf pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 67934df3f72e0795b6e30e48cb4d800dadc42b38 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 9d679f3063..7551aae6f6 100644 --- a/java/org/apache/tomcat/util/modeler/LocalStrings.properties +++ b/java/org/apache/tomcat/util/modeler/LocalStrings.properties @@ -45,12 +45,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 8686645f44..b202240104 100644 --- a/java/org/apache/tomcat/util/modeler/Registry.java +++ b/java/org/apache/tomcat/util/modeler/Registry.java @@ -537,6 +537,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; @@ -556,22 +558,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]
