...
Code Block | ||
---|---|---|
| ||
class CalendarSubclass extends Calendar { @Override public boolean after(Object when) { if(when instanceof Calendar && super.compareTo((Calendar)when) == 0) { // correctly calls Calendar.compareTo() return true; } return super.after(when); // Calls CalendarSubclass.compareTo() instead of Calendar.compareTo() } @Override public int compareTo(Calendar anotherCalendar) { // This method is erroneously invoked by Calendar.after() return compareTo(anotherCalendar.getFirstDayOfWeek(), anotherCalendar); } private int compareTo(int firstDayOfWeek, Calendar c) { int thisTime = c.get(Calendar.DAY_OF_WEEK); return (thisTime > firstDayOfWeek) ? 1 : (thisTime == firstDayOfWeek) ? 0 : -1; } public static void main(String[] args) { CalendarSubclass cs1 = new CalendarSubclass(); CalendarSubclass cs2 = new CalendarSubclass(); cs1.setTime(new Date()); System.out.println(cs1.after(cs2)); // prints false } // Implementation of other abstract methods } // The implementation of java.util.Calendar.after() method is shown below public boolean after(Object when) { return when instanceof Calendar && compareTo((Calendar)when) > 0; // forwards to the subclass's implementation erroneously } |
...
Code Block | ||
---|---|---|
| ||
// The CalendarImplementation object is a concrete implementation of the abstract Calendar class // Class ForwardingCalendar public class ForwardingCalendar { private final CalendarImplementation c; public ForwardingCalendar(CalendarImplementation c) { this.c = c; } public boolean after(Object when) { return c.after(when); } public int compareTo(Calendar anotherCalendar) { // CalendarImplementation.compareTo() will be called return c.compareTo(anotherCalendar); } } //Class CompositeCalendar class CompositeCalendar extends ForwardingCalendar { public CompositeCalendar(CalendarImplementation ci) { super(ci); } @Override public boolean after(Object when) { if(when instanceof Calendar && super.compareTo((Calendar)when) == 0) { // This will call the overridden version // i.e. CompositeClass.compareTo(); // Return true if it is the first day of week return true; } return super.after(when); // Does not compare with first day of week anymore; // Uses default comparison with epoch } @Override public int compareTo(Calendar anotherCalendar) { // CompositeCalendar.compareTo() will not be called now return compareTo(anotherCalendar.getFirstDayOfWeek(), anotherCalendar); } private int compareTo(int firstDayOfWeek, Calendar c) { int thisTime = c.get(Calendar.DAY_OF_WEEK); return (thisTime > firstDayOfWeek) ? 1 : (thisTime == firstDayOfWeek) ? 0 : -1; } public static void main(String[] args) { CalendarImplementation ci1 = new CalendarImplementation(); CalendarImplementation ci2 = new CalendarImplementation(); CompositeCalendar c = new CompositeCalendar(ci1); ci1.setTime(new Date()); System.out.println(c.after(ci2)); // prints true } } |
...
Search for vulnerabilities resulting from the violation of this guideline on the CERT website.
References
Wiki Markup |
---|
\[[SCG 07|AA. Java References#SCG 07]\] Guideline 1-3 Understand how a superclass can affect subclass behavior \[[Bloch 08|AA. Java References#Bloch 08]\] Item 16: "Favor composition over inheritance" \[[Gamma 95|AA. Java References#Gamma 95]\] \[[Lieberman 86|AA. Java References#Lieberman 86]\] |
...