[ 
https://issues.apache.org/jira/browse/CONFIGURATION-766?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16962517#comment-16962517
 ] 

Alex Herbert commented on CONFIGURATION-766:
--------------------------------------------

If this method is to be made more correct then the use of the BigDecimal double 
constructor does not allow all long integer values to be converted either 
(since double cannot represent every long). Same for BigInteger. These also 
fail in the current method:

{code:java}
@Test
public void testToBigDecimalLongConstructor()
{
    final long l = Long.MAX_VALUE;
    assertEquals("Incorrect BigDecimal value", new BigDecimal(l), 
        PropertyConverter.toBigDecimal(l));
}

@Test
public void testToBigDecimalBigIntegerConstructor()
{
    final BigInteger value = BigInteger.ONE.shiftLeft(64).add(BigInteger.ONE);
    assertEquals("Incorrect BigDecimal value", new BigDecimal(value), 
        PropertyConverter.toBigDecimal(value));
}
{code}

To fix this we can handle the expected return values from toNumber. These are 
either a BigDecimal (already done), a BigInteger or the object was already a 
Number instance. The case of BigInteger requires another instanceof check. To 
determine how to convert the remaining Number instances is a choice between the 
long or double representation. A simple solution is to round-trip to string and 
construct from that:

{code}
public static BigDecimal toBigDecimal(final Object value) throws 
ConversionException
{
    final Number n = toNumber(value, BigDecimal.class);
    if (n instanceof BigDecimal)
    {
        return (BigDecimal) n;
    }
    if (n instanceof BigInteger)
    {
        return new BigDecimal((BigInteger) n);
    }
    // At this point the returned Number from toNumber() was already an 
instanceof Number.
    // The BigDecimal can be constructed from the number's long or double 
representation.
    // Use the String constructor to allow all long values to be represented 
and correctly
    // round double values (avoiding the BigDecimal(double) constructor).
    return new BigDecimal(n.toString());
}
{code}

> BigDecimal(double) should not be used
> -------------------------------------
>
>                 Key: CONFIGURATION-766
>                 URL: https://issues.apache.org/jira/browse/CONFIGURATION-766
>             Project: Commons Configuration
>          Issue Type: Bug
>         Environment: A single occurrence in file PropertyConverter.java, line 
> 393:
> {code:java}
> return new BigDecimal(n.doubleValue());
> {code}
>            Reporter: Haris Adzemovic
>            Assignee: Rob Tompkins
>            Priority: Minor
>
> Static analysis with SonarQube shows a violation of ruleĀ 
> [S2111|[https://rules.sonarsource.com/java/type/Bug/RSPEC-2111]] - a 
> dangerous use of the BigDecimal constructor.
> Fixed by using BigDecimal.valueOf(param) instead.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to