From a97583a817d0883c2a08af2ec7e8dda983237deb Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Mon, 7 Sep 2015 01:18:49 +0000 Subject: [PATCH] ICU-11860 uspoof_openFromSource() initializes static variables; isolate test code for uspoof_openFromSource() so that initialization can be tested X-SVN-Rev: 37895 --- icu4c/source/i18n/uspoof.cpp | 3 ++ icu4c/source/i18n/uspoof_build.cpp | 6 ++- icu4c/source/test/cintltst/spooftest.c | 73 ++++++++++++++------------ 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/icu4c/source/i18n/uspoof.cpp b/icu4c/source/i18n/uspoof.cpp index 551ba03d3a4..44131b5a6fc 100644 --- a/icu4c/source/i18n/uspoof.cpp +++ b/icu4c/source/i18n/uspoof.cpp @@ -133,6 +133,9 @@ static void U_CALLCONV initializeStatics(UErrorCode &status) { ucln_i18n_registerCleanup(UCLN_I18N_SPOOF, uspoof_cleanup); } +U_CFUNC void uspoof_internalInit(UErrorCode *status) { + umtx_initOnce(gSpoofInitOnce, &initializeStatics, *status); +} U_CAPI USpoofChecker * U_EXPORT2 uspoof_open(UErrorCode *status) { diff --git a/icu4c/source/i18n/uspoof_build.cpp b/icu4c/source/i18n/uspoof_build.cpp index 681282e0a89..47508bd7b28 100644 --- a/icu4c/source/i18n/uspoof_build.cpp +++ b/icu4c/source/i18n/uspoof_build.cpp @@ -1,6 +1,6 @@ /* *************************************************************************** - * Copyright (C) 2008-2009, International Business Machines Corporation + * Copyright (C) 2008-2015, International Business Machines Corporation * and others. All Rights Reserved. *************************************************************************** * file name: uspoof_build.cpp @@ -41,6 +41,8 @@ U_NAMESPACE_USE +// Defined in uspoof.cpp, initializes file-static variables. +U_CFUNC void uspoof_internalInit(UErrorCode *status); // The main data building function @@ -48,7 +50,7 @@ U_CAPI USpoofChecker * U_EXPORT2 uspoof_openFromSource(const char *confusables, int32_t confusablesLen, const char *confusablesWholeScript, int32_t confusablesWholeScriptLen, int32_t *errorType, UParseError *pe, UErrorCode *status) { - + uspoof_internalInit(status); if (U_FAILURE(*status)) { return NULL; } diff --git a/icu4c/source/test/cintltst/spooftest.c b/icu4c/source/test/cintltst/spooftest.c index 536754f72f3..ea70416f944 100644 --- a/icu4c/source/test/cintltst/spooftest.c +++ b/icu4c/source/test/cintltst/spooftest.c @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 2009-2014, International Business Machines Corporation and + * Copyright (c) 2009-2015, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ /******************************************************************************** @@ -62,7 +62,7 @@ log_err("Test Failure at file %s, line %d: \"%s\" is false.\n", __FILE__, __LINE uspoof_close(sc); \ } - +static void TestOpenFromSource(void); static void TestUSpoofCAPI(void); void addUSpoofTest(TestNode** root); @@ -70,8 +70,9 @@ void addUSpoofTest(TestNode** root); void addUSpoofTest(TestNode** root) { #if !UCONFIG_NO_FILE_IO - addTest(root, &TestUSpoofCAPI, "uspoof/TestUSpoofCAPI"); + addTest(root, &TestOpenFromSource, "uspoof/TestOpenFromSource"); #endif + addTest(root, &TestUSpoofCAPI, "uspoof/TestUSpoofCAPI"); } /* @@ -102,33 +103,12 @@ const UChar han_Hiragana[] = {(UChar)0x3086, (UChar)0x308A, (UChar)0x0020, (UCha /* Provide better code coverage */ const char goodLatinUTF8[] = {0x75, 0x77, 0}; -/* - * Spoof Detction C API Tests - */ -static void TestUSpoofCAPI(void) { - /* - * basic uspoof_open(). - */ - { - USpoofChecker *sc; - UErrorCode status = U_ZERO_ERROR; - sc = uspoof_open(&status); - TEST_ASSERT_SUCCESS(status); - if (U_FAILURE(status)) { - /* If things are so broken that we can't even open a default spoof checker, */ - /* don't even try the rest of the tests. They would all fail. */ - return; - } - uspoof_close(sc); - } - - - - /* - * Test Open from source rules. - */ - TEST_SETUP +// Test open from source rules. +// Run this in isolation to verify initialization. +static void TestOpenFromSource() { + // No TEST_SETUP because that calls uspoof_open(). + UErrorCode status = U_ZERO_ERROR; const char *dataSrcDir; char *fileName; char *confusables; @@ -138,8 +118,9 @@ static void TestUSpoofCAPI(void) { FILE *f; UParseError pe; int32_t errType; + int32_t checkResults; USpoofChecker *rsc; - + dataSrcDir = ctest_dataSrcDir(); fileName = malloc(strlen(dataSrcDir) + 100); strcpy(fileName, dataSrcDir); @@ -163,17 +144,43 @@ static void TestUSpoofCAPI(void) { } rsc = uspoof_openFromSource(confusables, confusablesLength, - confusablesWholeScript, confusablesWholeScriptLength, - &errType, &pe, &status); + confusablesWholeScript, confusablesWholeScriptLength, + &errType, &pe, &status); TEST_ASSERT_SUCCESS(status); + // Ticket #11860: uspoof_openFromSource() did not initialize for use. + // Verify that the spoof checker does not crash. + checkResults = uspoof_check(rsc, goodLatin, -1, NULL, &status); + TEST_ASSERT_SUCCESS(status); + TEST_ASSERT_EQ(0, checkResults); + free(confusablesWholeScript); free(confusables); free(fileName); uspoof_close(rsc); /* printf("ParseError Line is %d\n", pe.line); */ - TEST_TEARDOWN; +} +/* + * Spoof Detection C API Tests + */ +static void TestUSpoofCAPI(void) { + + /* + * basic uspoof_open(). + */ + { + USpoofChecker *sc; + UErrorCode status = U_ZERO_ERROR; + sc = uspoof_open(&status); + TEST_ASSERT_SUCCESS(status); + if (U_FAILURE(status)) { + /* If things are so broken that we can't even open a default spoof checker, */ + /* don't even try the rest of the tests. They would all fail. */ + return; + } + uspoof_close(sc); + } /* * openFromSerialized and serialize