]> granicus.if.org Git - icu/commitdiff
ICU-13512 Fix problem with break iterator cloning.
authorAndy Heninger <andy.heninger@gmail.com>
Mon, 18 Dec 2017 01:32:19 +0000 (01:32 +0000)
committerAndy Heninger <andy.heninger@gmail.com>
Mon, 18 Dec 2017 01:32:19 +0000 (01:32 +0000)
X-SVN-Rev: 40743

icu4j/main/classes/core/src/com/ibm/icu/text/DictionaryBreakEngine.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/rbbi/RBBITest.java

index ddd4a56fc5322cd500f3571b0ec7c4fed42847e0..3ed879196d4798b895dd2d1374d91ebc68254df2 100644 (file)
@@ -97,7 +97,7 @@ abstract class DictionaryBreakEngine implements LanguageBreakEngine {
         @Override
         public Object clone() throws CloneNotSupportedException {
             DequeI result = (DequeI)super.clone();
-            data = data.clone();
+            result.data = data.clone();
             return result;
         }
 
index 9d025e7c8de321213531d242ca7946ea1317c6f7..1696e34bfff07abb372ff20fe2fbb5337ed7ef86 100644 (file)
@@ -488,4 +488,64 @@ public class RBBITest extends TestFmwk {
         assertEquals("", biFr, cloneFr);
         assertEquals("", ULocale.FRENCH, cloneFr.getLocale(ULocale.VALID_LOCALE));
     }
+
+    static class T13512Thread extends Thread {
+        private String fText;
+        public List fBoundaries;
+        public List fExpectedBoundaries;
+
+        T13512Thread(String text) {
+            fText = text;
+            fExpectedBoundaries = getBoundary(fText);
+        }
+        @Override
+        public void run() {
+            for (int i= 0; i<10000; ++i) {
+                fBoundaries = getBoundary(fText);
+                if (!fBoundaries.equals(fExpectedBoundaries)) {
+                    break;
+                }
+            }
+        }
+        private static final BreakIterator BREAK_ITERATOR_CACHE = BreakIterator.getWordInstance(ULocale.ROOT);
+        public static List<Integer> getBoundary(String toParse) {
+            List<Integer> retVal = new ArrayList<Integer>();
+            BreakIterator bi = (BreakIterator) BREAK_ITERATOR_CACHE.clone();
+            bi.setText(toParse);
+            for (int boundary=bi.first(); boundary != BreakIterator.DONE; boundary = bi.next()) {
+                retVal.add(boundary);
+            }
+            return retVal;
+        }
+    }
+
+    @Test
+    public void TestBug13512() {
+        String japanese = "コンピューターは、本質的には数字しか扱うことができません。コンピューターは、文字や記号などのそれぞれに番号を割り振る"
+                + "ことによって扱えるようにします。ユニコードが出来るまでは、これらの番号を割り振る仕組みが何百種類も存在しました。どの一つをとっても、十分な"
+                + "文字を含んではいませんでした。例えば、欧州連合一つを見ても、そのすべての言語をカバーするためには、いくつかの異なる符号化の仕"
+                + "組みが必要でした。英語のような一つの言語に限っても、一つだけの符号化の仕組みでは、一般的に使われるすべての文字、句読点、技術"
+                + "的な記号などを扱うには不十分でした。";
+
+        String thai = "โดยพื้นฐานแล้ว, คอมพิวเตอร์จะเกี่ยวข้องกับเรื่องของตัวเลข. คอมพิวเตอร์จัดเก็บตัวอักษรและอักขระอื่นๆ"
+                + " โดยการกำหนดหมายเลขให้สำหรับแต่ละตัว. ก่อนหน้าที่๊ Unicode จะถูกสร้างขึ้น, ได้มีระบบ encoding "
+                + "อยู่หลายร้อยระบบสำหรับการกำหนดหมายเลขเหล่านี้. ไม่มี encoding ใดที่มีจำนวนตัวอักขระมากเพียงพอ: ยกตัวอย่างเช่น, "
+                + "เฉพาะในกลุ่มสหภาพยุโรปเพียงแห่งเดียว ก็ต้องการหลาย encoding ในการครอบคลุมทุกภาษาในกลุ่ม. "
+                + "หรือแม้แต่ในภาษาเดี่ยว เช่น ภาษาอังกฤษ ก็ไม่มี encoding ใดที่เพียงพอสำหรับทุกตัวอักษร, "
+                + "เครื่องหมายวรรคตอน และสัญลักษณ์ทางเทคนิคที่ใช้กันอยู่ทั่วไป.\n" +
+                "ระบบ encoding เหล่านี้ยังขัดแย้งซึ่งกันและกัน. นั่นก็คือ, ในสอง encoding สามารถใช้หมายเลขเดียวกันสำหรับตัวอักขระสองตัวที่แตกต่างกัน,"
+                + "หรือใช้หมายเลขต่างกันสำหรับอักขระตัวเดียวกัน. ในระบบคอมพิวเตอร์ (โดยเฉพาะเซิร์ฟเวอร์) ต้องมีการสนับสนุนหลาย"
+                + " encoding; และเมื่อข้อมูลที่ผ่านไปมาระหว่างการเข้ารหัสหรือแพล็ตฟอร์มที่ต่างกัน, ข้อมูลนั้นจะเสี่ยงต่อการผิดพลาดเสียหาย.";
+
+        T13512Thread t1 = new T13512Thread(thai);
+        T13512Thread t2 = new T13512Thread(japanese);
+        try {
+            t1.start(); t2.start();
+            t1.join(); t2.join();
+        } catch (Exception e) {
+            fail(e.toString());
+        }
+        assertEquals("", t1.fExpectedBoundaries, t1.fBoundaries);
+        assertEquals("", t2.fExpectedBoundaries, t2.fBoundaries);
+    }
 }