8005277: Regression in JDK 7 in Bidi implementation
authorpeytoia
Fri, 28 Dec 2012 15:07:08 +0900
changeset 14927 c05c961b1dbd
parent 14926 1cb5d2255451
child 14928 afdc82e5403a
8005277: Regression in JDK 7 in Bidi implementation Reviewed-by: okutsu
jdk/src/share/classes/sun/text/bidi/BidiBase.java
jdk/test/java/text/Bidi/BidiConformance.java
jdk/test/java/text/Bidi/Bug8005277.java
--- a/jdk/src/share/classes/sun/text/bidi/BidiBase.java	Fri Dec 28 14:13:10 2012 +0900
+++ b/jdk/src/share/classes/sun/text/bidi/BidiBase.java	Fri Dec 28 15:07:08 2012 +0900
@@ -3251,10 +3251,9 @@
     {
         verifyValidParaOrLine();
         BidiLine.getRuns(this);
-        if (runCount == 1) {
+        if (run < 0 || run >= runCount) {
             return getParaLevel();
         }
-        verifyIndex(run, 0, runCount);
         getLogicalToVisualRunsMap();
         return runs[logicalToVisualRunsMap[run]].level;
     }
--- a/jdk/test/java/text/Bidi/BidiConformance.java	Fri Dec 28 14:13:10 2012 +0900
+++ b/jdk/test/java/text/Bidi/BidiConformance.java	Fri Dec 28 15:07:08 2012 +0900
@@ -656,7 +656,6 @@
                        baseIsLTR4Constructor1[textNo][testNo],
                        isLTR_isRTL4Constructor1[textNo][0][testNo],
                        isLTR_isRTL4Constructor1[textNo][1][testNo]);
-System.out.println(bidi.toString());
     }
 
     private void callTestEachMethod4Constructor2(int textNo,
@@ -668,7 +667,6 @@
                        baseIsLTR4Constructor2[textNo][flagNo],
                        isLTR_isRTL4Constructor2[textNo][0][flagNo],
                        isLTR_isRTL4Constructor2[textNo][1][flagNo]);
-System.out.println(bidi.toString());
     }
 
     private void callTestEachMethod4Constructor3(int textNo,
@@ -680,7 +678,6 @@
                        baseIsLTR4Constructor3[textNo][dataNo],
                        isLTR_isRTL4Constructor3[textNo][0][dataNo],
                        isLTR_isRTL4Constructor3[textNo][1][dataNo]);
-System.out.println(bidi.toString());
     }
 
     private StringBuilder sb = new StringBuilder();
@@ -934,59 +931,145 @@
         System.out.println("*** Test getRunLevel()");
 
         String str = "ABC 123";
-        int length = str.length();
         Bidi bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
