JDK-6583583 : javax.swing.RowFilter.NumberFilter: incorrect comparison
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-07-20
  • Updated: 2021-11-23
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :


A DESCRIPTION OF THE PROBLEM :
javaw.swing.RowFilter.NumberFilter compares numbers of different Number subclasses incorrectly.

This code is wrong because possible overflow  and precision loss.

        private int longCompare(Number o) {
            long diff = number.longValue() - o.longValue();

            if (diff < 0) {
                return -1;
            }
            else if (diff > 0) {
                return 1;
            }
            return 0;
        }

(see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6582946)



REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.swing.RowFilter;
import javax.swing.RowFilter.ComparisonType;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

public class NumberFilter {
	RowFilter filter;

	@Before
	public void setUp() {
		filter = RowFilter.numberFilter(ComparisonType.AFTER, -10.5);
	}

	@Test
	@Ignore("just example how it should work")
	public void testNoOverflow() {
		Assert.assertTrue("overflow", filter.include(new MyEntry(new Double(Long.MAX_VALUE))));
	}

	@Test
	public void testOverflow() {
		Assert.assertTrue("overflow", filter.include(new MyEntry(Long.MAX_VALUE)));
	}

	@Test
	@Ignore("just example how it should work")
	public void testNoPrecisionLoss() {
		Assert.assertTrue("precision loss", filter.include(new MyEntry(-10.0)));
	}

	@Test
	public void testPrecisionLoss() {
		Assert.assertTrue("precision loss", filter.include(new MyEntry(-10L)));
	}
}
//-----
import javax.swing.RowFilter.Entry;

public class MyEntry extends Entry {
	private final Object _value;

	public MyEntry(Object value) {
		_value = value;
	}

	@Override
	public Object getIdentifier() {
		throw new UnsupportedOperationException();
	}

	@Override
	public Object getModel() {
		throw new UnsupportedOperationException();
	}

	@Override
	public Object getValue(int index) {
		return _value;
	}

	@Override
	public int getValueCount() {
		return 1;
	}

}

---------- END SOURCE ----------

Comments
EVALUATION The current is clearly incorrect, we should use the same pattern as Long.compareTo() uses
30-10-2007