JD.CAST.DOWNCAST

Possible ClassCastException for subtypes

JD.CAST.DOWNCAST is triggered when an object of type B is cast to type C, where B and C are sub types of Object A.

Vulnerability and risk

This can cause a ClassCastException because a base class can have multiple child classes.

Vulnerable code example 1

10  class TestVar {}
11  class TestVar1 extends TestVar {
12   TestVar display() {
13       return new TestVar1();
14   }
15  }
16  class TestVar2 extends TestVar {
17   TestVar display() {
18       return new TestVar2();
19   }
20  } 
21  public class DownCast {
22   public void cast() {
23       TestVar var = new TestVar1();
24       TestVar2 var2 = (TestVar2)var.display();       
25   }
26  }

Klocwork reports a JD.CAST.DOWNCAST defect at line 24, indicating, "TestVar2 var2 = (TestVar2)var.display(): Suspicious cast of 'TestVar1' to 'TestVar2', where 'TestVar2' is a subtype of 'TestVar'. This Object can hold other subtypes as well which can cause a ClassCastException."

Fixed code example 1

10  class TestVar {}
11  class TestVar1 extends TestVar {
12   TestVar display() {
13       return new TestVar1();
14   }
15  }
16  class TestVar2 extends TestVar {
17   TestVar display() {
18       return new TestVar2();
19   }
20  } 
21  public class DownCast {
22   public void cast() {
23       TestVar var = new TestVar1();
24       TestVar var2 = var.display();
25       if (var2 instanceOf TestVar2){
26         TestVar2 testVar2 = (TestVar2)var2;
27       }          
28   }
29  }

In this example, Klocwork no longer reports a defect because we check the Object with InstanceOf on line 25: if (var2 instanceOf TestVar2), and after that we type cast the object on line 26: TestVar2 testVar2 = (TestVar2)v2;.

Vulnerable code example 2

10  class TestVar {
11   TestVar display() {
12       return new TestVar();
13   }
14  }
15  class TestVar1 extends TestVar {
16   TestVar display() {
17       return new TestVar1();
18   }
19  }
20  public class DownCast {
21   public void cast() {
22       TestVar var = new TestVar();
23       TestVar1 var1 = (TestVar1) var.display();
24   }
25  }

Klocwork reports a JD.CAST.DOWNCAST defect at line 23, indicating, "TestVar1 var1 = (TestVar1)var.display(): Suspicious cast of 'TestVar' to 'TestVar1', where 'TestVar1' is subtype of 'TestVar'. This Object can hold other subtypes as well which can cause ClassCastException."

Fixed code example 2

10  class TestVar {
11   TestVar display() {
12       return new TestVar();
13   }
14  }
15  class TestVar1 extends TestVar {
16   TestVar display() {
17       return new TestVar1();
18   }
19  }
20  public class DownCast {
21   public void cast() {
22       TestVar var = new TestVar();
23       TestVar var1 = var.display();
24       if (var1 instanceOf TestVar1){
25         TestVar1 testVar1 = (TestVar1)var1;
26       }
27   }
28  }

In this example, Klocwork no longer reports a defect because we check the Object with InstanceOf on line 24: if (var1 instanceOf TestVar1), and after that we type cast the object on line 25: TestVar1 testVar1 = (TestVar1)var1;.

Related checkers