Search code examples
javasecuritybigdecimaleffective-java

BigDecimal is extendable and has no copy-constructor. Is that a security risk?


According to Effective Java Item 24 (Make defensive copies when needed) mutable objects pose a security risk, especially when passed as constructor arguments. One is encouraged to make defensive copies as necessary.

BigDecimal is meant to be immutable, but it is not final. According to Effective Java Item 15 (Minimise mutability), a class cannot be immutable unless it is final or all of its constructors are non-extendable.

To make matters worse, BigDecimal doesn't provide a copy constructor.

So, do BigDecimal arguments pose a security risk? Should one go through the painful process of invoking new BigDecimal(untrusted.toString())?


Solution

  • According to https://stackoverflow.com/a/33463772/14731:

    As discussed in Effective Java, Item 13, Favor Immutability, this was a design oversight when the class was written

    According to https://stackoverflow.com/a/12600683/14731 BigDecimal does pose a security risk and defensive copies should be made as necessary.

    Looks like the quickest way to create a defensive copy is:

    public static BigDecimal copyOf(BigDecimal value)
    {
        if (value == null || value.getClass() == BigDecimal.class)
            return value;
        return new BigDecimal(value.unscaledValue(), value.scale());
    }
    

    UPDATE: Apparently this is now explicitly discussed in Effective Java 3rd edition, Item 17 (Minimize Mutability).