1 /*
  2  * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 /*
 25  * @test
 26  * @bug 4221795 8174270
 27  * @summary Confirm Normalizer's fundamental behavior
 28  * @modules java.base/sun.text java.base/jdk.internal.icu.text
 29  * @library /java/text/testlib
 30  * @compile -XDignore.symbol.file NormalizerAPITest.java
 31  * @run main/timeout=30 NormalizerAPITest
 32  */
 33 
 34 import java.text.Normalizer;
 35 import java.nio.CharBuffer;
 36 
 37 
 38 /*
 39  * Tests around null/"" arguments for public methods.
 40  *
 41  * You may think that so elaborate testing for such a part is not necessary.
 42  * But I actually detected a bug by this program during my porting work.
 43  */
 44 public class NormalizerAPITest extends IntlTest {
 45 
 46     //
 47     // Shortcuts
 48     //
 49 
 50     /*
 51      * Normalization forms
 52      */
 53     static final Normalizer.Form NFC  = Normalizer.Form.NFC;
 54     static final Normalizer.Form NFD  = Normalizer.Form.NFD;
 55     static final Normalizer.Form NFKC = Normalizer.Form.NFKC;
 56     static final Normalizer.Form NFKD = Normalizer.Form.NFKD;
 57     static final Normalizer.Form[] forms = {NFC, NFD, NFKC, NFKD};
 58 
 59     static final Normalizer.Form NULL = null;
 60 
 61     /*
 62      * Option
 63      */
 64     static final int[] options = {
 65         0x00,
 66         sun.text.Normalizer.UNICODE_3_2,
 67         jdk.internal.icu.text.NormalizerBase.UNICODE_3_2,
 68         jdk.internal.icu.text.NormalizerBase.UNICODE_LATEST,
 69     };
 70 
 71     static final String nonNullStr = "testdata";
 72 
 73 
 74     public static void main(String[] args) throws Exception {
 75         new NormalizerAPITest().run(args);
 76     }
 77 
 78     /*
 79      * Check if normalize(null) throws NullPointerException as expected.
 80      */
 81     public void Test_NullPointerException_java_normalize() {
 82         boolean error = false;
 83 
 84         /* Check null as String to be normalized */
 85         for (int i = 0; i < forms.length; i++) {
 86             try {
 87                 String s = Normalizer.normalize(null, forms[i]);
 88                 error = true;
 89             }
 90             catch (NullPointerException e) {
 91             }
 92         }
 93 
 94         /* Check null as a Normalization form */
 95         try {
 96             String s = Normalizer.normalize(nonNullStr, NULL);
 97             error = true;
 98         }
 99         catch (NullPointerException e) {
100         }
101 
102         if (error) {
103              errln("normalize(null) should throw NullPointerException.");
104         }
105     }
106 
107     /*
108      * Check if normalize(null) throws NullPointerException as expected.
109      */
110     public void Test_NullPointerException_sun_normalize() {
111         boolean error = false;
112 
113         for (int j = 0; j < options.length; j++) {
114             for (int i = 0; i < forms.length; i++) {
115                 /* Check null as a String to be normalized */
116                 try {
117                     String s = sun.text.Normalizer.normalize(null, forms[i], options[j]);
118                     error = true;
119                 }
120                 catch (NullPointerException e) {
121                 }
122             }
123 
124             /* Check null as a Normalization form */
125             try {
126                 String s = sun.text.Normalizer.normalize(nonNullStr, NULL, options[j]);
127                 error = true;
128             }
129             catch (NullPointerException e) {
130             }
131         }
132 
133         if (error) {
134              errln("normalize(null) should throw NullPointerException.");
135         }
136     }
137 
138     /*
139      * Check if isNormalized(null) throws NullPointerException as expected.
140      */
141     public void Test_NullPointerException_java_isNormalized() {
142         boolean error = false;
143 
144         for (int i = 0; i < forms.length; i++) {
145             try {
146                 /* Check null as a String to be scanned */
147                 boolean b = Normalizer.isNormalized(null, forms[i]);
148                 error = true;
149             }
150             catch (NullPointerException e) {
151             }
152         }
153 
154         /* Check null as a String to be scanned */
155         try {
156             boolean b = Normalizer.isNormalized(nonNullStr, NULL);
157             error = true;
158         }
159 
160         catch (NullPointerException e) {
161         }
162         if (error) {
163              errln("isNormalized(null) should throw NullPointerException.");
164         }
165     }
166 
167     /*
168      * Check if isNormalized(null) throws NullPointerException as expected.
169      */
170     public void Test_NullPointerException_sun_isNormalized() {
171         boolean error = false;
172 
173         for (int j = 0; j < options.length; j++) {
174             for (int i = 0; i < forms.length; i++) {
175                 try {
176                     /* Check null as a String to be scanned */
177                     boolean b = sun.text.Normalizer.isNormalized(null, forms[i], options[j]);
178                     error = true;
179                 }
180                 catch (NullPointerException e) {
181                 }
182             }
183 
184             /* Check null as a String to be scanned */
185             try {
186                 boolean b = sun.text.Normalizer.isNormalized(nonNullStr, NULL, options[j]);
187                 error = true;
188             }
189             catch (NullPointerException e) {
190             }
191         }
192 
193         if (error) {
194              errln("isNormalized(null) should throw NullPointerException.");
195         }
196     }
197 
198     /*
199      * Check if isNormalized("") doesn't throw NullPointerException and returns
200      * "" as expected.
201      */
202     public void Test_No_NullPointerException_java_normalize() {
203         boolean error = false;
204 
205         for (int i = 0; i < forms.length; i++) {
206             try {
207                 String s = Normalizer.normalize("", forms[i]);
208                 if (!s.equals("")) {
209                     error = true;
210                 }
211             }
212             catch (NullPointerException e) {
213                 error = true;
214             }
215         }
216 
217         if (error) {
218              errln("normalize() for String(\"\") should return \"\".");
219         }
220     }
221 
222     /*
223      * Check if isNormalized("") doesn't throw NullPointerException and returns
224      * "" as expected.
225      */
226     public void Test_No_NullPointerException_sun_normalize() {
227         boolean error = false;
228 
229         for (int j = 0; j < options.length; j++) {
230             for (int i = 0; i < forms.length; i++) {
231                 try {
232                     String s = sun.text.Normalizer.normalize("", forms[i], options[j]);
233                     if (!s.equals("")) {
234                         error = true;
235                     }
236                 }
237                 catch (NullPointerException e) {
238                     error = true;
239                 }
240             }
241         }
242         if (error) {
243              errln("normalize() for String(\"\") should return \"\".");
244         }
245     }
246 
247     /*
248      * Check if isNormalized("") doesn't throw NullPointerException and returns
249      * "" as expected.
250      */
251     public void Test_No_NullPointerException_java_isNormalized() {
252         boolean error = false;
253 
254         for (int i = 0; i < forms.length; i++) {
255             try {
256                 boolean b = Normalizer.isNormalized("", forms[i]);
257                 if (!b) {
258                     error = true;
259                 }
260             }
261             catch (NullPointerException e) {
262                 error = true;
263             }
264         }
265         if (error) {
266              errln("isNormalized() for String(\"\") should not return true.");
267         }
268     }
269 
270     /*
271      * Check if isNormalized("") doesn't throw NullPointerException and returns
272      * "" as expected.
273      */
274     public void Test_No_NullPointerException_sun_isNormalized() {
275         boolean error = false;
276 
277         for (int j = 0; j < options.length; j++) {
278             for (int i = 0; i < forms.length; i++) {
279                 try {
280                     boolean b = sun.text.Normalizer.isNormalized("", forms[i], options[j]);
281                     if (!b) {
282                         error = true;
283                     }
284                 }
285                 catch (NullPointerException e) {
286                     error = true;
287                 }
288             }
289         }
290         if (error) {
291              errln("isNormalized() for String(\"\") should not return true.");
292         }
293     }
294 
295     /*
296      * Check if normalize() and isNormalized() work as expected for every
297      * known class which implement CharSequence Interface.
298      */
299     public void Test_CharSequence() {
300 
301         check_CharSequence(String.valueOf(inputData),
302                            String.valueOf(outputData));
303 
304         check_CharSequence(new StringBuffer(original),
305                            new StringBuffer(expected));
306 
307         check_CharSequence(new StringBuilder(original),
308                            new StringBuilder(expected));
309 
310         check_CharSequence(CharBuffer.wrap(inputData),
311                            CharBuffer.wrap(outputData));
312     }
313 
314 
315     void check_CharSequence(CharSequence in, CharSequence expected) {
316         String out = Normalizer.normalize(in, NFD);
317         if (!out.equals(expected.toString())) {
318             errln("java.text.Normalizer.normalize(" +
319                   in.getClass().getSimpleName() + ") failed.");
320         }
321         out = sun.text.Normalizer.normalize(in, NFD,
322                              jdk.internal.icu.text.NormalizerBase.UNICODE_LATEST);
323         if (!out.equals(expected.toString())) {
324             errln("sun.text.Normalizer.normalize(" +
325                   in.getClass().getSimpleName() + ") failed.");
326         }
327 
328         if (!Normalizer.isNormalized(expected, NFD)) {
329             errln("java.text.Normalizer.isNormalize(" +
330                   in.getClass().getSimpleName() + ") failed.");
331         }
332         if (!sun.text.Normalizer.isNormalized(expected, NFD,
333                            jdk.internal.icu.text.NormalizerBase.UNICODE_LATEST)) {
334             errln("sun.text.Normalizer.isNormalize(" +
335                   in.getClass().getSimpleName() + ") failed.");
336         }
337     }
338 
339     static final char[] inputData  = {'T', 's', 'c', 'h', 'u', '\u1e9b'};
340     static final char[] outputData = {'T', 's', 'c', 'h', 'u', '\u017f', '\u0307'};
341     static final String original   = String.valueOf(inputData);
342     static final String expected   = String.valueOf(outputData);
343 }