1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3/********************************************************************
4 * COPYRIGHT:
5 * Copyright (c) 2009-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
8/********************************************************************************
9*
10* File spooftest.c
11*
12*********************************************************************************/
13/*C API TEST for the uspoof Unicode Indentifier Spoofing and Security API */
14/**
15*   This is an API test for ICU spoof detection in plain C.  It doesn't test very many cases, and doesn't
16*   try to test the full functionality.  It just calls each function and verifies that it
17*   works on a basic level.
18*
19*   More complete testing of spoof detection functionality is done with the C++ tests.
20**/
21
22#include "unicode/utypes.h"
23#if !UCONFIG_NO_REGULAR_EXPRESSIONS && !UCONFIG_NO_NORMALIZATION
24
25#include <stdlib.h>
26#include <stdio.h>
27#include <string.h>
28#include "unicode/uspoof.h"
29#include "unicode/ustring.h"
30#include "unicode/uset.h"
31#include "cintltst.h"
32#include "cmemory.h"
33
34#define TEST_ASSERT_SUCCESS(status) {if (U_FAILURE(status)) { \
35    log_err_status(status, "Failure at file %s, line %d, error = %s\n", __FILE__, __LINE__, u_errorName(status));}}
36
37#define TEST_ASSERT(expr) {if ((expr)==FALSE) { \
38log_err("Test Failure at file %s, line %d: \"%s\" is false.\n", __FILE__, __LINE__, #expr);};}
39
40#define TEST_ASSERT_EQ(a, b) { if ((a) != (b)) { \
41    log_err("Test Failure at file %s, line %d: \"%s\" (%d) != \"%s\" (%d) \n", \
42             __FILE__, __LINE__, #a, (a), #b, (b)); }}
43
44#define TEST_ASSERT_NE(a, b) { if ((a) == (b)) { \
45    log_err("Test Failure at file %s, line %d: \"%s\" (%d) == \"%s\" (%d) \n", \
46             __FILE__, __LINE__, #a, (a), #b, (b)); }}
47
48
49/*
50 *   TEST_SETUP and TEST_TEARDOWN
51 *         macros to handle the boilerplate around setting up test case.
52 *         Put arbitrary test code between SETUP and TEARDOWN.
53 *         "sc" is the ready-to-go  SpoofChecker for use in the tests.
54 */
55#define TEST_SETUP {  \
56    UErrorCode status = U_ZERO_ERROR; \
57    USpoofChecker *sc;     \
58    sc = uspoof_open(&status);  \
59    TEST_ASSERT_SUCCESS(status);   \
60    if (U_SUCCESS(status)){
61
62#define TEST_TEARDOWN  \
63    }  \
64    TEST_ASSERT_SUCCESS(status);  \
65    uspoof_close(sc);  \
66}
67
68static void TestOpenFromSource(void);
69static void TestUSpoofCAPI(void);
70
71void addUSpoofTest(TestNode** root);
72
73void addUSpoofTest(TestNode** root)
74{
75#if !UCONFIG_NO_FILE_IO
76    addTest(root, &TestOpenFromSource, "uspoof/TestOpenFromSource");
77#endif
78    addTest(root, &TestUSpoofCAPI, "uspoof/TestUSpoofCAPI");
79}
80
81/*
82 *  Identifiers for verifying that spoof checking is minimally alive and working.
83 */
84const UChar goodLatin[] = {(UChar)0x75, (UChar)0x7a, 0};    /* "uz", all ASCII             */
85                                                            /*   (not confusable)          */
86const UChar scMixed[]  = {(UChar)0x73, (UChar)0x0441, 0};   /* "sc", with Cyrillic 'c'     */
87                                                            /*   (mixed script, confusable */
88
89const UChar scLatin[]  = {(UChar)0x73,  (UChar)0x63, 0};    /* "sc", plain ascii.        */
90const UChar goodCyrl[] = {(UChar)0x438, (UChar)0x43B, 0};   /* Plain lower case Cyrillic letters,
91                                                               no latin confusables         */
92
93const UChar goodGreek[]   = {(UChar)0x3c0, (UChar)0x3c6, 0};   /* Plain lower case Greek letters */
94
95const UChar lll_Latin_a[] = {(UChar)0x6c, (UChar)0x49, (UChar)0x31, 0};   /* lI1, all ASCII */
96
97                             /*  Full-width I, Small Roman Numeral fifty, Latin Cap Letter IOTA*/
98const UChar lll_Latin_b[] = {(UChar)0xff29, (UChar)0x217c, (UChar)0x196, 0};
99
100const UChar lll_Cyrl[]    = {(UChar)0x0406, (UChar)0x04C0, (UChar)0x31, 0};
101
102/* The skeleton transform for all of thes 'lll' lookalikes is all lower case l. */
103const UChar lll_Skel[]    = {(UChar)0x6c, (UChar)0x6c, (UChar)0x6c, 0};
104
105const UChar han_Hiragana[] = {(UChar)0x3086, (UChar)0x308A, (UChar)0x0020, (UChar)0x77F3, (UChar)0x7530, 0};
106
107/* Provide better code coverage */
108const char goodLatinUTF8[]    = {0x75, 0x77, 0};
109
110// Test open from source rules.
111// Run this in isolation to verify initialization.
112static void TestOpenFromSource() {
113    // No TEST_SETUP because that calls uspoof_open().
114    UErrorCode status = U_ZERO_ERROR;
115    const char *dataSrcDir;
116    char       *fileName;
117    char       *confusables;
118    int         confusablesLength = 0;
119    char       *confusablesWholeScript;
120    int         confusablesWholeScriptLength = 0;
121    FILE       *f;
122    UParseError pe;
123    int32_t     errType;
124    int32_t     checkResults;
125    USpoofChecker *rsc;
126
127    dataSrcDir = ctest_dataSrcDir();
128    fileName = malloc(strlen(dataSrcDir) + 100);
129    strcpy(fileName, dataSrcDir);
130    strcat(fileName, U_FILE_SEP_STRING "unidata" U_FILE_SEP_STRING "confusables.txt");
131    f = fopen(fileName, "rb");
132    TEST_ASSERT_NE(f, NULL);
133    confusables = malloc(3000000);
134    if (f != NULL) {
135        confusablesLength = fread(confusables, 1, 3000000, f);
136        fclose(f);
137    }
138
139    strcpy(fileName, dataSrcDir);
140    strcat(fileName, U_FILE_SEP_STRING "unidata" U_FILE_SEP_STRING "confusablesWholeScript.txt");
141    f = fopen(fileName, "rb");
142    TEST_ASSERT_NE(f, NULL);
143    confusablesWholeScript = malloc(1000000);
144    if (f != NULL) {
145        confusablesWholeScriptLength = fread(confusablesWholeScript, 1, 1000000, f);
146        fclose(f);
147    }
148
149    rsc = uspoof_openFromSource(confusables, confusablesLength,
150                                confusablesWholeScript, confusablesWholeScriptLength,
151                                &errType, &pe, &status);
152    TEST_ASSERT_SUCCESS(status);
153
154    // Ticket #11860: uspoof_openFromSource() did not initialize for use.
155    // Verify that the spoof checker does not crash.
156    checkResults = uspoof_check(rsc, goodLatin, -1, NULL, &status);
157    TEST_ASSERT_SUCCESS(status);
158    TEST_ASSERT_EQ(0, checkResults);
159
160    free(confusablesWholeScript);
161    free(confusables);
162    free(fileName);
163    uspoof_close(rsc);
164    /*  printf("ParseError Line is %d\n", pe.line);  */
165}
166
167/*
168 *   Spoof Detection C API Tests
169 */
170static void TestUSpoofCAPI(void) {
171
172    /*
173     *  basic uspoof_open().
174     */
175    {
176        USpoofChecker *sc;
177        UErrorCode  status = U_ZERO_ERROR;
178        sc = uspoof_open(&status);
179        TEST_ASSERT_SUCCESS(status);
180        if (U_FAILURE(status)) {
181            /* If things are so broken that we can't even open a default spoof checker,  */
182            /*   don't even try the rest of the tests.  They would all fail.             */
183            return;
184        }
185        uspoof_close(sc);
186    }
187
188    /*
189     * openFromSerialized and serialize
190    */
191    TEST_SETUP
192        int32_t        serializedSize = 0;
193        int32_t        actualLength = 0;
194        char           *buf;
195        USpoofChecker  *sc2;
196        int32_t         checkResults;
197
198
199        serializedSize = uspoof_serialize(sc, NULL, 0, &status);
200        TEST_ASSERT_EQ(status, U_BUFFER_OVERFLOW_ERROR);
201        TEST_ASSERT(serializedSize > 0);
202
203        /* Serialize the default spoof checker */
204        status = U_ZERO_ERROR;
205        buf = (char *)malloc(serializedSize + 10);
206        TEST_ASSERT(buf != NULL);
207        buf[serializedSize] = 42;
208        uspoof_serialize(sc, buf, serializedSize, &status);
209        TEST_ASSERT_SUCCESS(status);
210        TEST_ASSERT_EQ(42, buf[serializedSize]);
211
212        /* Create a new spoof checker from the freshly serialized data */
213        sc2 = uspoof_openFromSerialized(buf, serializedSize+10, &actualLength, &status);
214        TEST_ASSERT_SUCCESS(status);
215        TEST_ASSERT_NE(NULL, sc2);
216        TEST_ASSERT_EQ(serializedSize, actualLength);
217
218        /* Verify that the new spoof checker at least wiggles */
219        checkResults = uspoof_check(sc2, goodLatin, -1, NULL, &status);
220        TEST_ASSERT_SUCCESS(status);
221        TEST_ASSERT_EQ(0, checkResults);
222
223        checkResults = uspoof_check(sc2, scMixed, -1, NULL, &status);
224        TEST_ASSERT_SUCCESS(status);
225        TEST_ASSERT_EQ(USPOOF_SINGLE_SCRIPT, checkResults);
226
227        uspoof_close(sc2);
228        free(buf);
229    TEST_TEARDOWN;
230
231
232
233    /*
234     * Set & Get Check Flags
235    */
236    TEST_SETUP
237        int32_t t;
238        uspoof_setChecks(sc, USPOOF_ALL_CHECKS, &status);
239        TEST_ASSERT_SUCCESS(status);
240        t = uspoof_getChecks(sc, &status);
241        TEST_ASSERT_EQ(t, USPOOF_ALL_CHECKS);
242
243        uspoof_setChecks(sc, 0, &status);
244        TEST_ASSERT_SUCCESS(status);
245        t = uspoof_getChecks(sc, &status);
246        TEST_ASSERT_EQ(0, t);
247
248        uspoof_setChecks(sc,
249                        USPOOF_WHOLE_SCRIPT_CONFUSABLE | USPOOF_MIXED_SCRIPT_CONFUSABLE | USPOOF_ANY_CASE,
250                        &status);
251        TEST_ASSERT_SUCCESS(status);
252        t = uspoof_getChecks(sc, &status);
253        TEST_ASSERT_SUCCESS(status);
254        TEST_ASSERT_EQ(USPOOF_WHOLE_SCRIPT_CONFUSABLE | USPOOF_MIXED_SCRIPT_CONFUSABLE | USPOOF_ANY_CASE, t);
255    TEST_TEARDOWN;
256
257    /*
258    * get & setAllowedChars
259    */
260    TEST_SETUP
261        USet *us;
262        const USet *uset;
263
264        uset = uspoof_getAllowedChars(sc, &status);
265        TEST_ASSERT_SUCCESS(status);
266        TEST_ASSERT(uset_isFrozen(uset));
267        us = uset_open((UChar32)0x41, (UChar32)0x5A);   /*  [A-Z]  */
268        uspoof_setAllowedChars(sc, us, &status);
269        TEST_ASSERT_SUCCESS(status);
270        TEST_ASSERT_NE(us, uspoof_getAllowedChars(sc, &status));
271        TEST_ASSERT(uset_equals(us, uspoof_getAllowedChars(sc, &status)));
272        TEST_ASSERT_SUCCESS(status);
273        uset_close(us);
274    TEST_TEARDOWN;
275
276    /*
277    *  clone()
278    */
279
280    TEST_SETUP
281        USpoofChecker *clone1 = NULL;
282        USpoofChecker *clone2 = NULL;
283        int32_t        checkResults = 0;
284
285        clone1 = uspoof_clone(sc, &status);
286        TEST_ASSERT_SUCCESS(status);
287        TEST_ASSERT_NE(clone1, sc);
288
289        clone2 = uspoof_clone(clone1, &status);
290        TEST_ASSERT_SUCCESS(status);
291        TEST_ASSERT_NE(clone2, clone1);
292
293        uspoof_close(clone1);
294
295        /* Verify that the cloned spoof checker is alive */
296        checkResults = uspoof_check(clone2, goodLatin, -1, NULL, &status);
297        TEST_ASSERT_SUCCESS(status);
298        TEST_ASSERT_EQ(0, checkResults);
299
300        checkResults = uspoof_check(clone2, scMixed, -1, NULL, &status);
301        TEST_ASSERT_SUCCESS(status);
302        TEST_ASSERT_EQ(USPOOF_SINGLE_SCRIPT, checkResults);
303        uspoof_close(clone2);
304    TEST_TEARDOWN;
305
306     /*
307     *  basic uspoof_check()
308     */
309     TEST_SETUP
310         int32_t result;
311         result = uspoof_check(sc, goodLatin, -1, NULL, &status);
312         TEST_ASSERT_SUCCESS(status);
313         TEST_ASSERT_EQ(0, result);
314
315         result = uspoof_check(sc, han_Hiragana, -1, NULL, &status);
316         TEST_ASSERT_SUCCESS(status);
317         TEST_ASSERT_EQ(0, result);
318
319         result = uspoof_check(sc, scMixed, -1, NULL, &status);
320         TEST_ASSERT_SUCCESS(status);
321         TEST_ASSERT_EQ(USPOOF_SINGLE_SCRIPT, result);
322     TEST_TEARDOWN
323
324
325    /*
326     *  get & set Checks
327    */
328    TEST_SETUP
329        int32_t   checks;
330        int32_t   checks2;
331        int32_t   checkResults;
332
333        checks = uspoof_getChecks(sc, &status);
334        TEST_ASSERT_SUCCESS(status);
335        TEST_ASSERT_EQ(USPOOF_ALL_CHECKS, checks);
336
337        checks &= ~(USPOOF_SINGLE_SCRIPT | USPOOF_MIXED_SCRIPT_CONFUSABLE);
338        uspoof_setChecks(sc, checks, &status);
339        TEST_ASSERT_SUCCESS(status);
340        checks2 = uspoof_getChecks(sc, &status);
341        TEST_ASSERT_EQ(checks, checks2);
342
343        /* The checks that were disabled just above are the same ones that the "scMixed" test fails.
344            So with those tests gone checking that Identifier should now succeed */
345        checkResults = uspoof_check(sc, scMixed, -1, NULL, &status);
346        TEST_ASSERT_SUCCESS(status);
347        TEST_ASSERT_EQ(0, checkResults);
348    TEST_TEARDOWN;
349
350    /*
351     *  AllowedLoacles
352     */
353
354    TEST_SETUP
355        const char  *allowedLocales;
356        int32_t  checkResults;
357
358        /* Default allowed locales list should be empty */
359        allowedLocales = uspoof_getAllowedLocales(sc, &status);
360        TEST_ASSERT_SUCCESS(status);
361        TEST_ASSERT(strcmp("", allowedLocales) == 0)
362
363        /* Allow en and ru, which should enable Latin and Cyrillic only to pass */
364        uspoof_setAllowedLocales(sc, "en, ru_RU", &status);
365        TEST_ASSERT_SUCCESS(status);
366        allowedLocales = uspoof_getAllowedLocales(sc, &status);
367        TEST_ASSERT_SUCCESS(status);
368        TEST_ASSERT(strstr(allowedLocales, "en") != NULL);
369        TEST_ASSERT(strstr(allowedLocales, "ru") != NULL);
370
371        /* Limit checks to USPOOF_CHAR_LIMIT.  Some of the test data has whole script confusables also,
372         * which we don't want to see in this test. */
373        uspoof_setChecks(sc, USPOOF_CHAR_LIMIT, &status);
374        TEST_ASSERT_SUCCESS(status);
375
376        checkResults = uspoof_check(sc, goodLatin, -1, NULL, &status);
377        TEST_ASSERT_SUCCESS(status);
378        TEST_ASSERT_EQ(0, checkResults);
379
380        checkResults = uspoof_check(sc, goodGreek, -1, NULL, &status);
381        TEST_ASSERT_SUCCESS(status);
382        TEST_ASSERT_EQ(USPOOF_CHAR_LIMIT, checkResults);
383
384        checkResults = uspoof_check(sc, goodCyrl, -1, NULL, &status);
385        TEST_ASSERT_SUCCESS(status);
386        TEST_ASSERT_EQ(0, checkResults);
387
388        /* Reset with an empty locale list, which should allow all characters to pass */
389        uspoof_setAllowedLocales(sc, " ", &status);
390        TEST_ASSERT_SUCCESS(status);
391
392        checkResults = uspoof_check(sc, goodGreek, -1, NULL, &status);
393        TEST_ASSERT_SUCCESS(status);
394        TEST_ASSERT_EQ(0, checkResults);
395    TEST_TEARDOWN;
396
397    /*
398     * AllowedChars   set/get the USet of allowed characters.
399     */
400    TEST_SETUP
401        const USet  *set;
402        USet        *tmpSet;
403        int32_t      checkResults;
404
405        /* By default, we should see no restriction; the USet should allow all characters. */
406        set = uspoof_getAllowedChars(sc, &status);
407        TEST_ASSERT_SUCCESS(status);
408        tmpSet = uset_open(0, 0x10ffff);
409        TEST_ASSERT(uset_equals(tmpSet, set));
410
411        /* Setting the allowed chars should enable the check. */
412        uspoof_setChecks(sc, USPOOF_ALL_CHECKS & ~USPOOF_CHAR_LIMIT, &status);
413        TEST_ASSERT_SUCCESS(status);
414
415        /* Remove a character that is in our good Latin test identifier from the allowed chars set. */
416        uset_remove(tmpSet, goodLatin[1]);
417        uspoof_setAllowedChars(sc, tmpSet, &status);
418        TEST_ASSERT_SUCCESS(status);
419        uset_close(tmpSet);
420
421        /* Latin Identifier should now fail; other non-latin test cases should still be OK
422         *  Note: fail of CHAR_LIMIT also causes the restriction level to be USPOOF_UNRESTRICTIVE
423         *        which will give us a USPOOF_RESTRICTION_LEVEL failure.
424         */
425        checkResults = uspoof_check(sc, goodLatin, -1, NULL, &status);
426        TEST_ASSERT_SUCCESS(status);
427        TEST_ASSERT_EQ(USPOOF_CHAR_LIMIT | USPOOF_RESTRICTION_LEVEL, checkResults);
428
429        checkResults = uspoof_check(sc, goodGreek, -1, NULL, &status);
430        TEST_ASSERT_SUCCESS(status);
431        TEST_ASSERT_EQ(0, checkResults);
432    TEST_TEARDOWN;
433
434    /*
435     * check UTF-8
436     */
437    TEST_SETUP
438        char    utf8buf[200];
439        int32_t checkResults, checkResults2;
440        int32_t position;
441
442        u_strToUTF8(utf8buf, sizeof(utf8buf), NULL, goodLatin, -1, &status);
443        TEST_ASSERT_SUCCESS(status);
444        position = 666;
445        checkResults = uspoof_checkUTF8(sc, utf8buf, -1, &position, &status);
446        TEST_ASSERT_SUCCESS(status);
447        TEST_ASSERT_EQ(0, checkResults);
448        TEST_ASSERT_EQ(0, position);
449
450        u_strToUTF8(utf8buf, sizeof(utf8buf), NULL, goodCyrl, -1, &status);
451        TEST_ASSERT_SUCCESS(status);
452        checkResults = uspoof_checkUTF8(sc, utf8buf, -1, &position, &status);
453        TEST_ASSERT_SUCCESS(status);
454        TEST_ASSERT_EQ(0, checkResults);
455
456        u_strToUTF8(utf8buf, sizeof(utf8buf), NULL, scMixed, -1, &status);
457        TEST_ASSERT_SUCCESS(status);
458        position = 666;
459        checkResults = uspoof_checkUTF8(sc, utf8buf, -1, &position, &status);
460        checkResults2 = uspoof_check(sc, scMixed, -1, NULL, &status);
461        TEST_ASSERT_SUCCESS(status);
462        TEST_ASSERT_EQ(USPOOF_SINGLE_SCRIPT , checkResults);
463        TEST_ASSERT_EQ(0, position);
464        TEST_ASSERT_EQ(checkResults , checkResults2);
465
466    TEST_TEARDOWN;
467
468    /*
469     * uspoof_check2 variants
470     */
471    TEST_SETUP
472        int32_t result1, result2;
473        char utf8buf[200];
474        uspoof_setChecks(sc, USPOOF_ALL_CHECKS | USPOOF_AUX_INFO, &status);
475        USpoofCheckResult* checkResult = uspoof_openCheckResult(&status);
476        TEST_ASSERT_SUCCESS(status);
477
478        const UChar* tests[] = { goodLatin, scMixed, scLatin,
479                goodCyrl, goodGreek, lll_Latin_a, lll_Latin_b, han_Hiragana };
480
481        for (int32_t i=0; i<UPRV_LENGTHOF(tests); i++) {
482            const UChar* str = tests[i];
483
484            // Basic test
485            result1 = uspoof_check(sc, str, -1, NULL, &status);
486            result2 = uspoof_check2(sc, str, -1, NULL, &status);
487            TEST_ASSERT_SUCCESS(status);
488            TEST_ASSERT_EQ(result1, result2);
489
490            // With check result parameter
491            result1 = uspoof_check(sc, str, -1, NULL, &status);
492            result2 = uspoof_check2(sc, str, -1, checkResult, &status);
493            TEST_ASSERT_SUCCESS(status);
494            TEST_ASSERT_EQ(result1, result2);
495
496            // Checks from checkResult should be same as those from bitmask
497            TEST_ASSERT_EQ(result1 & USPOOF_ALL_CHECKS, uspoof_getCheckResultChecks(checkResult, &status));
498
499            // Restriction level from checkResult should be same as that from bitmask
500            URestrictionLevel restrictionLevel = uspoof_getCheckResultRestrictionLevel(checkResult, &status);
501            TEST_ASSERT_EQ(result1 & restrictionLevel, restrictionLevel);
502
503            // UTF8 endpoint
504            u_strToUTF8(utf8buf, sizeof(utf8buf), NULL, goodLatin, -1, &status);
505            TEST_ASSERT_SUCCESS(status);
506            result1 = uspoof_checkUTF8(sc, utf8buf, -1, NULL, &status);
507            result2 = uspoof_check2UTF8(sc, utf8buf, -1, NULL, &status);
508            TEST_ASSERT_SUCCESS(status);
509            TEST_ASSERT_EQ(result1, result2);
510        }
511
512        uspoof_closeCheckResult(checkResult);
513    TEST_TEARDOWN;
514
515    /*
516     * uspoof_areConfusable()
517     */
518    TEST_SETUP
519        int32_t  checkResults;
520
521        checkResults = uspoof_areConfusable(sc, scLatin, -1, scMixed, -1, &status);
522        TEST_ASSERT_SUCCESS(status);
523        TEST_ASSERT_EQ(USPOOF_MIXED_SCRIPT_CONFUSABLE, checkResults);
524
525        checkResults = uspoof_areConfusable(sc, goodGreek, -1, scLatin, -1, &status);
526        TEST_ASSERT_SUCCESS(status);
527        TEST_ASSERT_EQ(0, checkResults);
528
529        checkResults = uspoof_areConfusable(sc, lll_Latin_a, -1, lll_Latin_b, -1, &status);
530        TEST_ASSERT_SUCCESS(status);
531        TEST_ASSERT_EQ(USPOOF_SINGLE_SCRIPT_CONFUSABLE, checkResults);
532
533    TEST_TEARDOWN;
534
535    /*
536     * areConfusableUTF8
537     */
538    TEST_SETUP
539        int32_t checkResults;
540        char s1[200];
541        char s2[200];
542
543
544        u_strToUTF8(s1, sizeof(s1), NULL, scLatin, -1, &status);
545        u_strToUTF8(s2, sizeof(s2), NULL, scMixed, -1, &status);
546        TEST_ASSERT_SUCCESS(status);
547        checkResults = uspoof_areConfusableUTF8(sc, s1, -1, s2, -1, &status);
548        TEST_ASSERT_SUCCESS(status);
549        TEST_ASSERT_EQ(USPOOF_MIXED_SCRIPT_CONFUSABLE, checkResults);
550
551        u_strToUTF8(s1, sizeof(s1), NULL, goodGreek, -1, &status);
552        u_strToUTF8(s2, sizeof(s2), NULL, scLatin, -1, &status);
553        TEST_ASSERT_SUCCESS(status);
554        checkResults = uspoof_areConfusableUTF8(sc, s1, -1, s2, -1, &status);
555        TEST_ASSERT_SUCCESS(status);
556        TEST_ASSERT_EQ(0, checkResults);
557
558        u_strToUTF8(s1, sizeof(s1), NULL, lll_Latin_a, -1, &status);
559        u_strToUTF8(s2, sizeof(s2), NULL, lll_Latin_b, -1, &status);
560        TEST_ASSERT_SUCCESS(status);
561        checkResults = uspoof_areConfusableUTF8(sc, s1, -1, s2, -1, &status);
562        TEST_ASSERT_SUCCESS(status);
563        TEST_ASSERT_EQ(USPOOF_SINGLE_SCRIPT_CONFUSABLE, checkResults);
564
565    TEST_TEARDOWN;
566
567
568  /*
569   * getSkeleton
570   */
571
572    TEST_SETUP
573        UChar dest[100];
574        int32_t   skelLength;
575
576        skelLength = uspoof_getSkeleton(sc, USPOOF_ANY_CASE, lll_Latin_a, -1, dest, UPRV_LENGTHOF(dest), &status);
577        TEST_ASSERT_SUCCESS(status);
578        TEST_ASSERT_EQ(0, u_strcmp(lll_Skel, dest));
579        TEST_ASSERT_EQ(u_strlen(lll_Skel), skelLength);
580
581        skelLength = uspoof_getSkeletonUTF8(sc, USPOOF_ANY_CASE, goodLatinUTF8, -1, (char*)dest,
582                                            UPRV_LENGTHOF(dest), &status);
583        TEST_ASSERT_SUCCESS(status);
584
585        skelLength = uspoof_getSkeleton(sc, USPOOF_ANY_CASE, lll_Latin_a, -1, NULL, 0, &status);
586        TEST_ASSERT_EQ(U_BUFFER_OVERFLOW_ERROR, status);
587        TEST_ASSERT_EQ(3, skelLength);
588        status = U_ZERO_ERROR;
589
590    TEST_TEARDOWN;
591
592    /*
593     * get Inclusion and Recommended sets
594     */
595    TEST_SETUP
596        const USet *inclusions = NULL;
597        const USet *recommended = NULL;
598
599        inclusions = uspoof_getInclusionSet(&status);
600        TEST_ASSERT_SUCCESS(status);
601        TEST_ASSERT_EQ(TRUE, uset_isFrozen(inclusions));
602
603        status = U_ZERO_ERROR;
604        recommended = uspoof_getRecommendedSet(&status);
605        TEST_ASSERT_SUCCESS(status);
606        TEST_ASSERT_EQ(TRUE, uset_isFrozen(recommended));
607    TEST_TEARDOWN;
608
609}
610
611#endif  /* UCONFIG_NO_REGULAR_EXPRESSIONS */
612