This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch fix/CAMEL-24976 in repository https://gitbox.apache.org/repos/asf/camel.git
commit 24196b406e548e3d4e63e286e29f1b4f24d644c7 Author: Claus Ibsen <[email protected]> AuthorDate: Wed Sep 23 21:48:47 2026 +0200 CAMEL-24976: type converter - fix number conversions in ObjectConverter - String to Number failed for values below Integer.MIN_VALUE, returned a Long for Integer.MAX_VALUE, and did not support exponent notation. - Converting a BigDecimal, or a double larger than a long, to BigInteger went through longValue() and returned a wrong value. - byte[] to char sign-extended bytes above 127. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../apache/camel/converter/ObjectConverter.java | 28 ++++++++++++---------- .../camel/converter/ObjectConverterTest.java | 17 +++++++++++++ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/core/camel-base/src/main/java/org/apache/camel/converter/ObjectConverter.java b/core/camel-base/src/main/java/org/apache/camel/converter/ObjectConverter.java index fc365e117c11..9c3bc24cfde7 100644 --- a/core/camel-base/src/main/java/org/apache/camel/converter/ObjectConverter.java +++ b/core/camel-base/src/main/java/org/apache/camel/converter/ObjectConverter.java @@ -16,6 +16,7 @@ */ package org.apache.camel.converter; +import java.math.BigDecimal; import java.math.BigInteger; import java.util.Iterator; @@ -133,8 +134,8 @@ public final class ObjectConverter { if (value.length != 1) { throw new IllegalArgumentException("byte[] must have exactly a length of 1: " + value.length); } - byte b = value[0]; - return (char) b; + // a byte is signed, so mask to avoid sign extension of values above 127 + return (char) (value[0] & 0xFF); } @Converter(order = 14) @@ -233,12 +234,15 @@ public final class ObjectConverter { return new BigInteger(str); } - Long num = null; - if (value instanceof Number number) { - num = number.longValue(); - } - if (num != null) { - return BigInteger.valueOf(num); + if (value instanceof BigInteger bi) { + return bi; + } else if (value instanceof BigDecimal bd) { + return bd.toBigInteger(); + } else if (value instanceof Double || value instanceof Float) { + // use big decimal to not lose precision for values larger than a long + return new BigDecimal(((Number) value).doubleValue()).toBigInteger(); + } else if (value instanceof Number number) { + return BigInteger.valueOf(number.longValue()); } else { return null; } @@ -329,14 +333,14 @@ public final class ObjectConverter { @Converter(order = 39) public static Number toNumber(String text) { // what kind of numeric is it - boolean dot = text.indexOf('.') != -1; - if (dot) { + boolean decimal = text.indexOf('.') != -1 || text.indexOf('e') != -1 || text.indexOf('E') != -1; + if (decimal) { return Double.parseDouble(text); } else { // its either a long or integer value (lets just avoid bytes) long lon = Long.parseLong(text); - if (lon < Integer.MAX_VALUE) { - return Integer.valueOf(text); + if (lon >= Integer.MIN_VALUE && lon <= Integer.MAX_VALUE) { + return (int) lon; } else { return lon; } diff --git a/core/camel-core/src/test/java/org/apache/camel/converter/ObjectConverterTest.java b/core/camel-core/src/test/java/org/apache/camel/converter/ObjectConverterTest.java index 7d76d07a217e..e818aee68263 100644 --- a/core/camel-core/src/test/java/org/apache/camel/converter/ObjectConverterTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/converter/ObjectConverterTest.java @@ -16,6 +16,7 @@ */ package org.apache.camel.converter; +import java.math.BigDecimal; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.util.Date; @@ -146,6 +147,10 @@ public class ObjectConverterTest { assertNull(ObjectConverter.toBigInteger(Float.NaN)); assertEquals(BigInteger.valueOf(4), ObjectConverter.toBigInteger(Long.valueOf("4"))); assertEquals(new BigInteger("14350442579497085228"), ObjectConverter.toBigInteger("14350442579497085228")); + assertEquals(new BigInteger("123456789012345678901234"), + ObjectConverter.toBigInteger(new BigDecimal("123456789012345678901234.56"))); + assertEquals(new BigInteger("100000000000000000000"), ObjectConverter.toBigInteger(1e20)); + assertEquals(BigInteger.ONE, ObjectConverter.toBigInteger(1.9d)); } @Test @@ -162,6 +167,7 @@ public class ObjectConverterTest { assertEquals('A', ObjectConverter.toChar("A".getBytes(StandardCharsets.UTF_8))); assertEquals(Character.valueOf('A'), ObjectConverter.toCharacter("A")); assertEquals(Character.valueOf('A'), ObjectConverter.toCharacter("A".getBytes(StandardCharsets.UTF_8))); + assertEquals('\u00e9', ObjectConverter.toChar(new byte[] { (byte) 0xE9 })); } @Test @@ -195,4 +201,15 @@ public class ObjectConverterTest { assertThrows(IllegalArgumentException.class, () -> ObjectConverter.toBool("yes"), "Should throw exception"); } + @Test + public void testToNumber() { + assertEquals(123, ObjectConverter.toNumber("123")); + assertEquals(Integer.MAX_VALUE, ObjectConverter.toNumber("2147483647")); + assertEquals(Integer.MIN_VALUE, ObjectConverter.toNumber("-2147483648")); + assertEquals(2147483648L, ObjectConverter.toNumber("2147483648")); + assertEquals(-3000000000L, ObjectConverter.toNumber("-3000000000")); + assertEquals(1.5d, ObjectConverter.toNumber("1.5")); + assertEquals(1e5d, ObjectConverter.toNumber("1e5")); + assertEquals(2.5e-3d, ObjectConverter.toNumber("2.5E-3")); + } }
