Checker Clone

belongs to group Basic
Identify possibly incorrect object cloning implementations

Frameworks supported by this checker

  • java up to 11
  • android up to API level 28
  • dotnet

Warnings generated by this checker

  • CloneForNonCloneableWarning: method clone() is defined in a non-cloneable class [ CWE491 ]
  • NonFinalCloneMethodWarning: method clone() is not final, which allows object-hijack [ CWE491 ]
  • SubclassesMayBeClonedWarning: a subclass of a non-cloneable class may be cloned [ CWE491 ]

Options accepted by this checker

  • allowsCloningByExtension: allow non-cloneable classes to be cloned by implementating Cloneable in extensions
    This option allows one to extend a non-cloneable class and implement Cloneable, so that its objects can be cloned by using the clone() method of Object

Annotations understood by this checker

  • none


Description

This checker identifies frequent problems in the definition of the method clone(). That method is used to generate a clone of an object, that is, a distinct instance with the same behavior as the original one. The default implementation in java.lang.Object checks that the object to clone implements the interface java.lang.Cloneable or otherwise throws a java.lang.CloneNotSupportedException. Hence, in order to clone an object it is in general enough to implement that interface and use the default implementation of clone(). It is also possible to override that default implementation. Note that a class that inherits the default implementation allows its subclasses to implement java.lang.Cloneable and clone its instances.

Action: Check that clone() is only redefined in classes that implement java.lang.Cloneable. Check that the default implementation of clone() is only used for classes that have explicitly declared to implement java.lang.Cloneable.

This checker identifies frequent problems in the definition of the method Clone(). That method is used to generate a clone of an object, that is, a distinct instance with the same behavior as the original one. The default implementation in System.Object checks that the object to clone implements the interface System.ICloneable or otherwise throws a CloneNotSupportedException. Hence, in order to clone an object it is in general enough to implement that interface and use the default implementation of Clone(). It is also possible to override that default implementation. Note that a class that inherits the default implementation allows its subclasses to implement System.ICloneable and clone its instances.

Action: Check that Clone() is only redefined in classes that implement System.ICloneable. Check that the default implementation of Clone() is only used for classes that have explicitly declared to implement java.lang.Cloneable.

Examples

Consider the following classes:

public class TestClone1 {

  @Override
  public Object clone() {
    return new TestClone1();
  }
}

and

public class TestClone2 {
  private int data;
  private String s;

  public TestClone2(int data, String s) {
    this.data = data;
    this.s = s;
  }
}

This checker issues the following warning:

TestClone1.java:5: [Clone: CloneForNonCloneableWarning] Method clone() is defined here, but class TestClone1 does not implement java.lang.Cloneable

since it is unexpected to override the clone() method without implementing the java.lang.Cloneable interface.

If the allowsCloningByExtension option is set to false (its default is true), then this checker will also issue the following warning:

TestClone2.java:1: [Clone: SubclassesMayBeClonedWarning] Non-cloneable class TestClone2 allows one to define cloneable subclasses

since subclasses might exploit the default clone() method to get a complete dump of the private data of the class instances, as in the following example:

public class CloneableTestClone2 extends TestClone2 implements Cloneable {
  public CloneableTestClone2(int data, String s) {
    super(data, s);
  }
}

In this case, it is enough to define class TestClone2 as final, so that the previous exploit cannot be accomplished and Julia will not issue the second warning.

Consider the following classes:


namespace DocumentationExamples
{

    public class Clone1
    {
        public static void Main(string[] args)
        { }

        public object Clone()
        {
            return new Clone1();
        }
    }
}

This checker issues the following warning:

DocumentationExamples.cs:11: [Clone: CloneForNonCloneableWarning] Method "Clone" is defined here, but class "Clone1" is not declared as cloneable

since it is unexpected to override the Clone() method without implementing the System.ICloneable interface.