-
         try {
-            if (bidi.getRunLevel(-1) != 0 ||  // runCount - 2
+            if (bidi.getRunLevel(-1) != 0 ||  // runCount - 2 (out of range)
                 bidi.getRunLevel(0) != 0 ||   // runCount - 1
-                bidi.getRunLevel(1) != 0 ||   // runCount
-                bidi.getRunLevel(2) != 0) {   // runCount + 1
-                errorHandling("getRunLevel() should return 0" +
-                    " when getRunCount() is 1.");
+                bidi.getRunLevel(1) != 0 ||   // runCount     (out of range)
+                bidi.getRunLevel(2) != 0) {   // runCount + 1 (out of range)
+                errorHandling("Incorrect getRunLevel() value(s).");
             }
         }
         catch (Exception e) {
-            errorHandling("getRunLevel() should not throw an exception " +
-                "when getRunCount() is 1.");
+            errorHandling("getRunLevel() should not throw an exception: " + e);
         }
 
         str = "ABC " + HebrewABC + " 123";
-        length = str.length();
         bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
+        try {
+            if (bidi.getRunLevel(-1) != 0 ||  // runCount - 4 (out of range)
+                bidi.getRunLevel(0) != 0 ||   // runCount - 3
+                bidi.getRunLevel(1) != 1 ||   // runCount - 2
+                bidi.getRunLevel(2) != 2 ||   // runCount - 1
+                bidi.getRunLevel(3) != 0 ||   // runCount     (out of range)
+                bidi.getRunLevel(4) != 0) {   // runCount + 1 (out of range)
+                errorHandling("Incorrect getRunLevel() value(s).");
+            }
+        }
+        catch (Exception e) {
+            errorHandling("getRunLevel() should not throw an exception: " + e);
+        }
 
+        str = "ABC";
+        bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
         try {
-            bidi.getRunLevel(-1);
-            errorHandling("getRunLevel() should throw an AIOoBE " +
-                "when run is -1(too small).");
+            if (bidi.getRunLevel(-1) != 0 ||  // runCount - 2 (out of range)
+                bidi.getRunLevel(0) != 0 ||   // runCount - 1
+                bidi.getRunLevel(1) != 0 ||   // runCount     (out of range)
+                bidi.getRunLevel(2) != 0) {   // runCount + 1 (out of range)
+                errorHandling("Incorrect getRunLevel() value(s).");
+            }
+        }
+        catch (Exception e) {
+            errorHandling("getRunLevel() should not throw an exception: " + e);
         }
-        catch (ArrayIndexOutOfBoundsException e) {
+
+        str = "ABC";
+        bidi = new Bidi(str, Bidi.DIRECTION_RIGHT_TO_LEFT);
+        try {
+            if (bidi.getRunLevel(-1) != 1 ||  // runCount - 2 (out of range)
+                bidi.getRunLevel(0) != 2 ||   // runCount - 1
+                bidi.getRunLevel(1) != 1 ||   // runCount     (out of range)
+                bidi.getRunLevel(2) != 1) {   // runCount + 1 (out of range)
+                errorHandling("Incorrect getRunLevel() value(s).");
+            }
+        }
+        catch (Exception e) {
+            errorHandling("getRunLevel() should not throw an exception: " + e);
         }
-        catch (IllegalArgumentException e) {
-            errorHandling("getRunLevel() should not throw an IAE " +
-                "but an AIOoBE when run is -1(too small).");
+
+        str = "ABC";
+        bidi = new Bidi(str, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+        try {
+            if (bidi.getRunLevel(-1) != 0 ||  // runCount - 2 (out of range)
+                bidi.getRunLevel(0) != 0 ||   // runCount - 1
+                bidi.getRunLevel(1) != 0 ||   // runCount     (out of range)
+                bidi.getRunLevel(2) != 0) {   // runCount + 1 (out of range)
+                errorHandling("Incorrect getRunLevel() value(s).");
+            }
+        }
+        catch (Exception e) {
+            errorHandling("getRunLevel() should not throw an exception: " + e);
         }
 
+        str = "ABC";
+        bidi = new Bidi(str, Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
         try {
-            bidi.getRunLevel(0);
-            bidi.getRunLevel(1);
-            bidi.getRunLevel(2);
+            if (bidi.getRunLevel(-1) != 0 ||  // runCount - 2 (out of range)
+                bidi.getRunLevel(0) != 0 ||   // runCount - 1
+                bidi.getRunLevel(1) != 0 ||   // runCount     (out of range)
+                bidi.getRunLevel(2) != 0) {   // runCount + 1 (out of range)
+                errorHandling("Incorrect getRunLevel() value(s).");
+            }
         }
         catch (Exception e) {
-            errorHandling("getRunLevel() should not throw an exception" +
-                " when run is from 0 to 2(runCount-1).");
+            errorHandling("getRunLevel() should not throw an exception: " + e);
+        }
+
+        str = HebrewABC;
+        bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
+        try {
+            if (bidi.getRunLevel(-1) != 0 ||  // runCount - 2 (out of range)
+                bidi.getRunLevel(0) != 1 ||   // runCount - 1
+                bidi.getRunLevel(1) != 0 ||   // runCount     (out of range)
+                bidi.getRunLevel(2) != 0) {   // runCount + 1 (out of range)
+                errorHandling("Incorrect getRunLevel() value(s).");
+            }
+        }
+        catch (Exception e) {
+            errorHandling("getRunLevel() should not throw an exception: " + e);
         }
 
+        str = HebrewABC;
+        bidi = new Bidi(str, Bidi.DIRECTION_RIGHT_TO_LEFT);
         try {
-            bidi.getRunLevel(3);
-            errorHandling("getRunLevel() should throw an AIOoBE" +
-                " when run is 3(same as runCount).");
+            if (bidi.getRunLevel(-1) != 1 ||  // runCount - 2 (out of range)
+                bidi.getRunLevel(0) != 1 ||   // runCount - 1
+                bidi.getRunLevel(1) != 1 ||   // runCount     (out of range)
+                bidi.getRunLevel(2) != 1) {   // runCount + 1 (out of range)
+                errorHandling("Incorrect getRunLevel() value(s).");
+            }
+        }
+        catch (Exception e) {
+            errorHandling("getRunLevel() should not throw an exception: " + e);
         }
-        catch (ArrayIndexOutOfBoundsException e) {
+
+        str = HebrewABC;
+        bidi = new Bidi(str, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+        try {
+            if (bidi.getRunLevel(-1) != 1 ||  // runCount - 2 (out of range)
+                bidi.getRunLevel(0) != 1 ||   // runCount - 1
+                bidi.getRunLevel(1) != 1 ||   // runCount     (out of range)
+                bidi.getRunLevel(2) != 1) {   // runCount + 1 (out of range)
+                errorHandling("Incorrect getRunLevel() value(s).");
+            }
+        }
+        catch (Exception e) {
+            errorHandling("getRunLevel() should not throw an exception: " + e);
         }
-        catch (IllegalArgumentException e) {
-            errorHandling("getRunLevel() should not throw an IAE " +
-                "but an AIOoBE when run is 3(same as runCount).");
+
+        str = HebrewABC;
+        bidi = new Bidi(str, Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
+        try {
+            if (bidi.getRunLevel(-1) != 1 ||  // runCount - 2 (out of range)
+                bidi.getRunLevel(0) != 1 ||   // runCount - 1
+                bidi.getRunLevel(1) != 1 ||   // runCount     (out of range)
+                bidi.getRunLevel(2) != 1) {   // runCount + 1 (out of range)
+                errorHandling("Incorrect getRunLevel() value(s).");
+            }
+        }
+        catch (Exception e) {
+            errorHandling("getRunLevel() should not throw an exception: " + e);
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/text/Bidi/Bug8005277.java	Fri Dec 28 15:07:08 2012 +0900
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005277
+ * @summary verify that Bidi.getRunLevel() returns a corect level.
+ */
+import java.text.Bidi;
+
+public class Bug8005277 {
+
+    public static void main(String[] args) {
+        boolean err = false;
+        String string = "\u05D0\u05D1\u05D2";
+        Bidi bidi = new Bidi(string, Bidi.DIRECTION_LEFT_TO_RIGHT);
+
+        int result = bidi.getRunCount();
+        if (result != 1) {
+            System.err.println("Incorrect run count: " + result);
+            err = true;
+        }
+
+        result = bidi.getRunStart(0);
+        if (result != 0) {
+            System.err.println("Incorrect run start: " + result);
+            err = true;
+        }
+
+        result = bidi.getRunLimit(0);
+        if (result != 3) {
+            System.err.println("Incorrect run limit: " + result);
+            err = true;
+        }
+
+        result = bidi.getRunLevel(0);
+        if (result != 1) {
+            System.err.println("Incorrect run level: " + result);
+            err = true;
+        }
+
+        if (err) {
+            throw new RuntimeException("Failed.");
+        }
+    }
+
+}