diff --git a/src/main/java/org/apache/xmlbeans/GDate.java b/src/main/java/org/apache/xmlbeans/GDate.java index 90e0ed816..b854e99bd 100644 --- a/src/main/java/org/apache/xmlbeans/GDate.java +++ b/src/main/java/org/apache/xmlbeans/GDate.java @@ -16,6 +16,7 @@ package org.apache.xmlbeans; import org.apache.xmlbeans.impl.util.ExceptionUtil; +import org.apache.xmlbeans.impl.util.MathUtil; import java.math.BigDecimal; import java.math.BigInteger; @@ -274,7 +275,7 @@ public GDate(CharSequence string) { } } try { - fs = new BigDecimal(string.subSequence(start, len).toString()); + fs = MathUtil.parseAsBigDecimal(string.subSequence(start, len).toString()); } catch (Throwable e) { if (ExceptionUtil.isFatal(e)) { ExceptionUtil.rethrow(e); diff --git a/src/main/java/org/apache/xmlbeans/GDuration.java b/src/main/java/org/apache/xmlbeans/GDuration.java index eb9255dd6..c5e232c1b 100644 --- a/src/main/java/org/apache/xmlbeans/GDuration.java +++ b/src/main/java/org/apache/xmlbeans/GDuration.java @@ -15,6 +15,8 @@ package org.apache.xmlbeans; +import org.apache.xmlbeans.impl.util.MathUtil; + import java.math.BigDecimal; /** @@ -131,7 +133,7 @@ public GDuration(CharSequence str) int i = start; do i += 1; while (i < len && GDate.isDigit(ch = str.charAt(i))); - _fs = new BigDecimal(str.subSequence(start, i).toString()); + _fs = MathUtil.parseAsBigDecimal(str.subSequence(start, i).toString()); if (i >= len || ch != 'S') throw new IllegalArgumentException("illegal duration"); start = i; diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/BuiltinSchemaTypeSystem.java b/src/main/java/org/apache/xmlbeans/impl/schema/BuiltinSchemaTypeSystem.java index 2455e71f7..de16f8600 100644 --- a/src/main/java/org/apache/xmlbeans/impl/schema/BuiltinSchemaTypeSystem.java +++ b/src/main/java/org/apache/xmlbeans/impl/schema/BuiltinSchemaTypeSystem.java @@ -17,6 +17,7 @@ import org.apache.xmlbeans.*; import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.util.MathUtil; import org.apache.xmlbeans.impl.values.XmlIntegerImpl; import org.apache.xmlbeans.impl.values.XmlStringImpl; import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException; @@ -165,7 +166,7 @@ public static SchemaTypeSystem get() build_wsstring(SchemaType.WS_COLLAPSE), null, null }; private final static XmlValueRef[] FACETS_UNSIGNED_LONG = new XmlValueRef[] - { null, null, null, null, buildInteger(BigInteger.ZERO), buildInteger(new BigInteger("18446744073709551615")), null, null, buildNnInteger(BigInteger.ZERO), + { null, null, null, null, buildInteger(BigInteger.ZERO), buildInteger(MathUtil.parseAsBigInteger("18446744073709551615")), null, null, buildNnInteger(BigInteger.ZERO), build_wsstring(SchemaType.WS_COLLAPSE), null, null }; private final static XmlValueRef[] FACETS_UNSIGNED_INT = new XmlValueRef[] diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/StscTranslator.java b/src/main/java/org/apache/xmlbeans/impl/schema/StscTranslator.java index e69a35660..a23795ecd 100644 --- a/src/main/java/org/apache/xmlbeans/impl/schema/StscTranslator.java +++ b/src/main/java/org/apache/xmlbeans/impl/schema/StscTranslator.java @@ -19,6 +19,7 @@ import org.apache.xmlbeans.impl.common.QNameHelper; import org.apache.xmlbeans.impl.common.XMLChar; import org.apache.xmlbeans.impl.schema.StscImporter.SchemaToProcess; +import org.apache.xmlbeans.impl.util.MathUtil; import org.apache.xmlbeans.impl.values.NamespaceContext; import org.apache.xmlbeans.impl.values.XmlNonNegativeIntegerImpl; import org.apache.xmlbeans.impl.values.XmlPositiveIntegerImpl; @@ -1511,8 +1512,8 @@ static BigInteger buildBigInt(XmlAnySimpleType value) { String text = value.getStringValue(); BigInteger bigInt; try { - bigInt = new BigInteger(text); - } catch (NumberFormatException e) { + bigInt = MathUtil.parseAsBigInteger(text); + } catch (Exception e) { StscState.get().error(XmlErrorCodes.INVALID_VALUE_DETAIL, new Object[]{text, "nonNegativeInteger", e.getMessage()}, value); return null; } diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/XQuerySchemaTypeSystem.java b/src/main/java/org/apache/xmlbeans/impl/schema/XQuerySchemaTypeSystem.java index 2359ed782..e307c827d 100644 --- a/src/main/java/org/apache/xmlbeans/impl/schema/XQuerySchemaTypeSystem.java +++ b/src/main/java/org/apache/xmlbeans/impl/schema/XQuerySchemaTypeSystem.java @@ -17,6 +17,7 @@ import org.apache.xmlbeans.*; import org.apache.xmlbeans.impl.common.QNameHelper; +import org.apache.xmlbeans.impl.util.MathUtil; import org.apache.xmlbeans.impl.values.XmlIntegerImpl; import org.apache.xmlbeans.impl.values.XmlStringImpl; import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException; @@ -185,7 +186,7 @@ public static SchemaTypeSystem get() { build_wsstring(SchemaType.WS_COLLAPSE), null, null}; private final static XmlValueRef[] FACETS_UNSIGNED_LONG = new XmlValueRef[] - {null, null, null, null, buildInteger(BigInteger.ZERO), buildInteger(new BigInteger("18446744073709551615")), null, null, buildNnInteger(BigInteger.ZERO), + {null, null, null, null, buildInteger(BigInteger.ZERO), buildInteger(MathUtil.parseAsBigInteger("18446744073709551615")), null, null, buildNnInteger(BigInteger.ZERO), build_wsstring(SchemaType.WS_COLLAPSE), null, null}; private final static XmlValueRef[] FACETS_UNSIGNED_INT = new XmlValueRef[] diff --git a/src/main/java/org/apache/xmlbeans/impl/util/MathUtil.java b/src/main/java/org/apache/xmlbeans/impl/util/MathUtil.java index 76776fe00..ad723fc97 100644 --- a/src/main/java/org/apache/xmlbeans/impl/util/MathUtil.java +++ b/src/main/java/org/apache/xmlbeans/impl/util/MathUtil.java @@ -16,6 +16,9 @@ Licensed to the Apache Software Foundation (ASF) under one or more ==================================================================== */ package org.apache.xmlbeans.impl.util; +import java.math.BigDecimal; +import java.math.BigInteger; + /** * Internal Use Only. Utility methods for dealing with conversions */ @@ -47,4 +50,41 @@ public static int safeDoubleToInt(double d) { } return (int) d; } + + // TODO try to make this configurable + private static final int MAX_NUMBER_LENGTH = 1024; + + /** + * @param s string to parse + * @return valid BigDecimal + * @throws NumberFormatException if parse fails + * @throws IllegalArgumentException if string is too long + * @throws NullPointerException if string is null + */ + public static BigDecimal parseAsBigDecimal(String s) { + if (s == null) { + throw new NullPointerException("Cannot parse null as BigDecimal"); + } + if (s.length() > MAX_NUMBER_LENGTH) { + throw new IllegalArgumentException("Number has more than " + MAX_NUMBER_LENGTH + " characters"); + } + return new BigDecimal(s); + } + + /** + * @param s string to parse + * @return valid BigInteger + * @throws NumberFormatException if parse fails + * @throws IllegalArgumentException if string is too long + * @throws NullPointerException if string is null + */ + public static BigInteger parseAsBigInteger(String s) { + if (s == null) { + throw new NullPointerException("Cannot parse null as BigInteger"); + } + if (s.length() > MAX_NUMBER_LENGTH) { + throw new IllegalArgumentException("Number has more than " + MAX_NUMBER_LENGTH + " characters"); + } + return new BigInteger(s); + } } diff --git a/src/main/java/org/apache/xmlbeans/impl/util/XsTypeConverter.java b/src/main/java/org/apache/xmlbeans/impl/util/XsTypeConverter.java index c9473893d..bd6a7354f 100644 --- a/src/main/java/org/apache/xmlbeans/impl/util/XsTypeConverter.java +++ b/src/main/java/org/apache/xmlbeans/impl/util/XsTypeConverter.java @@ -248,7 +248,7 @@ public static BigDecimal lexDecimal(CharSequence cs, boolean allowExponent) //equals() method, but the xml value //space does not consider them significant. //See http://www.w3.org/2001/05/xmlschema-errata#e2-44 - return new BigDecimal(trimTrailingZeros(v)); + return MathUtil.parseAsBigDecimal(trimTrailingZeros(v)); } private static final char[] CH_ZEROS = new char[]{'0', '0', '0', '0', '0', '0', '0', '0', @@ -308,7 +308,7 @@ public static BigInteger lexInteger(CharSequence cs) //TODO: consider special casing zero and one to return static values //from BigInteger to avoid object creation. - return new BigInteger(trimInitialPlus(v)); + return MathUtil.parseAsBigInteger(trimInitialPlus(v)); } public static BigInteger lexInteger(CharSequence cs, Collection errors) { diff --git a/src/main/java/org/apache/xmlbeans/impl/validator/Validator.java b/src/main/java/org/apache/xmlbeans/impl/validator/Validator.java index 4b62a81be..af956d3e8 100644 --- a/src/main/java/org/apache/xmlbeans/impl/validator/Validator.java +++ b/src/main/java/org/apache/xmlbeans/impl/validator/Validator.java @@ -20,6 +20,7 @@ import org.apache.xmlbeans.impl.schema.SchemaTypeImpl; import org.apache.xmlbeans.impl.schema.SchemaTypeVisitorImpl; import org.apache.xmlbeans.impl.util.ExceptionUtil; +import org.apache.xmlbeans.impl.util.MathUtil; import org.apache.xmlbeans.impl.util.XsTypeConverter; import org.apache.xmlbeans.impl.values.*; @@ -1108,7 +1109,7 @@ private void validateAtomicType( } if (errorState == _errorState) { - _decimalValue = new BigDecimal(value); + _decimalValue = MathUtil.parseAsBigDecimal(value); JavaDecimalHolderEx.validateValue(_decimalValue, type, _vc); } diff --git a/src/main/java/org/apache/xmlbeans/impl/values/JavaDecimalHolder.java b/src/main/java/org/apache/xmlbeans/impl/values/JavaDecimalHolder.java index 03b4f9f9d..afb93b045 100644 --- a/src/main/java/org/apache/xmlbeans/impl/values/JavaDecimalHolder.java +++ b/src/main/java/org/apache/xmlbeans/impl/values/JavaDecimalHolder.java @@ -20,6 +20,7 @@ import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.impl.common.ValidationContext; import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; +import org.apache.xmlbeans.impl.util.MathUtil; import org.apache.xmlbeans.impl.util.XsTypeConverter; import java.math.BigDecimal; @@ -47,8 +48,8 @@ protected void set_text(String s) { } try { - set_BigDecimal(new BigDecimal(s)); - } catch (NumberFormatException e) { + set_BigDecimal(MathUtil.parseAsBigDecimal(s)); + } catch (Exception e) { _voorVc.invalid(XmlErrorCodes.DECIMAL, new Object[]{s}); } } @@ -70,8 +71,8 @@ public static void validateLexical(String v, ValidationContext context, boolean // long-standing lenient behaviour: accept whatever BigDecimal accepts, // which includes scientific/exponent notation such as "1E5". try { - new BigDecimal(v); - } catch (NumberFormatException e) { + MathUtil.parseAsBigDecimal(v); + } catch (Exception e) { context.invalid(XmlErrorCodes.DECIMAL, new Object[]{v}); } return; diff --git a/src/main/java/org/apache/xmlbeans/impl/values/JavaDecimalHolderEx.java b/src/main/java/org/apache/xmlbeans/impl/values/JavaDecimalHolderEx.java index 6cc6dd2e0..70c4b8d03 100644 --- a/src/main/java/org/apache/xmlbeans/impl/values/JavaDecimalHolderEx.java +++ b/src/main/java/org/apache/xmlbeans/impl/values/JavaDecimalHolderEx.java @@ -20,6 +20,7 @@ import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.impl.common.QNameHelper; import org.apache.xmlbeans.impl.common.ValidationContext; +import org.apache.xmlbeans.impl.util.MathUtil; import java.math.BigDecimal; import java.math.RoundingMode; @@ -44,8 +45,8 @@ protected void set_text(String s) { BigDecimal v = null; try { - v = new BigDecimal(s); - } catch (NumberFormatException e) { + v = MathUtil.parseAsBigDecimal(s); + } catch (Exception e) { _voorVc.invalid(XmlErrorCodes.DECIMAL, new Object[]{s}); } @@ -83,7 +84,6 @@ public static void validateLexical(String v, SchemaType sType, ValidationContext /** * Performs facet validation only. */ - public static void validateValue(BigDecimal v, SchemaType sType, ValidationContext context) { // fractional digits XmlObject fd = sType.getFacet(SchemaType.FACET_FRACTION_DIGITS); diff --git a/src/main/java/org/apache/xmlbeans/impl/values/JavaIntegerHolder.java b/src/main/java/org/apache/xmlbeans/impl/values/JavaIntegerHolder.java index 2bb115669..6edd803ef 100644 --- a/src/main/java/org/apache/xmlbeans/impl/values/JavaIntegerHolder.java +++ b/src/main/java/org/apache/xmlbeans/impl/values/JavaIntegerHolder.java @@ -21,6 +21,7 @@ import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.impl.common.ValidationContext; import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem; +import org.apache.xmlbeans.impl.util.MathUtil; import java.math.BigDecimal; import java.math.BigInteger; @@ -49,7 +50,7 @@ public static BigInteger lex(String s, ValidationContext vc) { } try { - return new BigInteger(s); + return MathUtil.parseAsBigInteger(s); } catch (Exception e) { vc.invalid(XmlErrorCodes.INTEGER, new Object[]{s}); return null; diff --git a/src/main/java/org/apache/xmlbeans/impl/xsd2inst/SampleXmlUtil.java b/src/main/java/org/apache/xmlbeans/impl/xsd2inst/SampleXmlUtil.java index 11939da0d..939f0cc84 100644 --- a/src/main/java/org/apache/xmlbeans/impl/xsd2inst/SampleXmlUtil.java +++ b/src/main/java/org/apache/xmlbeans/impl/xsd2inst/SampleXmlUtil.java @@ -26,6 +26,7 @@ import org.apache.xmlbeans.*; import org.apache.xmlbeans.impl.util.HexBin; +import org.apache.xmlbeans.impl.util.MathUtil; import org.apache.xmlbeans.soap.SOAPArrayType; import org.apache.xmlbeans.soap.SchemaWSDLArrayType; @@ -382,7 +383,7 @@ private String formatToLength(String s, SchemaType sType) { } private String formatDecimal(String start, SchemaType sType) { - BigDecimal result = new BigDecimal(start); + BigDecimal result = MathUtil.parseAsBigDecimal(start); XmlDecimal xmlD; xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); BigDecimal min = xmlD != null ? xmlD.getBigDecimalValue() : null; @@ -414,7 +415,7 @@ private String formatDecimal(String start, SchemaType sType) { for (int i = 0; i < totalDigits; i++) { sb.append('9'); } - BigDecimal digitsLimit = new BigDecimal(sb.toString()); + BigDecimal digitsLimit = MathUtil.parseAsBigDecimal(sb.toString()); if (max != null && max.compareTo(digitsLimit) > 0) { max = digitsLimit; maxInclusive = true; @@ -445,7 +446,7 @@ private String formatDecimal(String start, SchemaType sType) { sb.append('0'); } sb.append('1'); - increment = new BigDecimal(sb.toString()); + increment = MathUtil.parseAsBigDecimal(sb.toString()); } else { increment = BigDecimal.ONE; }