From 1aa700cbeb409e9b3b2d65e00bbb3838f070773e Mon Sep 17 00:00:00 2001 From: Aizal Khan Date: Thu, 13 Aug 2026 03:22:21 +0530 Subject: [PATCH 1/2] report over-long float and double as invalid in validateLexical --- .../impl/values/JavaDoubleHolder.java | 2 +- .../xmlbeans/impl/values/JavaFloatHolder.java | 2 +- .../checkin/MaxNumberCharsValidateTest.java | 68 +++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 src/test/java/misc/checkin/MaxNumberCharsValidateTest.java diff --git a/src/main/java/org/apache/xmlbeans/impl/values/JavaDoubleHolder.java b/src/main/java/org/apache/xmlbeans/impl/values/JavaDoubleHolder.java index 41dea0c7b..914e98c6e 100644 --- a/src/main/java/org/apache/xmlbeans/impl/values/JavaDoubleHolder.java +++ b/src/main/java/org/apache/xmlbeans/impl/values/JavaDoubleHolder.java @@ -69,7 +69,7 @@ public static double validateLexical(String v, ValidationContext context, boolea int maxNumberOfCharsForNumbers) { try { return XsTypeConverter.lexDouble(v, strict, maxNumberOfCharsForNumbers); - } catch (NumberFormatException e) { + } catch (IllegalArgumentException e) { context.invalid(XmlErrorCodes.DOUBLE, new Object[]{v}); return Double.NaN; diff --git a/src/main/java/org/apache/xmlbeans/impl/values/JavaFloatHolder.java b/src/main/java/org/apache/xmlbeans/impl/values/JavaFloatHolder.java index 9734c9db3..54e35e438 100644 --- a/src/main/java/org/apache/xmlbeans/impl/values/JavaFloatHolder.java +++ b/src/main/java/org/apache/xmlbeans/impl/values/JavaFloatHolder.java @@ -69,7 +69,7 @@ public static float validateLexical(String v, ValidationContext context, boolean int maxNumberOfChars) { try { return XsTypeConverter.lexFloat(v, strict, maxNumberOfChars); - } catch (NumberFormatException e) { + } catch (IllegalArgumentException e) { context.invalid(XmlErrorCodes.FLOAT, new Object[]{v}); return Float.NaN; diff --git a/src/test/java/misc/checkin/MaxNumberCharsValidateTest.java b/src/test/java/misc/checkin/MaxNumberCharsValidateTest.java new file mode 100644 index 000000000..5994aa65c --- /dev/null +++ b/src/test/java/misc/checkin/MaxNumberCharsValidateTest.java @@ -0,0 +1,68 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package misc.checkin; + +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class MaxNumberCharsValidateTest { + + // XmlOptions.DEFAULT_MAX_NUMBER_CHARS is 1024; a lexically valid number longer + // than that trips the length cap in MathUtil.parseAsFloat/parseAsDouble, which + // throws IllegalArgumentException rather than NumberFormatException. + private static String tooLong(char c) { + char[] cs = new char[1025]; + Arrays.fill(cs, c); + return new String(cs); + } + + private static boolean validates(String base, String value) throws Exception { + String xsd = + "" + + " " + + ""; + SchemaTypeLoader loader = XmlBeans.loadXsd(new XmlObject[]{SchemaDocument.Factory.parse(xsd)}); + XmlObject doc = loader.parse("" + value + "", null, null); + return doc.validate(); + } + + @Test + void overlongFloatIsReportedNotThrown() throws Exception { + // used to escape validate() as java.lang.IllegalArgumentException + assertFalse(validates("xs:float", tooLong('1'))); + } + + @Test + void overlongDoubleIsReportedNotThrown() throws Exception { + assertFalse(validates("xs:double", tooLong('1'))); + } + + @Test + void normalFloatingPointValuesStillValidate() throws Exception { + assertTrue(validates("xs:float", "1.5")); + assertTrue(validates("xs:double", "-3.25E7")); + } +} From 1b8907867b288865ab149f4ca18548c7d1df869d Mon Sep 17 00:00:00 2001 From: Aizal Khan Date: Thu, 13 Aug 2026 14:20:02 +0530 Subject: [PATCH 2/2] catch RuntimeException in float and double validateLexical --- .../java/org/apache/xmlbeans/impl/values/JavaDoubleHolder.java | 2 +- .../java/org/apache/xmlbeans/impl/values/JavaFloatHolder.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/xmlbeans/impl/values/JavaDoubleHolder.java b/src/main/java/org/apache/xmlbeans/impl/values/JavaDoubleHolder.java index 914e98c6e..56d16fa20 100644 --- a/src/main/java/org/apache/xmlbeans/impl/values/JavaDoubleHolder.java +++ b/src/main/java/org/apache/xmlbeans/impl/values/JavaDoubleHolder.java @@ -69,7 +69,7 @@ public static double validateLexical(String v, ValidationContext context, boolea int maxNumberOfCharsForNumbers) { try { return XsTypeConverter.lexDouble(v, strict, maxNumberOfCharsForNumbers); - } catch (IllegalArgumentException e) { + } catch (RuntimeException e) { context.invalid(XmlErrorCodes.DOUBLE, new Object[]{v}); return Double.NaN; diff --git a/src/main/java/org/apache/xmlbeans/impl/values/JavaFloatHolder.java b/src/main/java/org/apache/xmlbeans/impl/values/JavaFloatHolder.java index 54e35e438..48d6b7fc4 100644 --- a/src/main/java/org/apache/xmlbeans/impl/values/JavaFloatHolder.java +++ b/src/main/java/org/apache/xmlbeans/impl/values/JavaFloatHolder.java @@ -69,7 +69,7 @@ public static float validateLexical(String v, ValidationContext context, boolean int maxNumberOfChars) { try { return XsTypeConverter.lexFloat(v, strict, maxNumberOfChars); - } catch (IllegalArgumentException e) { + } catch (RuntimeException e) { context.invalid(XmlErrorCodes.FLOAT, new Object[]{v}); return Float.NaN;