]> granicus.if.org Git - icu/commitdiff
ICU-7645 Fixed problem in comparator exposed by Java 7.
authorMark Davis <mark@macchiato.com>
Wed, 5 Dec 2012 00:10:44 +0000 (00:10 +0000)
committerMark Davis <mark@macchiato.com>
Wed, 5 Dec 2012 00:10:44 +0000 (00:10 +0000)
X-SVN-Rev: 32924

icu4j/main/classes/core/src/com/ibm/icu/text/IdentifierInfo.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/text/SpoofCheckerTest.java

index fd94f999ec81b6ca494481e76491b4db3d3f9b32..a46143897c5b61e66b4c3f850b6c32a82f2561cf 100644 (file)
@@ -378,7 +378,7 @@ public class IdentifierInfo {
             if (diff != 0) return diff;
             int i0 = arg0.nextSetBit(0);
             int i1 = arg1.nextSetBit(0);
-            while ((diff = i0-i1) == 0) {
+            while ((diff = i0-i1) == 0 && i0 > 0) {
                 i0 = arg0.nextSetBit(i0+1);
                 i1 = arg1.nextSetBit(i1+1);
             }
index 7563351ef34dda1b4168c91ff1f7127d4cb5ef1f..61d56b8bfce03b1d25c3356c75b8b6292225cd5f 100644 (file)
@@ -13,9 +13,11 @@ import java.text.ParseException;
 import java.util.Arrays;
 import java.util.BitSet;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Random;
 import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -559,6 +561,60 @@ public class SpoofCheckerTest extends TestFmwk {
 //        getIdentifierProfile()
 //        setIdentifierProfile(UnicodeSet)
     }
+    
+    public void TestComparator() {
+        Random random = new Random(0);
+        for (int i = 0; i < 100; ++i) {
+            BitSet[] items = new BitSet[random.nextInt(5)+3];
+            for (int j = 0; j < items.length; ++j) {
+                items[j] = new BitSet();
+                int countInBitset = random.nextInt(5);
+                for (int k = 0; k < countInBitset; ++k) {
+                    items[j].set(random.nextInt(10));
+                }
+            }
+            checkComparator(IdentifierInfo.BITSET_COMPARATOR, items);
+        }
+    }
+    
+    // Dumb implementation for now
+    private <T> void checkComparator(Comparator<T> comparator, T... items) {
+        logln("Checking " + Arrays.asList(items));
+        /*
+         * The relation is transitive: a < b and b < c implies a < c. We test here.
+         * The relation is trichotomous: exactly one of a <  b, b < a and a = b is true. Guaranteed by comparator.
+         */
+        for (int i = 0; i < items.length-2; ++i) {
+            T a = items[i];
+            for (int j = i+1; j < items.length-1; ++j) {
+                T b = items[j];
+                for (int k = j+1; k < items.length; ++k) {
+                    T c = items[k];
+                    checkTransitivity(comparator, a, b, c);
+                    checkTransitivity(comparator, a, c, b);
+                    checkTransitivity(comparator, b, a, b);
+                    checkTransitivity(comparator, b, c, a);
+                    checkTransitivity(comparator, c, a, b);
+                    checkTransitivity(comparator, c, b, a);
+                }
+            }
+        }
+    }
+    
+    private <T> void checkTransitivity(Comparator<T> comparator, T a, T b, T c) {
+        int ab = comparator.compare(a,b);
+        int bc = comparator.compare(b,c);
+        int ca = comparator.compare(c,a);
+        if (!assertFalse("Transitive: " + a + ", " + b + ", " + c, 
+                ab < 0 && bc < 0 && ca <= 0)) {
+            // for debugging
+            comparator.compare(a,b);
+            comparator.compare(b,c);
+            comparator.compare(c,a);
+            assertFalse("Transitive: " + a + ", " + b + ", " + c, 
+                    ab < 0 && bc < 0 && ca <= 0);
+        }
+    }
 
     private String parseHex(String in) {
         StringBuilder sb = new StringBuilder();