static void TestFCDCrash(void) { static const char *test[] = { "Gr\\u00F6\\u00DFe", "Grossist" }; UErrorCode status = U_ZERO_ERROR; UCollator *coll = ucol_open("es", &status); if(U_FAILURE(status)) { log_err_status(status, "Couldn't open collator -> %s\n", u_errorName(status)); return; } ucol_close(coll); coll = NULL; ctest_resetICU(); coll = ucol_open("de_DE", &status); if(U_FAILURE(status)) { log_err_status(status, "Couldn't open collator -> %s\n", u_errorName(status)); return; } ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_ON, &status); genericOrderingTest(coll, test, 2); ucol_close(coll); }
static void TestBug11665(void) { // The problem was with the incorrect breaking of Japanese text beginning // with Katakana characters when no prior Japanese or Chinese text had been // encountered. // // Tested here in cintltst, rather than in intltest, because only cintltst // tests have the ability to reset ICU, which is needed to get the bug // to manifest itself. static UChar japaneseText[] = {0x30A2, 0x30EC, 0x30EB, 0x30AE, 0x30FC, 0x6027, 0x7D50, 0x819C, 0x708E}; int32_t boundaries[10] = {0}; UBreakIterator *bi = NULL; int32_t brk; int32_t brkIdx = 0; int32_t totalBreaks = 0; UErrorCode status = U_ZERO_ERROR; ctest_resetICU(); bi = ubrk_open(UBRK_WORD, "en_US", japaneseText, UPRV_LENGTHOF(japaneseText), &status); TEST_ASSERT_SUCCESS(status); if (!bi) { return; } for (brk=ubrk_first(bi); brk != UBRK_DONE; brk=ubrk_next(bi)) { boundaries[brkIdx] = brk; if (++brkIdx >= UPRV_LENGTHOF(boundaries) - 1) { break; } } if (brkIdx <= 2 || brkIdx >= UPRV_LENGTHOF(boundaries)) { log_err("%s:%d too few or many breaks found.\n", __FILE__, __LINE__); } else { totalBreaks = brkIdx; brkIdx = 0; for (brk=ubrk_first(bi); brk != UBRK_DONE; brk=ubrk_next(bi)) { if (brk != boundaries[brkIdx]) { log_err("%s:%d Break #%d differs between first and second iteration.\n", __FILE__, __LINE__, brkIdx); break; } if (++brkIdx >= UPRV_LENGTHOF(boundaries) - 1) { log_err("%s:%d Too many breaks.\n", __FILE__, __LINE__); break; } } if (totalBreaks != brkIdx) { log_err("%s:%d Number of breaks differ between first and second iteration.\n", __FILE__, __LINE__); } } ubrk_close(bi); }
static void TestIncDecFunctions() { UErrorCode status = U_ZERO_ERROR; int32_t t = 1; /* random value to make sure that Inc/dec works */ char *dataDir; /* Save ICU's data dir and tracing functions so that they can be resored after cleanup and reinit. */ dataDir = safeGetICUDataDirectory(); /* Verify that ICU can be cleaned up and reinitialized successfully. * Failure here usually means that some ICU service didn't clean up successfully, * probably because some earlier test accidently left something open. */ ctest_resetICU(); /* Can not set mutex functions if ICU is already initialized */ u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, myDecFunc, &status); TEST_STATUS(status, U_INVALID_STATE_ERROR); /* Clean up ICU */ u_cleanup(); /* Can not set functions with NULL values */ status = U_ZERO_ERROR; u_setAtomicIncDecFunctions(&gIncDecContext, NULL, myDecFunc, &status); TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR); status = U_ZERO_ERROR; u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, NULL, &status); TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR); /* u_setIncDecFunctions() should work with null or non-null context pointer */ status = U_ZERO_ERROR; gExpectedContext = NULL; u_setAtomicIncDecFunctions(NULL, myIncFunc, myDecFunc, &status); TEST_STATUS(status, U_ZERO_ERROR); gExpectedContext = &gIncDecContext; u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, myDecFunc, &status); TEST_STATUS(status, U_ZERO_ERROR); /* After reinitializing ICU, we should not be able to set the inc/dec funcs again. */ status = U_ZERO_ERROR; u_setDataDirectory(dataDir); u_init(&status); TEST_STATUS(status, U_ZERO_ERROR); gExpectedContext = &gIncDecContext; u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, myDecFunc, &status); TEST_STATUS(status, U_INVALID_STATE_ERROR); /* Doing ICU operations should cause our functions to be called */ gIncCount = 0; gDecCount = 0; umtx_atomic_inc(&t); TEST_ASSERT(t == 2); umtx_atomic_dec(&t); TEST_ASSERT(t == 1); TEST_ASSERT(gIncCount > 0); TEST_ASSERT(gDecCount > 0); /* Cleanup should cancel use of our inc/dec functions. */ /* Additional ICU operations should not use them */ ctest_resetICU(); gIncCount = 0; gDecCount = 0; status = U_ZERO_ERROR; u_setDataDirectory(dataDir); u_init(&status); TEST_ASSERT(gIncCount == 0); TEST_ASSERT(gDecCount == 0); status = U_ZERO_ERROR; umtx_atomic_inc(&t); umtx_atomic_dec(&t); TEST_STATUS(status, U_ZERO_ERROR); TEST_ASSERT(gIncCount == 0); TEST_ASSERT(gDecCount == 0); free(dataDir); }
static void TestMutexFunctions() { UErrorCode status = U_ZERO_ERROR; UResourceBundle *rb = NULL; char *icuDataDir; gMutexFailures = 0; /* Save initial ICU state so that it can be restored later. * u_cleanup(), which is called in this test, resets ICU's state. */ icuDataDir = safeGetICUDataDirectory(); /* Verify that ICU can be cleaned up and reinitialized successfully. * Failure here usually means that some ICU service didn't clean up successfully, * probably because some earlier test accidently left something open. */ ctest_resetICU(); /* Can not set mutex functions if ICU is already initialized */ u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status); TEST_STATUS(status, U_INVALID_STATE_ERROR); /* Un-initialize ICU */ u_cleanup(); /* Can not set Mutex functions with NULL values */ status = U_ZERO_ERROR; u_setMutexFunctions(&gContext, NULL, myMutexDestroy, myMutexLock, myMutexUnlock, &status); TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR); status = U_ZERO_ERROR; u_setMutexFunctions(&gContext, myMutexInit, NULL, myMutexLock, myMutexUnlock, &status); TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR); status = U_ZERO_ERROR; u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, NULL, myMutexUnlock, &status); TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR); status = U_ZERO_ERROR; u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, NULL, &status); TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR); /* u_setMutexFunctions() should work with null or non-null context pointer */ status = U_ZERO_ERROR; u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status); TEST_STATUS(status, U_ZERO_ERROR); u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status); TEST_STATUS(status, U_ZERO_ERROR); /* After reinitializing ICU, we should not be able to set the mutex funcs again. */ status = U_ZERO_ERROR; u_setDataDirectory(icuDataDir); u_init(&status); TEST_STATUS(status, U_ZERO_ERROR); u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status); TEST_STATUS(status, U_INVALID_STATE_ERROR); /* Doing ICU operations should cause allocations to come through our test mutexes */ gBlockCount = 0; status = U_ZERO_ERROR; rb = ures_open(NULL, "es", &status); TEST_STATUS(status, U_ZERO_ERROR); TEST_ASSERT(gTotalMutexesInitialized > 0); TEST_ASSERT(gTotalMutexesActive > 0); ures_close(rb); /* Cleanup should destroy all of the mutexes. */ ctest_resetICU(); status = U_ZERO_ERROR; TEST_ASSERT(gTotalMutexesInitialized > 0); TEST_ASSERT(gTotalMutexesActive == 0); /* Additional ICU operations should no longer use our dummy test mutexes */ gTotalMutexesInitialized = 0; gTotalMutexesActive = 0; u_init(&status); TEST_STATUS(status, U_ZERO_ERROR); status = U_ZERO_ERROR; rb = ures_open(NULL, "fr", &status); TEST_STATUS(status, U_ZERO_ERROR); TEST_ASSERT(gTotalMutexesInitialized == 0); TEST_ASSERT(gTotalMutexesActive == 0); ures_close(rb); free(icuDataDir); if(gMutexFailures) { log_info("Note: these failures may be caused by ICU failing to initialize/uninitialize properly.\n"); log_verbose("Check for prior tests which may not have closed all open resources. See the internal function ures_flushCache()\n"); } }
static void TestHeapFunctions() { UErrorCode status = U_ZERO_ERROR; UResourceBundle *rb = NULL; char *icuDataDir; UVersionInfo unicodeVersion = {0,0,0,0}; icuDataDir = safeGetICUDataDirectory(); /* save icu data dir, so we can put it back * after doing u_cleanup(). */ /* Verify that ICU can be cleaned up and reinitialized successfully. * Failure here usually means that some ICU service didn't clean up successfully, * probably because some earlier test accidently left something open. */ ctest_resetICU(); /* Can not set memory functions if ICU is already initialized */ u_setMemoryFunctions(&gContext, myMemAlloc, myMemRealloc, myMemFree, &status); TEST_STATUS(status, U_INVALID_STATE_ERROR); /* Un-initialize ICU */ u_cleanup(); /* Can not set memory functions with NULL values */ status = U_ZERO_ERROR; u_setMemoryFunctions(&gContext, NULL, myMemRealloc, myMemFree, &status); TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR); status = U_ZERO_ERROR; u_setMemoryFunctions(&gContext, myMemAlloc, NULL, myMemFree, &status); TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR); status = U_ZERO_ERROR; u_setMemoryFunctions(&gContext, myMemAlloc, myMemRealloc, NULL, &status); TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR); /* u_setMemoryFunctions() should work with null or non-null context pointer */ status = U_ZERO_ERROR; u_setMemoryFunctions(NULL, myMemAlloc, myMemRealloc, myMemFree, &status); TEST_STATUS(status, U_ZERO_ERROR); u_setMemoryFunctions(&gContext, myMemAlloc, myMemRealloc, myMemFree, &status); TEST_STATUS(status, U_ZERO_ERROR); /* After reinitializing ICU, we should not be able to set the memory funcs again. */ status = U_ZERO_ERROR; u_setDataDirectory(icuDataDir); u_init(&status); TEST_STATUS(status, U_ZERO_ERROR); u_setMemoryFunctions(NULL, myMemAlloc, myMemRealloc, myMemFree, &status); TEST_STATUS(status, U_INVALID_STATE_ERROR); /* Doing ICU operations should cause allocations to come through our test heap */ gBlockCount = 0; status = U_ZERO_ERROR; rb = ures_open(NULL, "es", &status); TEST_STATUS(status, U_ZERO_ERROR); if (gBlockCount == 0) { log_err("Heap functions are not being called from ICU.\n"); } ures_close(rb); /* Cleanup should put the heap back to its default implementation. */ ctest_resetICU(); u_getUnicodeVersion(unicodeVersion); if (unicodeVersion[0] <= 0) { log_err("Properties doesn't reinitialize without u_init.\n"); } status = U_ZERO_ERROR; u_init(&status); TEST_STATUS(status, U_ZERO_ERROR); /* ICU operations should no longer cause allocations to come through our test heap */ gBlockCount = 0; status = U_ZERO_ERROR; rb = ures_open(NULL, "fr", &status); TEST_STATUS(status, U_ZERO_ERROR); if (gBlockCount != 0) { log_err("Heap functions did not reset after u_cleanup.\n"); } ures_close(rb); free(icuDataDir); ctest_resetICU(); }