1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 import junit.framework.Assert;
18 import java.lang.reflect.Method;
19 import java.util.Locale;
20 
21 /**
22  * more string tests
23  */
24 public class Main {
main(String args[])25     public static void main(String args[]) throws Exception {
26         String test = "0123456789";
27         String test1 = new String("0123456789");    // different object
28         String test2 = new String("0123456780");    // different value
29         String offset = new String("xxx0123456789yyy");
30         String sub = offset.substring(3, 13);
31         Object blah = new Object();
32 
33         Assert.assertTrue(test.equals(test));
34         Assert.assertTrue(test.equals(test1));
35         Assert.assertFalse(test.equals(test2));
36 
37         Assert.assertEquals(test.compareTo(test1), 0);
38         Assert.assertTrue(test1.compareTo(test2) > 0);
39         Assert.assertTrue(test2.compareTo(test1) < 0);
40 
41         Assert.assertEquals("".compareTo(""), 0);
42         Assert.assertTrue(test.compareTo("") > 0);
43         Assert.assertTrue("".compareTo(test) < 0);
44 
45         /* compare string with a nonzero offset, in left/right side */
46         Assert.assertEquals(test.compareTo(sub), 0);
47         Assert.assertEquals(sub.compareTo(test), 0);
48         Assert.assertTrue(test.equals(sub));
49         Assert.assertTrue(sub.equals(test));
50         /* same base, one is a substring */
51         Assert.assertFalse(offset.equals(sub));
52         Assert.assertFalse(sub.equals(offset));
53         /* wrong class */
54         Assert.assertFalse(test.equals(blah));
55 
56         /* null ptr - throw */
57         try {
58             test.compareTo(null);
59             Assert.fail("didn't get expected npe");
60         } catch (NullPointerException npe) {
61             System.out.println("Got expected npe");
62         }
63         /* null ptr - ok */
64         Assert.assertFalse(test.equals(null));
65 
66         test = test.substring(1);
67         Assert.assertTrue(test.equals("123456789"));
68         Assert.assertFalse(test.equals(test1));
69 
70         test = test.substring(1);
71         Assert.assertTrue(test.equals("23456789"));
72 
73         test = test.substring(1);
74         Assert.assertTrue(test.equals("3456789"));
75 
76         test = test.substring(1);
77         Assert.assertTrue(test.equals("456789"));
78 
79         test = test.substring(3,5);
80         Assert.assertTrue(test.equals("78"));
81 
82         test = "this/is/a/path";
83         String[] strings = test.split("/");
84         Assert.assertEquals(4, strings.length);
85 
86         Assert.assertEquals("this is a path", test.replaceAll("/", " "));
87         Assert.assertEquals("this is a path", test.replace("/", " "));
88 
89         Class<?> Strings = Class.forName("com.android.org.bouncycastle.util.Strings");
90         Method fromUTF8ByteArray = Strings.getDeclaredMethod("fromUTF8ByteArray", byte[].class);
91         String result = (String) fromUTF8ByteArray.invoke(null, new byte[] {'O', 'K'});
92         System.out.println(result);
93 
94         testCompareToAndEquals();
95         testIndexOf();
96 
97         String s0_0 = "\u0000";
98         String s0_1 = new String(s0_0);
99         String s0_2 = new String(new char[] { '\u0000' });
100         String s0_3 = s0_0 + "";
101         System.out.println(
102             " " + $noinline$equals(s0_0, s0_0) +
103             " " + $noinline$equals(s0_0, s0_1) +
104             " " + $noinline$equals(s0_0, s0_2) +
105             " " + $noinline$equals(s0_0, s0_3));
106         System.out.println(
107             " " + $noinline$equals(s0_1, s0_0) +
108             " " + $noinline$equals(s0_1, s0_1) +
109             " " + $noinline$equals(s0_1, s0_2) +
110             " " + $noinline$equals(s0_1, s0_3));
111         System.out.println(
112             " " + $noinline$equals(s0_2, s0_0) +
113             " " + $noinline$equals(s0_2, s0_1) +
114             " " + $noinline$equals(s0_2, s0_2) +
115             " " + $noinline$equals(s0_2, s0_3));
116         System.out.println(
117             " " + $noinline$equals(s0_3, s0_0) +
118             " " + $noinline$equals(s0_3, s0_1) +
119             " " + $noinline$equals(s0_3, s0_2) +
120             " " + $noinline$equals(s0_3, s0_3));
121 
122         testEqualsConstString();
123         testConstStringEquals();
124 
125         // Regression tests for String.setCharAt() breaking string compression invariants.
126         Locale en_US = new Locale("en", "US");
127         Assert.assertEquals("I", /* Small latin dotless i */ "\u0131".toUpperCase());
128         Assert.assertEquals("abc", "a\u0131c".replace('\u0131', 'b'));
129         Assert.assertEquals("a\u0131c", "abc".replace('b', '\u0131'));
130 
131         // Regression test for scratch register exhaustion in String.equals() intrinsic on arm64.
132         Assert.assertFalse(result.equals("Very long constant string, so that the known constant count field cannot be embedded in a CMP immediate instruction on arm64. Since it can hold 12-bit values, optionally shifted left by 12, let's go somewhere over 2^12, i.e. 4096. That should trigger the bug with or without string compression. 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/"));
133     }
134 
testCompareToAndEquals()135     public static void testCompareToAndEquals() {
136         String[] strings = {
137                 // Special: empty string.
138                 "",
139                 // Category 0, ASCII strings:
140                 //     "0123456789abcdef".substring(0, index + 1)
141                 "0",
142                 "01",
143                 "012",
144                 "0123",
145                 "01234",
146                 "012345",
147                 "0123456",
148                 "01234567",
149                 "012345678",
150                 "0123456789",
151                 "0123456789a",
152                 "0123456789ab",
153                 "0123456789abc",
154                 "0123456789abcd",
155                 "0123456789abcde",
156                 "0123456789abcdef",
157                 // Category 1, ASCII strings:
158                 //     "0123456789abcdef".substring(0, index) + "x"
159                 "x",
160                 "0x",
161                 "01x",
162                 "012x",
163                 "0123x",
164                 "01234x",
165                 "012345x",
166                 "0123456x",
167                 "01234567x",
168                 "012345678x",
169                 "0123456789x",
170                 "0123456789ax",
171                 "0123456789abx",
172                 "0123456789abcx",
173                 "0123456789abcdx",
174                 "0123456789abcdex",
175                 // Category 2, ASCII strings,
176                 //     "0123456789abcdef".substring(0, index) + "x" +
177                 //     "0123456789abcdef".substring(index + 1)
178                 "x123456789abcdef",
179                 "0x23456789abcdef",
180                 "01x3456789abcdef",
181                 "012x456789abcdef",
182                 "0123x56789abcdef",
183                 "01234x6789abcdef",
184                 "012345x789abcdef",
185                 "0123456x89abcdef",
186                 "01234567x9abcdef",
187                 "012345678xabcdef",
188                 "0123456789xbcdef",
189                 "0123456789axcdef",
190                 "0123456789abxdef",
191                 "0123456789abcxef",
192                 "0123456789abcdxf",
193                 "0123456789abcdex",
194                 // Category 3, ASCII strings:
195                 //     "z" + "0123456789abcdef".substring(1, index + 1)
196                 "z",
197                 "z1",
198                 "z12",
199                 "z123",
200                 "z1234",
201                 "z12345",
202                 "z123456",
203                 "z1234567",
204                 "z12345678",
205                 "z123456789",
206                 "z123456789a",
207                 "z123456789ab",
208                 "z123456789abc",
209                 "z123456789abcd",
210                 "z123456789abcde",
211                 "z123456789abcdef",
212                 // Category 4, non-ASCII strings:
213                 //     "0123456789abcdef".substring(0, index) + "\u0440"
214                 "\u0440",
215                 "0\u0440",
216                 "01\u0440",
217                 "012\u0440",
218                 "0123\u0440",
219                 "01234\u0440",
220                 "012345\u0440",
221                 "0123456\u0440",
222                 "01234567\u0440",
223                 "012345678\u0440",
224                 "0123456789\u0440",
225                 "0123456789a\u0440",
226                 "0123456789ab\u0440",
227                 "0123456789abc\u0440",
228                 "0123456789abcd\u0440",
229                 "0123456789abcde\u0440",
230                 // Category 5, non-ASCII strings:
231                 //     "0123456789abcdef".substring(0, index) + "\u0440" +
232                 //     "0123456789abcdef".substring(index + 1)
233                 "\u0440123456789abcdef",
234                 "0\u044023456789abcdef",
235                 "01\u04403456789abcdef",
236                 "012\u0440456789abcdef",
237                 "0123\u044056789abcdef",
238                 "01234\u04406789abcdef",
239                 "012345\u0440789abcdef",
240                 "0123456\u044089abcdef",
241                 "01234567\u04409abcdef",
242                 "012345678\u0440abcdef",
243                 "0123456789\u0440bcdef",
244                 "0123456789a\u0440cdef",
245                 "0123456789ab\u0440def",
246                 "0123456789abc\u0440ef",
247                 "0123456789abcd\u0440f",
248                 "0123456789abcde\u0440",
249                 // Category 6, ASCII strings:
250                 //     "\u0443" + "0123456789abcdef".substring(1, index + 1)
251                 "\u0443",
252                 "\u04431",
253                 "\u044312",
254                 "\u0443123",
255                 "\u04431234",
256                 "\u044312345",
257                 "\u0443123456",
258                 "\u04431234567",
259                 "\u044312345678",
260                 "\u0443123456789",
261                 "\u0443123456789a",
262                 "\u0443123456789ab",
263                 "\u0443123456789abc",
264                 "\u0443123456789abcd",
265                 "\u0443123456789abcde",
266                 "\u0443123456789abcdef",
267                 // Category 7, non-ASCII strings:
268                 //     "0123456789abcdef".substring(0, index) + "\u0482"
269                 "\u0482",
270                 "0\u0482",
271                 "01\u0482",
272                 "012\u0482",
273                 "0123\u0482",
274                 "01234\u0482",
275                 "012345\u0482",
276                 "0123456\u0482",
277                 "01234567\u0482",
278                 "012345678\u0482",
279                 "0123456789\u0482",
280                 "0123456789a\u0482",
281                 "0123456789ab\u0482",
282                 "0123456789abc\u0482",
283                 "0123456789abcd\u0482",
284                 "0123456789abcde\u0482",
285                 // Category 8, non-ASCII strings:
286                 //     "0123456789abcdef".substring(0, index) + "\u0482" +
287                 //     "0123456789abcdef".substring(index + 1)
288                 "\u0482123456789abcdef",
289                 "0\u048223456789abcdef",
290                 "01\u04823456789abcdef",
291                 "012\u0482456789abcdef",
292                 "0123\u048256789abcdef",
293                 "01234\u04826789abcdef",
294                 "012345\u0482789abcdef",
295                 "0123456\u048289abcdef",
296                 "01234567\u04829abcdef",
297                 "012345678\u0482abcdef",
298                 "0123456789\u0482bcdef",
299                 "0123456789a\u0482cdef",
300                 "0123456789ab\u0482def",
301                 "0123456789abc\u0482ef",
302                 "0123456789abcd\u0482f",
303                 "0123456789abcde\u0482",
304                 // Category 9, ASCII strings:
305                 //     "\u0489" + "0123456789abcdef".substring(1, index + 1)
306                 "\u0489",
307                 "\u04891",
308                 "\u048912",
309                 "\u0489123",
310                 "\u04891234",
311                 "\u048912345",
312                 "\u0489123456",
313                 "\u04891234567",
314                 "\u048912345678",
315                 "\u0489123456789",
316                 "\u0489123456789a",
317                 "\u0489123456789ab",
318                 "\u0489123456789abc",
319                 "\u0489123456789abcd",
320                 "\u0489123456789abcde",
321                 "\u0489123456789abcdef",
322         };
323         int length = strings.length;
324         Assert.assertEquals(1 + 16 * 10, length);
325         for (int i = 0; i != length; ++i) {
326             String lhs = strings[i];
327             for (int j = 0; j != length; ++j) {
328                 String rhs = strings[j];
329                 int result = $noinline$compareTo(lhs, rhs);
330                 final int expected;
331                 if (i == 0 || j == 0 || i == j) {
332                     // One of the strings is empty or the strings are the same.
333                     expected = lhs.length() - rhs.length();
334                 } else {
335                     int i_category = (i - 1) / 16;
336                     int i_index = (i - 1) % 16;
337                     int j_category = (j - 1) / 16;
338                     int j_index = (j - 1) % 16;
339                     int min_ij_index = (i_index < j_index) ? i_index : j_index;
340                     if (i_category == j_category) {
341                         switch (i_category) {
342                             case 0: case 3: case 6: case 9:
343                                 // Differs in length.
344                                 expected = lhs.length() - rhs.length();
345                                 break;
346                             case 1: case 2: case 4: case 5: case 7: case 8:
347                                 // Differs in charAt(min_ij_index).
348                                 expected = lhs.charAt(min_ij_index) - rhs.charAt(min_ij_index);
349                                 break;
350                             default: throw new Error("Unexpected category.");
351                       }
352                     } else if (i_category == 3 || i_category == 6 || i_category == 9 ||
353                                j_category == 3 || j_category == 6 || j_category == 9) {
354                         // In these categories, charAt(0) differs from other categories' strings.
355                         expected = lhs.charAt(0) - rhs.charAt(0);
356                     } else if (// Category 0 string is a prefix to any longer string in
357                                // remaining categories.
358                                (i_category == 0 && i_index < j_index) ||
359                                (j_category == 0 && j_index < i_index) ||
360                                // Category 2 string is a prefix to category 3 string at the same
361                                // index. Similar for categories 4 and 5 and also 7 and 8.
362                                // This includes matching last strings of these pairs of categories.
363                                (i_index == j_index &&
364                                    ((i_category == 1 && j_category == 2) ||
365                                     (i_category == 2 && j_category == 1) ||
366                                     (i_category == 4 && j_category == 5) ||
367                                     (i_category == 5 && j_category == 4) ||
368                                     (i_category == 7 && j_category == 8) ||
369                                     (i_category == 8 && j_category == 7)))) {
370                         // Differs in length.
371                         expected = lhs.length() - rhs.length();
372                     } else {
373                         // The remaining cases differ in charAt(min_ij_index), the characters
374                         // before that are "0123456789abcdef".substring(0, min_ij_index).
375                         for (int k = 0; k < min_ij_index; ++k) {
376                           Assert.assertEquals("0123456789abcdef".charAt(k), lhs.charAt(k));
377                           Assert.assertEquals("0123456789abcdef".charAt(k), rhs.charAt(k));
378                         }
379                         expected = lhs.charAt(min_ij_index) - rhs.charAt(min_ij_index);
380                         Assert.assertFalse(expected == 0);
381                     }
382                 }
383                 if (expected != result) {
384                   throw new Error(
385                       "Mismatch at i=" + i + ", j=" + j + ", expected=" + expected +
386                       ", result=" + result);
387                 }
388                 boolean equalsExpected =
389                     (i == j) ||
390                     // Last string in categories 1 and 2.
391                     (i == 32 && j == 48) || (i == 48 && j == 32) ||
392                     // Last string in categories 4 and 5.
393                     (i == 80 && j == 96) || (i == 96 && j == 80) ||
394                     // Last string in categories 7 and 8.
395                     (i == 128 && j == 144) || (i == 144 && j == 128);
396                 Assert.assertEquals(equalsExpected, $noinline$equals(lhs, rhs));
397             }
398         }
399 
400         try {
401             $noinline$compareTo("", null);
402             Assert.fail();
403         } catch (NullPointerException expected) {
404         }
405         try {
406             $noinline$compareTo(null, "");
407             Assert.fail();
408         } catch (NullPointerException expected) {
409         }
410 
411         Assert.assertFalse($noinline$equals("", null));
412         try {
413             $noinline$equals(null, "");
414             Assert.fail();
415         } catch (NullPointerException expected) {
416         }
417     }
418 
testIndexOf()419     public static void testIndexOf() {
420         String[] prefixes = {
421                 "",
422                 "0",
423                 "01",
424                 "012",
425                 "0123",
426                 "01234",
427                 "012345",
428                 "0123456",
429                 "01234567",
430                 "012345678",
431                 "0123456789",
432                 "0123456789a",
433                 "0123456789ab",
434                 "0123456789abc",
435                 "0123456789abcd",
436                 "0123456789abcdef",
437         };
438         String[] cores = {
439                 "",
440                 "x",
441                 "xx",
442                 "xxx",
443                 "xxxx",
444                 "xxxxx",
445                 "xxxxxx",
446                 "xxxxxxx",
447                 "xxxxxxxx",
448                 "xzx",
449                 "xxzx",
450                 "xxxzx",
451                 "xxxxzx",
452                 "xxxxxzx",
453                 "xxxxxxzx",
454                 "xxxxxxxzx",
455                 "xxxxxxxxzx",
456                 "\u0440",
457                 "\u0440\u0440",
458                 "\u0440\u0440\u0440",
459                 "\u0440\u0440\u0440\u0440",
460                 "\u0440\u0440\u0440\u0440\u0440",
461                 "\u0440\u0440\u0440\u0440\u0440\u0440",
462                 "\u0440\u0440\u0440\u0440\u0440\u0440\u0440",
463                 "\u0440\u0440\u0440\u0440\u0440\u0440\u0440\u0440",
464                 "\u0440z\u0440",
465                 "\u0440\u0440z\u0440",
466                 "\u0440\u0440\u0440z\u0440",
467                 "\u0440\u0440\u0440\u0440z\u0440",
468                 "\u0440\u0440\u0440\u0440\u0440z\u0440",
469                 "\u0440\u0440\u0440\u0440\u0440\u0440z\u0440",
470                 "\u0440\u0440\u0440\u0440\u0440\u0440\u0440z\u0440",
471                 "\u0440\u0440\u0440\u0440\u0440\u0440\u0440\u0440z\u0440",
472                 "\u0000",
473                 "\u0000\u0000",
474                 "\u0000\u0000\u0000",
475                 "\u0000\u0000\u0000\u0000",
476                 "\u0000\u0000\u0000\u0000\u0000",
477                 "\u0000\u0000\u0000\u0000\u0000\u0000",
478                 "\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
479                 "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
480                 "\u0000z\u0000",
481                 "\u0000\u0000z\u0000",
482                 "\u0000\u0000\u0000z\u0000",
483                 "\u0000\u0000\u0000\u0000z\u0000",
484                 "\u0000\u0000\u0000\u0000\u0000z\u0000",
485                 "\u0000\u0000\u0000\u0000\u0000\u0000z\u0000",
486                 "\u0000\u0000\u0000\u0000\u0000\u0000\u0000z\u0000",
487                 "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000z\u0000",
488         };
489         String[] suffixes = {
490                 "",
491                 "y",
492                 "yy",
493                 "yyy",
494                 "yyyy",
495                 "yyyyy",
496                 "yyyyyy",
497                 "yyyyyyy",
498                 "yyyyyyyy",
499                 "\u0441",
500                 "y\u0441",
501                 "yy\u0441",
502                 "yyy\u0441",
503                 "yyyy\u0441",
504                 "yyyyy\u0441",
505                 "yyyyyy\u0441",
506                 "yyyyyyy\u0441",
507                 "yyyyyyyy\u0441",
508         };
509         for (String p : prefixes) {
510             for (String c : cores) {
511                 for (String s : suffixes) {
512                     String full = p + c + s;
513                     int expX = (c.isEmpty() || c.charAt(0) != 'x') ? -1 : p.length();
514                     int exp0440 = (c.isEmpty() || c.charAt(0) != '\u0440') ? -1 : p.length();
515                     int exp0000 = (c.isEmpty() || c.charAt(0) != '\u0000') ? -1 : p.length();
516                     Assert.assertEquals(expX, $noinline$indexOf(full, 'x'));
517                     Assert.assertEquals(exp0440, $noinline$indexOf(full, '\u0440'));
518                     Assert.assertEquals(exp0000, $noinline$indexOf(full, '\u0000'));
519                     Assert.assertEquals(expX, $noinline$indexOf(full, 'x', -1));
520                     Assert.assertEquals(exp0440, $noinline$indexOf(full, '\u0440', -1));
521                     Assert.assertEquals(exp0000, $noinline$indexOf(full, '\u0000', -1));
522                     Assert.assertEquals(-1, $noinline$indexOf(full, 'x', full.length() + 1));
523                     Assert.assertEquals(-1, $noinline$indexOf(full, '\u0440', full.length() + 1));
524                     Assert.assertEquals(-1, $noinline$indexOf(full, '\u0000', full.length() + 1));
525                     for (int from = 0; from != full.length(); ++from) {
526                         final int eX;
527                         final int e0440;
528                         final int e0000;
529                         if (from <= p.length()) {
530                             eX = expX;
531                             e0440 = exp0440;
532                             e0000 = exp0000;
533                         } else if (from >= p.length() + c.length()) {
534                             eX = -1;
535                             e0440 = -1;
536                             e0000 = -1;
537                         } else if (full.charAt(from) == 'z') {
538                             eX = (full.charAt(from + 1) != 'x') ? -1 : from + 1;
539                             e0440 = (full.charAt(from + 1) != '\u0440') ? -1 : from + 1;
540                             e0000 = (full.charAt(from + 1) != '\u0000') ? -1 : from + 1;
541                         } else {
542                             eX = (full.charAt(from) != 'x') ? -1 : from;
543                             e0440 = (full.charAt(from) != '\u0440') ? -1 : from;
544                             e0000 = (full.charAt(from) != '\u0000') ? -1 : from;
545                         }
546                         Assert.assertEquals(eX, $noinline$indexOf(full, 'x', from));
547                         Assert.assertEquals(e0440, $noinline$indexOf(full, '\u0440', from));
548                         Assert.assertEquals(e0000, $noinline$indexOf(full, '\u0000', from));
549                     }
550                 }
551             }
552         }
553     }
554 
testEqualsConstString()555     public static void testEqualsConstString() {
556         Assert.assertTrue($noinline$equalsConstString0(""));
557         Assert.assertFalse($noinline$equalsConstString0("1"));
558 
559         Assert.assertTrue($noinline$equalsConstString7("0123456"));
560         Assert.assertFalse($noinline$equalsConstString7("012345"));
561         Assert.assertFalse($noinline$equalsConstString7("01234567"));
562         Assert.assertFalse($noinline$equalsConstString7("012345x"));
563         Assert.assertFalse($noinline$equalsConstString7("012345\u0440"));
564 
565         Assert.assertTrue($noinline$equalsConstString14("01234567890123"));
566         Assert.assertFalse($noinline$equalsConstString14("0123456789012"));
567         Assert.assertFalse($noinline$equalsConstString14("012345678901234"));
568         Assert.assertFalse($noinline$equalsConstString14("0123456789012x"));
569         Assert.assertFalse($noinline$equalsConstString14("0123456789012\u0440"));
570 
571         Assert.assertTrue($noinline$equalsConstString24("012345678901234567890123"));
572         Assert.assertFalse($noinline$equalsConstString24("01234567890123456789012"));
573         Assert.assertFalse($noinline$equalsConstString24("0123456789012345678901234"));
574         Assert.assertFalse($noinline$equalsConstString24("01234567890123456789012x"));
575         Assert.assertFalse($noinline$equalsConstString24("01234567890123456789012\u0440"));
576 
577         Assert.assertTrue($noinline$equalsConstString29("01234567890123456789012345678"));
578         Assert.assertFalse($noinline$equalsConstString29("0123456789012345678901234567"));
579         Assert.assertFalse($noinline$equalsConstString29("012345678901234567890123456789"));
580         Assert.assertFalse($noinline$equalsConstString29("0123456789012345678901234567x"));
581         Assert.assertFalse($noinline$equalsConstString29("0123456789012345678901234567\u0440"));
582 
583         Assert.assertTrue($noinline$equalsConstString35("01234567890123456789012345678901234"));
584         Assert.assertFalse($noinline$equalsConstString35("0123456789012345678901234567890123"));
585         Assert.assertFalse($noinline$equalsConstString35("012345678901234567890123456789012345"));
586         Assert.assertFalse($noinline$equalsConstString35("0123456789012345678901234567890123x"));
587         Assert.assertFalse(
588             $noinline$equalsConstString35("0123456789012345678901234567890123\u0440"));
589 
590         Assert.assertTrue($noinline$equalsConstNonAsciiString7("\u0440123456"));
591         Assert.assertFalse($noinline$equalsConstNonAsciiString7("\u044012345"));
592         Assert.assertFalse($noinline$equalsConstNonAsciiString7("\u04401234567"));
593         Assert.assertFalse($noinline$equalsConstNonAsciiString7("\u044012345x"));
594         Assert.assertFalse($noinline$equalsConstNonAsciiString7("0123456"));
595 
596         Assert.assertTrue($noinline$equalsConstNonAsciiString14("\u04401234567890123"));
597         Assert.assertFalse($noinline$equalsConstNonAsciiString14("\u0440123456789012"));
598         Assert.assertFalse($noinline$equalsConstNonAsciiString14("\u044012345678901234"));
599         Assert.assertFalse($noinline$equalsConstNonAsciiString14("\u0440123456789012x"));
600         Assert.assertFalse($noinline$equalsConstNonAsciiString14("01234567890123"));
601 
602         Assert.assertTrue($noinline$equalsConstNonAsciiString24("\u044012345678901234567890123"));
603         Assert.assertFalse($noinline$equalsConstNonAsciiString24("\u04401234567890123456789012"));
604         Assert.assertFalse($noinline$equalsConstNonAsciiString24("\u0440123456789012345678901234"));
605         Assert.assertFalse($noinline$equalsConstNonAsciiString24("\u04401234567890123456789012x"));
606         Assert.assertFalse($noinline$equalsConstNonAsciiString24("\012345678901234567890123"));
607 
608         Assert.assertTrue(
609             $noinline$equalsConstNonAsciiString29("\u04401234567890123456789012345678"));
610         Assert.assertFalse(
611             $noinline$equalsConstNonAsciiString29("\u0440123456789012345678901234567"));
612         Assert.assertFalse(
613             $noinline$equalsConstNonAsciiString29("\u044012345678901234567890123456789"));
614         Assert.assertFalse(
615             $noinline$equalsConstNonAsciiString29("\u0440123456789012345678901234567x"));
616         Assert.assertFalse($noinline$equalsConstNonAsciiString29("01234567890123456789012345678"));
617 
618         Assert.assertTrue(
619             $noinline$equalsConstNonAsciiString35("\u04401234567890123456789012345678901234"));
620         Assert.assertFalse(
621             $noinline$equalsConstNonAsciiString35("\u0440123456789012345678901234567890123"));
622         Assert.assertFalse(
623             $noinline$equalsConstNonAsciiString35("\u044012345678901234567890123456789012345"));
624         Assert.assertFalse(
625             $noinline$equalsConstNonAsciiString35("\u0440123456789012345678901234567890123x"));
626         Assert.assertFalse(
627             $noinline$equalsConstNonAsciiString35("01234567890123456789012345678901234"));
628     }
629 
testConstStringEquals()630     public static void testConstStringEquals() {
631         Assert.assertTrue($noinline$constString0Equals(""));
632         Assert.assertFalse($noinline$constString0Equals("1"));
633 
634         Assert.assertTrue($noinline$constString7Equals("0123456"));
635         Assert.assertFalse($noinline$constString7Equals("012345"));
636         Assert.assertFalse($noinline$constString7Equals("01234567"));
637         Assert.assertFalse($noinline$constString7Equals("012345x"));
638         Assert.assertFalse($noinline$constString7Equals("012345\u0440"));
639 
640         Assert.assertTrue($noinline$constString14Equals("01234567890123"));
641         Assert.assertFalse($noinline$constString14Equals("0123456789012"));
642         Assert.assertFalse($noinline$constString14Equals("012345678901234"));
643         Assert.assertFalse($noinline$constString14Equals("0123456789012x"));
644         Assert.assertFalse($noinline$constString14Equals("0123456789012\u0440"));
645 
646         Assert.assertTrue($noinline$constString24Equals("012345678901234567890123"));
647         Assert.assertFalse($noinline$constString24Equals("01234567890123456789012"));
648         Assert.assertFalse($noinline$constString24Equals("0123456789012345678901234"));
649         Assert.assertFalse($noinline$constString24Equals("01234567890123456789012x"));
650         Assert.assertFalse($noinline$constString24Equals("01234567890123456789012\u0440"));
651 
652         Assert.assertTrue($noinline$constString29Equals("01234567890123456789012345678"));
653         Assert.assertFalse($noinline$constString29Equals("0123456789012345678901234567"));
654         Assert.assertFalse($noinline$constString29Equals("012345678901234567890123456789"));
655         Assert.assertFalse($noinline$constString29Equals("0123456789012345678901234567x"));
656         Assert.assertFalse($noinline$constString29Equals("0123456789012345678901234567\u0440"));
657 
658         Assert.assertTrue($noinline$constString35Equals("01234567890123456789012345678901234"));
659         Assert.assertFalse($noinline$constString35Equals("0123456789012345678901234567890123"));
660         Assert.assertFalse($noinline$constString35Equals("012345678901234567890123456789012345"));
661         Assert.assertFalse($noinline$constString35Equals("0123456789012345678901234567890123x"));
662         Assert.assertFalse(
663             $noinline$constString35Equals("0123456789012345678901234567890123\u0040"));
664 
665         Assert.assertTrue($noinline$constNonAsciiString7Equals("\u0440123456"));
666         Assert.assertFalse($noinline$constNonAsciiString7Equals("\u044012345"));
667         Assert.assertFalse($noinline$constNonAsciiString7Equals("\u04401234567"));
668         Assert.assertFalse($noinline$constNonAsciiString7Equals("\u044012345x"));
669         Assert.assertFalse($noinline$constNonAsciiString7Equals("0123456"));
670 
671         Assert.assertTrue($noinline$constNonAsciiString14Equals("\u04401234567890123"));
672         Assert.assertFalse($noinline$constNonAsciiString14Equals("\u0440123456789012"));
673         Assert.assertFalse($noinline$constNonAsciiString14Equals("\u044012345678901234"));
674         Assert.assertFalse($noinline$constNonAsciiString14Equals("\u0440123456789012x"));
675         Assert.assertFalse($noinline$constNonAsciiString14Equals("01234567890123"));
676 
677         Assert.assertTrue($noinline$constNonAsciiString24Equals("\u044012345678901234567890123"));
678         Assert.assertFalse($noinline$constNonAsciiString24Equals("\u04401234567890123456789012"));
679         Assert.assertFalse($noinline$constNonAsciiString24Equals("\u0440123456789012345678901234"));
680         Assert.assertFalse($noinline$constNonAsciiString24Equals("\u04401234567890123456789012x"));
681         Assert.assertFalse($noinline$constNonAsciiString24Equals("\012345678901234567890123"));
682 
683         Assert.assertTrue(
684             $noinline$constNonAsciiString29Equals("\u04401234567890123456789012345678"));
685         Assert.assertFalse(
686             $noinline$constNonAsciiString29Equals("\u0440123456789012345678901234567"));
687         Assert.assertFalse(
688             $noinline$constNonAsciiString29Equals("\u044012345678901234567890123456789"));
689         Assert.assertFalse(
690             $noinline$constNonAsciiString29Equals("\u0440123456789012345678901234567x"));
691         Assert.assertFalse($noinline$constNonAsciiString29Equals("01234567890123456789012345678"));
692 
693         Assert.assertTrue(
694             $noinline$constNonAsciiString35Equals("\u04401234567890123456789012345678901234"));
695         Assert.assertFalse(
696             $noinline$constNonAsciiString35Equals("\u0440123456789012345678901234567890123"));
697         Assert.assertFalse(
698             $noinline$constNonAsciiString35Equals("\u044012345678901234567890123456789012345"));
699         Assert.assertFalse(
700             $noinline$constNonAsciiString35Equals("\u0440123456789012345678901234567890123x"));
701         Assert.assertFalse(
702             $noinline$constNonAsciiString35Equals("01234567890123456789012345678901234"));
703     }
704 
$noinline$equalsConstString0(String s)705     public static boolean $noinline$equalsConstString0(String s) {
706         if (doThrow) { throw new Error(); }
707         return s.equals("");
708     }
709 
$noinline$equalsConstString7(String s)710     public static boolean $noinline$equalsConstString7(String s) {
711         if (doThrow) { throw new Error(); }
712         return s.equals("0123456");
713     }
714 
$noinline$equalsConstString14(String s)715     public static boolean $noinline$equalsConstString14(String s) {
716         if (doThrow) { throw new Error(); }
717         return s.equals("01234567890123");
718     }
719 
$noinline$equalsConstString24(String s)720     public static boolean $noinline$equalsConstString24(String s) {
721         if (doThrow) { throw new Error(); }
722         return s.equals("012345678901234567890123");
723     }
724 
$noinline$equalsConstString29(String s)725     public static boolean $noinline$equalsConstString29(String s) {
726         if (doThrow) { throw new Error(); }
727         return s.equals("01234567890123456789012345678");
728     }
729 
$noinline$equalsConstString35(String s)730     public static boolean $noinline$equalsConstString35(String s) {
731         if (doThrow) { throw new Error(); }
732         return s.equals("01234567890123456789012345678901234");
733     }
734 
$noinline$equalsConstNonAsciiString7(String s)735     public static boolean $noinline$equalsConstNonAsciiString7(String s) {
736         if (doThrow) { throw new Error(); }
737         return s.equals("\u0440123456");
738     }
739 
$noinline$equalsConstNonAsciiString14(String s)740     public static boolean $noinline$equalsConstNonAsciiString14(String s) {
741         if (doThrow) { throw new Error(); }
742         return s.equals("\u04401234567890123");
743     }
744 
$noinline$equalsConstNonAsciiString24(String s)745     public static boolean $noinline$equalsConstNonAsciiString24(String s) {
746         if (doThrow) { throw new Error(); }
747         return s.equals("\u044012345678901234567890123");
748     }
749 
$noinline$equalsConstNonAsciiString29(String s)750     public static boolean $noinline$equalsConstNonAsciiString29(String s) {
751         if (doThrow) { throw new Error(); }
752         return s.equals("\u04401234567890123456789012345678");
753     }
754 
$noinline$equalsConstNonAsciiString35(String s)755     public static boolean $noinline$equalsConstNonAsciiString35(String s) {
756         if (doThrow) { throw new Error(); }
757         return s.equals("\u04401234567890123456789012345678901234");
758     }
759 
$noinline$constString0Equals(String s)760     public static boolean $noinline$constString0Equals(String s) {
761         if (doThrow) { throw new Error(); }
762         return s.equals("");
763     }
764 
$noinline$constString7Equals(String s)765     public static boolean $noinline$constString7Equals(String s) {
766         if (doThrow) { throw new Error(); }
767         return "0123456".equals(s);
768     }
769 
$noinline$constString14Equals(String s)770     public static boolean $noinline$constString14Equals(String s) {
771         if (doThrow) { throw new Error(); }
772         return "01234567890123".equals(s);
773     }
774 
$noinline$constString24Equals(String s)775     public static boolean $noinline$constString24Equals(String s) {
776         if (doThrow) { throw new Error(); }
777         return "012345678901234567890123".equals(s);
778     }
779 
$noinline$constString29Equals(String s)780     public static boolean $noinline$constString29Equals(String s) {
781         if (doThrow) { throw new Error(); }
782         return "01234567890123456789012345678".equals(s);
783     }
784 
$noinline$constString35Equals(String s)785     public static boolean $noinline$constString35Equals(String s) {
786         if (doThrow) { throw new Error(); }
787         return "01234567890123456789012345678901234".equals(s);
788     }
789 
$noinline$constNonAsciiString7Equals(String s)790     public static boolean $noinline$constNonAsciiString7Equals(String s) {
791         if (doThrow) { throw new Error(); }
792         return "\u0440123456".equals(s);
793     }
794 
$noinline$constNonAsciiString14Equals(String s)795     public static boolean $noinline$constNonAsciiString14Equals(String s) {
796         if (doThrow) { throw new Error(); }
797         return "\u04401234567890123".equals(s);
798     }
799 
$noinline$constNonAsciiString24Equals(String s)800     public static boolean $noinline$constNonAsciiString24Equals(String s) {
801         if (doThrow) { throw new Error(); }
802         return "\u044012345678901234567890123".equals(s);
803     }
804 
$noinline$constNonAsciiString29Equals(String s)805     public static boolean $noinline$constNonAsciiString29Equals(String s) {
806         if (doThrow) { throw new Error(); }
807         return "\u04401234567890123456789012345678".equals(s);
808     }
809 
$noinline$constNonAsciiString35Equals(String s)810     public static boolean $noinline$constNonAsciiString35Equals(String s) {
811         if (doThrow) { throw new Error(); }
812         return "\u04401234567890123456789012345678901234".equals(s);
813     }
814 
$noinline$compareTo(String lhs, String rhs)815     public static int $noinline$compareTo(String lhs, String rhs) {
816         if (doThrow) { throw new Error(); }
817         return lhs.compareTo(rhs);
818     }
819 
$noinline$equals(String lhs, String rhs)820     public static boolean $noinline$equals(String lhs, String rhs) {
821         if (doThrow) { throw new Error(); }
822         return lhs.equals(rhs);
823     }
824 
$noinline$indexOf(String lhs, int ch)825     public static int $noinline$indexOf(String lhs, int ch) {
826         if (doThrow) { throw new Error(); }
827         return lhs.indexOf(ch);
828     }
829 
$noinline$indexOf(String lhs, int ch, int fromIndex)830     public static int $noinline$indexOf(String lhs, int ch, int fromIndex) {
831         if (doThrow) { throw new Error(); }
832         return lhs.indexOf(ch, fromIndex);
833     }
834 
835     public static boolean doThrow = false;
836 }
837