You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by bu...@apache.org on 2005/01/12 19:02:03 UTC

DO NOT REPLY [Bug 33069] New: - EqualsBuilder.append(Object[], Object[]) incorrectly checks that rhs[i] is instance of lhs[i]'s class

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=33069>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=33069

           Summary: EqualsBuilder.append(Object[], Object[]) incorrectly
                    checks that rhs[i] is instance of lhs[i]'s class
           Product: Commons
           Version: 2.0 Final
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: PatchAvailable
          Severity: major
          Priority: P2
         Component: Lang
        AssignedTo: commons-dev@jakarta.apache.org
        ReportedBy: andrew@terracottatech.com


Append two arrays of any object type to an EqualsBuilder using EqualsBuilder.append(Object[], 
Object[]) -- we'll call the first 'lhs' and the second 'rhs'. If, for any i, lhs[i] is not null, rhs[i] is not null, 
and rhs[i] is not of the same type as, or a subtype of, lhs[i], then the EqualsBuilder will return false.

However, this behavior is incorrect. While rare, it is perfectly valid in Java to define an equals() method 
on a class A that will return true when passed in an object of some class B, where B is not the same as A 
nor a subtype of A. (A conceptual example is comparing a RGBColor to a CMYKColor, where RGBColor is 
not a subclass of CMYKColor, nor vice-versa. In this example, the EqualsBuilder will return false, 
whether the equals() method is defined on RGBColor to explicitly check CMYKColors, or even if you 
define a base-class Color.equals() method that does an abstract comparison.)

To reproduce:

public static class A {
  private int a;
  public A(int a) { this.a = a; }
  public boolean equals(Object o) {
    if (o == this) return true;
    if (o instanceof A) return this.a = ((A) o).getA();
    if (o instanceof B) return this.a = ((B) o).getB();
    return false;
  }
  public int getA() { return this.a; }
}

public static class B {
  private int b;
  public B(int b) { this.b = b; }
  public boolean equals(Object o) {
    if (o == this) return true;
    if (o instanceof A) return this.b = ((A) o).getA();
    if (o instanceof B) return this.b = ((B) o).getB();
    return false;
  }
  public int getB() { return this.b; }
}

Object[] x = new Object[] { new A(1) };
Object[] y = new Object[] { new B(1) };

System.err.println("x[0].equals(y[0])? " + x[0].equals(y[0]));
System.err.println("Does EqualsBuilder think the arrays are equal? " + (new EqualsBuilder().append(x, 
y).isEquals()));

This program will output:

true
false

The attached patch adds to an existing unit-test case some code that proves the existence of this bug, 
and also fixes it. (It also fixes bug 33067.)

-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org