8042589: String.toLowerCase do not work for some concatenated strings
authorsherman
Thu, 17 Jul 2014 11:08:50 -0700
changeset 25652 3fa5768212c4
parent 25579 630405354c00
child 25653 41e5fa7ce490
8042589: String.toLowerCase do not work for some concatenated strings Summary: to include surrogate check in loop Reviewed-by: mchung
jdk/src/share/classes/java/lang/String.java
jdk/test/java/lang/String/ToLowerCase.java
jdk/test/java/lang/String/ToUpperCase.java
--- a/jdk/src/share/classes/java/lang/String.java	Wed Jul 16 18:22:09 2014 -0700
+++ b/jdk/src/share/classes/java/lang/String.java	Thu Jul 17 11:08:50 2014 -0700
@@ -2580,7 +2580,8 @@
         }
         for (int i = first; i < len; i++) {
             int cp = (int)value[i];
-            if (cp == '\u03A3') {                       // GREEK CAPITAL LETTER SIGMA
+            if (cp == '\u03A3' ||                       // GREEK CAPITAL LETTER SIGMA
+                Character.isSurrogate((char)cp)) {
                 return toLowerCaseEx(result, i, locale, false);
             }
             if (cp == '\u0130') {                       // LATIN CAPITAL LETTER I WITH DOT ABOVE
@@ -2742,7 +2743,11 @@
             return toUpperCaseEx(result, first, locale, false);
         }
         for (int i = first; i < len; i++) {
-            int cp = Character.toUpperCaseEx((int)value[i]);
+            int cp = (int)value[i];
+            if (Character.isSurrogate((char)cp)) {
+                return toUpperCaseEx(result, i, locale, false);
+            }
+            cp = Character.toUpperCaseEx(cp);
             if (!Character.isBmpCodePoint(cp)) {    // Character.ERROR is not bmp
                 return toUpperCaseEx(result, i, locale, false);
             }
--- a/jdk/test/java/lang/String/ToLowerCase.java	Wed Jul 16 18:22:09 2014 -0700
+++ b/jdk/test/java/lang/String/ToLowerCase.java	Thu Jul 17 11:08:50 2014 -0700
@@ -23,7 +23,7 @@
 
 /*
     @test
-    @bug 4217441 4533872 4900935 8020037 8032012 8041791
+    @bug 4217441 4533872 4900935 8020037 8032012 8041791 8042589
     @summary toLowerCase should lower-case Greek Sigma correctly depending
              on the context (final/non-final).  Also it should handle
              Locale specific (lt, tr, and az) lowercasings and supplementary
@@ -106,6 +106,12 @@
         // invalid code point tests:
         test("\uD800\uD800\uD801A\uDC00\uDC00\uDC00B", Locale.US, "\uD800\uD800\uD801a\uDC00\uDC00\uDC00b");
 
+        // lower/uppercase + surrogates
+        test("a\uD801\uDC1c", Locale.ROOT, "a\uD801\uDC44");
+        test("A\uD801\uDC1c", Locale.ROOT, "a\uD801\uDC44");
+        test("a\uD801\uDC00\uD801\uDC01\uD801\uDC02", Locale.US, "a\uD801\uDC28\uD801\uDC29\uD801\uDC2A");
+        test("A\uD801\uDC00\uD801\uDC01\uD801\uDC02", Locale.US, "a\uD801\uDC28\uD801\uDC29\uD801\uDC2A");
+
         // test bmp + supp1
         StringBuilder src = new StringBuilder(0x20000);
         StringBuilder exp = new StringBuilder(0x20000);
--- a/jdk/test/java/lang/String/ToUpperCase.java	Wed Jul 16 18:22:09 2014 -0700
+++ b/jdk/test/java/lang/String/ToUpperCase.java	Thu Jul 17 11:08:50 2014 -0700
@@ -23,7 +23,7 @@
 
 /*
     @test
-    @bug 4219630 4304573 4533872 4900935
+    @bug 4219630 4304573 4533872 4900935 8042589
     @summary toUpperCase should upper-case German sharp s correctly even if
              it's the only character in the string. should also uppercase
              all of the 1:M char mappings correctly.  Also it should handle
@@ -91,6 +91,12 @@
         test("\uD801\uDC28a\uD801\uDC29b\uD801\uDC2Ac", Locale.US, "\uD801\uDC00A\uD801\uDC01B\uD801\uDC02C");
         // invalid code point tests:
         test("\uD800\uD800\uD801a\uDC00\uDC00\uDC00b", Locale.US, "\uD800\uD800\uD801A\uDC00\uDC00\uDC00B");
+
+        // lower/uppercase + surrogates
+        test("a\uD801\uDC44", Locale.ROOT, "A\uD801\uDC1c");
+        test("A\uD801\uDC44", Locale.ROOT, "A\uD801\uDC1c");
+        test("a\uD801\uDC28\uD801\uDC29\uD801\uDC2A", Locale.US, "A\uD801\uDC00\uD801\uDC01\uD801\uDC02");
+        test("A\uD801\uDC28a\uD801\uDC29b\uD801\uDC2Ac", Locale.US, "A\uD801\uDC00A\uD801\uDC01B\uD801\uDC02C");
     }
 
     static void test(String in, Locale locale, String expected) {