1 /******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1998-2010, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ********************************************************************/ 6 /* 7 * File test.c 8 * 9 * Modification History: 10 * 11 * Date Name Description 12 * 02/22/2000 Madhu Creation 13 ****************************************************************************** 14 */ 15 16 #include "unicode/utypes.h" 17 #include "unicode/putil.h" 18 #include "unicode/udata.h" 19 #include "unicode/uchar.h" 20 #include "unicode/ucnv.h" 21 #include "unicode/ures.h" 22 #include "unicode/ustring.h" 23 #include "unicode/uclean.h" 24 #include "cmemory.h" 25 #include "cstring.h" 26 #include "filestrm.h" 27 #include "udatamem.h" 28 #include "cintltst.h" 29 #include "ubrkimpl.h" 30 31 #include <sys/types.h> 32 #include <sys/stat.h> 33 #include <fcntl.h> 34 #include <stdlib.h> 35 #include <stdio.h> 36 37 #ifdef U_WINDOWS 38 #include <io.h> 39 #else 40 #include <unistd.h> 41 #endif 42 43 /* includes for TestSwapData() */ 44 #include "udataswp.h" 45 46 /* swapping implementations in common */ 47 #include "uresdata.h" 48 #include "ucnv_io.h" 49 #include "uprops.h" 50 #include "ucase.h" 51 #include "ucol_imp.h" 52 #include "ucol_swp.h" 53 #include "ucnv_bld.h" 54 #include "sprpimpl.h" 55 #include "propname.h" 56 #include "rbbidata.h" 57 58 U_CAPI int32_t U_EXPORT2 59 unorm2_swap(const UDataSwapper *ds, 60 const void *inData, int32_t length, void *outData, 61 UErrorCode *pErrorCode); 62 63 /* other definitions and prototypes */ 64 65 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) 66 67 static void TestUDataOpen(void); 68 static void TestUDataOpenChoiceDemo1(void); 69 static void TestUDataOpenChoiceDemo2(void); 70 static void TestUDataGetInfo(void); 71 static void TestUDataGetMemory(void); 72 static void TestUDataSetAppData(void); 73 static void TestErrorConditions(void); 74 static void TestAppData(void); 75 static void TestICUDataName(void); 76 static void TestSwapData(void); 77 static void PointerTableOfContents(void); 78 static void SetBadCommonData(void); 79 static void TestUDataFileAccess(void); 80 81 82 void addUDataTest(TestNode** root); 83 84 void 85 addUDataTest(TestNode** root) 86 { 87 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION 88 addTest(root, &TestUDataOpen, "udatatst/TestUDataOpen" ); 89 addTest(root, &TestUDataOpenChoiceDemo1, "udatatst/TestUDataOpenChoiceDemo1"); 90 addTest(root, &TestUDataOpenChoiceDemo2, "udatatst/TestUDataOpenChoiceDemo2"); 91 addTest(root, &TestUDataGetInfo, "udatatst/TestUDataGetInfo" ); 92 addTest(root, &TestUDataGetMemory, "udatatst/TestUDataGetMemory" ); 93 addTest(root, &TestErrorConditions, "udatatst/TestErrorConditions"); 94 addTest(root, &TestAppData, "udatatst/TestAppData" ); 95 addTest(root, &TestSwapData, "udatatst/TestSwapData" ); 96 #endif 97 addTest(root, &TestUDataSetAppData, "udatatst/TestUDataSetAppData" ); 98 addTest(root, &TestICUDataName, "udatatst/TestICUDataName" ); 99 addTest(root, &PointerTableOfContents, "udatatst/PointerTableOfContents" ); 100 addTest(root, &SetBadCommonData, "udatatst/SetBadCommonData" ); 101 addTest(root, &TestUDataFileAccess, "udatatst/TestUDataFileAccess" ); 102 } 103 104 #if 0 105 static void lots_of_mallocs() 106 { 107 int q; 108 for(q=1;q<100;q++) 109 { 110 free(malloc(q)); 111 malloc(q*2); 112 } 113 114 } 115 #endif 116 117 static void TestUDataOpen(){ 118 UDataMemory *result; 119 UErrorCode status=U_ZERO_ERROR; 120 const char* memMap[][2]={ 121 {"root", "res"}, 122 {"pnames", "icu"}, 123 {"cnvalias", "icu"}, 124 {"unames", "icu"}, 125 {"ibm-37_P100-1995", "cnv"} 126 }; 127 const char* name = "test"; 128 const char* type = "icu"; 129 const char dirSepString[] = {U_FILE_SEP_CHAR, 0}; 130 const char pathSepString[] = {U_PATH_SEP_CHAR, 0}; 131 132 133 char* path=(char*)malloc(sizeof(char) * (strlen(ctest_dataOutDir()) 134 + strlen(U_ICUDATA_NAME) 135 + strlen("/build")+1 ) ); 136 137 char *icuDataFilePath = 0; 138 struct stat stat_buf; 139 140 const char* testPath=loadTestData(&status); 141 if(U_FAILURE(status)) { 142 log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status)); 143 free(path); 144 return; 145 } 146 147 /* lots_of_mallocs(); */ 148 149 strcat(strcpy(path, ctest_dataOutDir()), U_ICUDATA_NAME); 150 151 log_verbose("Testing udata_open()\n"); 152 result=udata_open(testPath, type, name, &status); 153 if(U_FAILURE(status)){ 154 log_data_err("FAIL: udata_open() failed for path = %s, name=%s, type=%s, \n errorcode=%s\n", testPath, name, type, myErrorName(status)); 155 } else { 156 log_verbose("PASS: udata_open worked\n"); 157 udata_close(result); 158 } 159 160 /* If the ICU system common data file is present in this confiugration, 161 * verify that udata_open can explicitly fetch items from it. 162 * If packaging mode == dll, the file may not exist. So, if the file is 163 * missing, skip this test without error. 164 */ 165 icuDataFilePath = (char *)malloc(strlen(path) + 10); 166 strcpy(icuDataFilePath, path); 167 strcat(icuDataFilePath, ".dat"); 168 /* lots_of_mallocs(); */ 169 if (stat(icuDataFilePath, &stat_buf) == 0) 170 { 171 int i; 172 log_verbose("Testing udata_open() on %s\n", icuDataFilePath); 173 for(i=0; i<sizeof(memMap)/sizeof(memMap[0]); i++){ 174 /* lots_of_mallocs(); */ 175 status=U_ZERO_ERROR; 176 result=udata_open(path, memMap[i][1], memMap[i][0], &status); 177 if(U_FAILURE(status)) { 178 log_data_err("FAIL: udata_open() failed for path = %s, name=%s, type=%s, \n errorcode=%s\n", path, memMap[i][0], memMap[i][1], myErrorName(status)); 179 } else { 180 log_verbose("PASS: udata_open worked for path = %s, name=%s, type=%s\n", path, memMap[i][0], memMap[i][1]); 181 udata_close(result); 182 } 183 } 184 } 185 else 186 { 187 /* lots_of_mallocs(); */ 188 log_verbose("Skipping tests of udata_open() on %s. File not present in this configuration.\n", 189 icuDataFilePath); 190 } 191 free(icuDataFilePath); 192 icuDataFilePath = NULL; 193 /* lots_of_mallocs(); */ 194 195 /* If the ICU individual files used to build the ICU system common data are 196 * present in this configuration, 197 * verify that udata_open can explicitly open them. 198 * These data files are present in the ICU data/build directory after a build 199 * completes. Tests are most commonly run with the data directory pointing 200 * back into this directory structure, but this is not required. Soooo, if 201 * the files are missing, skip this test without error. 202 */ 203 /* lots_of_mallocs(); */ 204 icuDataFilePath = (char *)malloc(strlen(ctest_dataOutDir()) + 50); 205 strcpy(icuDataFilePath, ctest_dataOutDir()); 206 strcat(icuDataFilePath, "build"); 207 strcat(icuDataFilePath, dirSepString); 208 strcat(icuDataFilePath, U_ICUDATA_NAME); 209 strcat(icuDataFilePath, "_"); 210 strcat(icuDataFilePath, "cnvalias.icu"); 211 212 /* lots_of_mallocs(); */ 213 if (stat(icuDataFilePath, &stat_buf) == 0) 214 { 215 int i; 216 log_verbose("%s exists, so..\n", icuDataFilePath); 217 strcpy(icuDataFilePath, ctest_dataOutDir()); 218 strcat(icuDataFilePath, "build"); 219 strcat(icuDataFilePath, dirSepString); 220 strcat(icuDataFilePath, U_ICUDATA_NAME); 221 log_verbose("Testing udata_open() on %s\n", icuDataFilePath); 222 for(i=0; i<sizeof(memMap)/sizeof(memMap[0]); i++){ 223 status=U_ZERO_ERROR; 224 result=udata_open(icuDataFilePath, memMap[i][1], memMap[i][0], &status); 225 if(U_FAILURE(status)) { 226 log_data_err("FAIL: udata_open() failed for path = %s, name=%s, type=%s, \n errorcode=%s\n", icuDataFilePath, memMap[i][0], memMap[i][1], myErrorName(status)); 227 } else { 228 log_verbose("PASS: udata_open worked for path = %s, name=%s, type=%s\n", icuDataFilePath, memMap[i][0], memMap[i][1]); 229 udata_close(result); 230 } 231 } 232 } 233 else 234 { 235 log_verbose("Skipping tests of udata_open() on %s. File not present in this configuration.\n", 236 icuDataFilePath); 237 } 238 239 free(icuDataFilePath); 240 icuDataFilePath = NULL; 241 242 /* 243 * Test fallback file names for open of separate data files. 244 * With these params to udata_open: 245 * path = wherever/testdata 246 * type = typ 247 * name = nam 248 * these files will be tried first: 249 * wherever/testudata_nam.typ 250 * testudata_nam.typ 251 * A test data file named testudata_nam.typ exists for the purpose of testing this. 252 */ 253 log_verbose("Testing udata_open, with base_name.type style fallback to individual file.\n"); 254 255 status = U_ZERO_ERROR; 256 result = udata_open( testPath, "typ", "nam", &status); 257 if (status != U_ZERO_ERROR) { 258 log_data_err("FAIL: udata_open( \"%s\", \"typ\", \"nam\") returned status %s\n", testPath, u_errorName(status)); 259 } 260 udata_close(result); 261 free(icuDataFilePath); 262 263 264 /* This type of path is deprecated */ 265 /* 266 * Another fallback test. Paths ending with a trailing directory separator 267 * take a slightly different code path, with the "base name" from the path 268 * being empty in the internal udata_open logic. 269 */ 270 271 /* log_verbose("Testing udata_open, with path containing a trailing directory separator.\n"); */ 272 /* icuDataFilePath = (char *)malloc(strlen(u_getDataDirectory()) + 50); */ 273 /* strcpy(icuDataFilePath, testPath); */ 274 /* status = U_ZERO_ERROR; */ 275 /* result = udata_open( icuDataFilePath, "cnv", "test1", &status); */ 276 /* if (status != U_ZERO_ERROR) { */ 277 /* log_err("FAIL: udata_open( \"%s\", \"cnv\", \"test1\") returned status %s\n", icuDataFilePath, u_errorName(status)); */ 278 /* } */ 279 /* udata_close(result); */ 280 /* free(icuDataFilePath); */ 281 282 283 log_verbose("Testing udata_open() with a non existing binary file\n"); 284 result=udata_open("testdata", "tst", "nonexist", &status); 285 if(status==U_FILE_ACCESS_ERROR){ 286 log_verbose("Opening udata_open with non-existing file handled correctly.\n"); 287 status=U_ZERO_ERROR; 288 } else { 289 log_err("calling udata_open with non-existing file [testdata | nonexist.tst] not handled correctly\n. Expected: U_FILE_ACCESS_ERROR, Got: %s\n", myErrorName(status)); 290 if(U_SUCCESS(status)) { 291 udata_close(result); 292 } 293 } 294 295 if(result != NULL){ 296 log_err("calling udata_open with non-existing file didn't return a null value\n"); 297 } else { 298 log_verbose("calling udat_open with non-existing file returned null as expected\n"); 299 } 300 301 /* 302 * Try opening data with absurdly long path and name, to trigger buffer size 303 * overflow handling code. 304 */ 305 { 306 char longTestPath[1024]; /* Implementation goes to heap at length of 128. */ 307 char longName[1024]; 308 309 /* Try a very long nonexistent directory path. 310 * udata_open should still succeed. Opening with the path will fail, 311 * then fall back to skipping the directory portion of the path. 312 */ 313 log_verbose("Testing udata_open() with really long names\n"); 314 longTestPath[0] = 0; 315 strcat(longTestPath, "bogus_directory_name"); 316 while (strlen(longTestPath) < 500) { 317 strcat(longTestPath, dirSepString); 318 strcat(longTestPath, "bogus_directory_name"); 319 } 320 strcat(longTestPath, pathSepString); 321 strcat(longTestPath, testPath); 322 result=udata_open(longTestPath, type, name, &status); 323 if(U_FAILURE(status)){ 324 log_data_err("FAIL: udata_open() failed for path = %s\n name=%s, type=%s, \n errorcode=%s\n", 325 longTestPath, name, type, myErrorName(status)); 326 } else { 327 log_verbose("PASS: udata_open worked\n"); 328 udata_close(result); 329 } 330 331 /* Try a very long name. Won't open, but shouldn't blow up. 332 */ 333 longName[0] = 0; 334 while (strlen(longName) < 500) { 335 strcat(longName, name); 336 strcat(longName, "_"); 337 } 338 strcat(longName, dirSepString); 339 strcat(longName, name); 340 341 result=udata_open(longTestPath, type, longName, &status); 342 if (status != U_FILE_ACCESS_ERROR) { 343 log_data_err("FAIL: udata_open() failed for path = %s\n name=%s, type=%s, \n errorcode=%s\n", 344 longTestPath, longName, type, myErrorName(status)); 345 } 346 udata_close(result); 347 } 348 349 free(path); 350 } 351 352 typedef struct { 353 uint16_t headerSize; 354 uint8_t magic1, magic2; 355 UDataInfo info; 356 char padding[8]; 357 uint32_t count, reserved; 358 /* 359 const struct { 360 const char *const name; 361 const void *const data; 362 } toc[1]; 363 */ 364 int32_t fakeNameAndData[4]; 365 } ICU_COMMON_Data_Header; 366 367 static const ICU_COMMON_Data_Header gEmptyHeader = { 368 32, /* headerSize */ 369 0xda, /* magic1, (see struct MappedData in udata.c) */ 370 0x27, /* magic2 */ 371 { /*UDataInfo */ 372 sizeof(UDataInfo), /* size */ 373 0, /* reserved */ 374 375 #if U_IS_BIG_ENDIAN 376 1, 377 #else 378 0, 379 #endif 380 381 U_CHARSET_FAMILY, 382 sizeof(UChar), 383 0, /* reserved */ 384 { /* data format identifier */ 385 0x43, 0x6d, 0x6e, 0x44}, /* "CmnD" */ 386 {1, 0, 0, 0}, /* format version major, minor, milli, micro */ 387 {0, 0, 0, 0} /* dataVersion */ 388 }, 389 {0,0,0,0,0,0,0,0}, /* Padding[8] */ 390 0, /* count */ 391 0, /* Reserved */ 392 { /* TOC structure */ 393 /* { */ 394 0 , 0 , 0, 0 /* name and data entries. Count says there are none, */ 395 /* but put one in just in case. */ 396 /* } */ 397 } 398 }; 399 400 401 static void TestUDataSetAppData(){ 402 /* UDataMemory *dataItem;*/ 403 404 UErrorCode status=U_ZERO_ERROR; 405 406 /* 407 * First we try some monkey business and try to do bad things. 408 */ 409 410 status=U_ZERO_ERROR; 411 udata_setAppData("appData1", NULL, &status); 412 if (status != U_ILLEGAL_ARGUMENT_ERROR) { 413 log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData1\", NULL, status) should have failed." 414 " It returned status of %s\n", u_errorName(status)); 415 return; 416 } 417 /* The following call should fail. 418 If the following works with a bad UErrorCode, then later calls to appData1 should fail. */ 419 udata_setAppData("appData1", &gEmptyHeader, &status); 420 421 /* 422 * Got testdata.dat into memory, now we try setAppData using the memory image. 423 */ 424 425 status=U_ZERO_ERROR; 426 udata_setAppData("appData1", &gEmptyHeader, &status); 427 if (status != U_ZERO_ERROR) { 428 log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData1\", fileBuf, status) " 429 " returned status of %s\n", u_errorName(status)); 430 return; 431 } 432 433 udata_setAppData("appData2", &gEmptyHeader, &status); 434 if (status != U_ZERO_ERROR) { 435 log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData2\", fileBuf, status) " 436 " returned status of %s\n", u_errorName(status)); 437 return; 438 } 439 440 /* If we try to setAppData with the same name a second time, we should get a 441 * a using default warning. 442 */ 443 udata_setAppData("appData2", &gEmptyHeader, &status); 444 if (status != U_USING_DEFAULT_WARNING) { 445 log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData2\", fileBuf, status) " 446 " returned status of %s, expected U_USING_DEFAULT_WARNING.\n", u_errorName(status)); 447 } 448 449 450 /** It is no longer correct to use udata_setAppData to change the 451 package of a contained item. 452 453 dataItem = udata_open("appData1", "res", "te_IN", &status); **/ 454 } 455 456 static char *safeGetICUDataDirectory() { 457 const char *dataDir = u_getDataDirectory(); /* Returned string vanashes with u_cleanup */ 458 char *retStr = NULL; 459 if (dataDir != NULL) { 460 retStr = (char *)malloc(strlen(dataDir)+1); 461 strcpy(retStr, dataDir); 462 } 463 return retStr; 464 } 465 466 static void TestUDataFileAccess(){ 467 UErrorCode status; 468 char *icuDataDir; 469 icuDataDir = safeGetICUDataDirectory(); /* save icu data dir, so we can put it back 470 * after doing u_cleanup(). */ 471 472 /** UDATA_NO_FILES, ICU does not access the file system for data loading. */ 473 status=U_ZERO_ERROR; 474 u_cleanup(); 475 udata_setFileAccess(UDATA_NO_FILES,&status); 476 u_init(&status); 477 if(U_FAILURE(status) && *icuDataDir == 0){ 478 log_data_err("udata_setFileAccess(UDATA_NO_FILES) failed with ICU_DATA=\"\" err=%s\n", u_errorName(status)); 479 } 480 481 /** UDATA_ONLY_PACKAGES, ICU only loads data from packages, not from single files. */ 482 status=U_ZERO_ERROR; 483 u_cleanup(); 484 udata_setFileAccess(UDATA_ONLY_PACKAGES,&status); 485 u_init(&status); 486 487 /** UDATA_PACKAGES_FIRST, ICU loads data from packages first, and only from single files 488 if the data cannot be found in a package. */ 489 status=U_ZERO_ERROR; 490 u_cleanup(); 491 udata_setFileAccess(UDATA_PACKAGES_FIRST,&status); 492 u_init(&status); 493 494 /** UDATA_FILES_FIRST, ICU looks for data in single files first, then in packages. (default) */ 495 status=U_ZERO_ERROR; 496 u_cleanup(); 497 udata_setFileAccess(UDATA_FILES_FIRST,&status); 498 u_init(&status); 499 500 /** An alias for the default access mode. */ 501 status=U_ZERO_ERROR; 502 u_cleanup(); 503 udata_setFileAccess(UDATA_DEFAULT_ACCESS,&status); 504 u_setDataDirectory(icuDataDir); 505 u_init(&status); 506 if(U_FAILURE(status)){ 507 log_err_status(status, "%s\n", u_errorName(status)); 508 } 509 free(icuDataDir); 510 ctest_resetICU(); 511 } 512 513 514 static UBool U_CALLCONV 515 isAcceptable1(void *context, 516 const char *type, const char *name, 517 const UDataInfo *pInfo) { 518 519 if( pInfo->size>=20 && 520 pInfo->isBigEndian==U_IS_BIG_ENDIAN && 521 pInfo->charsetFamily==U_CHARSET_FAMILY && 522 pInfo->dataFormat[0]==0x43 && /* dataFormat="CvAl" */ 523 pInfo->dataFormat[1]==0x76 && 524 pInfo->dataFormat[2]==0x41 && 525 pInfo->dataFormat[3]==0x6c && 526 pInfo->formatVersion[0]==3 ) 527 { 528 log_verbose("The data from \"%s.%s\" IS acceptable using the verifing function isAcceptable1()\n", name, type); 529 return TRUE; 530 } else { 531 log_verbose("The data from \"%s.%s\" IS NOT acceptable using the verifing function isAcceptable1():-\n" 532 "\tsize = %d\n" 533 "\tisBigEndian = %d\n" 534 "\tcharsetFamily = %d\n" 535 "\tformatVersion[0] = %d\n" 536 "\tdataVersion[0] = %d\n" 537 "\tdataFormat = %c%c%c%c\n", 538 name, type, pInfo->size, pInfo->isBigEndian, pInfo->charsetFamily, pInfo->formatVersion[0], 539 pInfo->dataVersion[0], pInfo->dataFormat[0], pInfo->dataFormat[1], pInfo->dataFormat[2], 540 pInfo->dataFormat[3]); 541 log_verbose("Call another verifing function to accept the data\n"); 542 return FALSE; 543 } 544 } 545 546 static UBool U_CALLCONV 547 isAcceptable2(void *context, 548 const char *type, const char *name, 549 const UDataInfo *pInfo){ 550 UVersionInfo unicodeVersion; 551 552 u_getUnicodeVersion(unicodeVersion); 553 554 if( pInfo->size>=20 && 555 pInfo->isBigEndian==U_IS_BIG_ENDIAN && 556 pInfo->charsetFamily==U_CHARSET_FAMILY && 557 pInfo->dataFormat[0]==0x75 && /* dataFormat="unam" */ 558 pInfo->dataFormat[1]==0x6e && 559 pInfo->dataFormat[2]==0x61 && 560 pInfo->dataFormat[3]==0x6d && 561 pInfo->formatVersion[0]==1 && 562 pInfo->dataVersion[0]==unicodeVersion[0] ) 563 { 564 log_verbose("The data from \"%s.%s\" IS acceptable using the verifing function isAcceptable2()\n", name, type); 565 return TRUE; 566 } else { 567 log_verbose("The data from \"%s.%s\" IS NOT acceptable using the verifing function isAcceptable2()\n", name, type); 568 569 return FALSE; 570 } 571 572 573 } 574 static UBool U_CALLCONV 575 isAcceptable3(void *context, 576 const char *type, const char *name, 577 const UDataInfo *pInfo){ 578 579 if( pInfo->size>=20 && 580 pInfo->isBigEndian==U_IS_BIG_ENDIAN && 581 pInfo->charsetFamily==U_CHARSET_FAMILY && 582 pInfo->dataFormat[0]==0x54 && /* dataFormat="test" */ 583 pInfo->dataFormat[1]==0x65 && 584 pInfo->dataFormat[2]==0x73 && 585 pInfo->dataFormat[3]==0x74 && 586 pInfo->formatVersion[0]==1 && 587 pInfo->dataVersion[0]==1 ) { 588 log_verbose("The data from \"%s.%s\" IS acceptable using the verifing function isAcceptable3()\n", name, type); 589 590 return TRUE; 591 } else { 592 log_verbose("The data from \"%s.%s\" IS NOT acceptable using the verifing function isAcceptable3()\n", name, type); 593 return FALSE; 594 } 595 596 597 } 598 599 static void TestUDataOpenChoiceDemo1() { 600 UDataMemory *result; 601 UErrorCode status=U_ZERO_ERROR; 602 603 const char* name[]={ 604 "cnvalias", 605 "unames", 606 "test", 607 "nam" 608 }; 609 const char* type="icu"; 610 const char* testPath="testdata"; 611 const char* fullTestDataPath = loadTestData(&status); 612 if(U_FAILURE(status)) { 613 log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status)); 614 return; 615 } 616 617 result=udata_openChoice(NULL, "icu", name[0], isAcceptable1, NULL, &status); 618 if(U_FAILURE(status)){ 619 log_data_err("FAIL: udata_openChoice() failed name=%s, type=%s, \n errorcode=%s\n", name[0], type, myErrorName(status)); 620 } else { 621 log_verbose("PASS: udata_openChoice worked\n"); 622 udata_close(result); 623 } 624 625 status=U_ZERO_ERROR; 626 result=udata_openChoice(NULL, type, name[1], isAcceptable1, NULL, &status); 627 if(U_FAILURE(status)){ 628 status=U_ZERO_ERROR; 629 result=udata_openChoice(NULL, type, name[1], isAcceptable2, NULL, &status); 630 if(U_FAILURE(status)){ 631 log_data_err("FAIL: udata_openChoice() failed name=%s, type=%s, \n errorcode=%s\n", name[1], type, myErrorName(status)); 632 } 633 } 634 else { 635 log_err("FAIL: udata_openChoice() unexpectedly passed. name=%s, type=%s, \n errorcode=%s\n", name[1], type, myErrorName(status)); 636 } 637 638 if(U_SUCCESS(status)){ 639 udata_close(result); 640 } 641 642 status=U_ZERO_ERROR; 643 result=udata_openChoice(testPath, type, name[2], isAcceptable1, NULL, &status); 644 if(U_FAILURE(status)){ 645 status=U_ZERO_ERROR; 646 result=udata_openChoice(testPath, type, name[2], isAcceptable3, NULL, &status); 647 if(U_FAILURE(status)){ 648 log_data_err("FAIL: udata_openChoice() failed path=%s name=%s, type=%s, \n errorcode=%s\n", testPath, name[2], type, myErrorName(status)); 649 } 650 } 651 else { 652 log_err("FAIL: udata_openChoice() unexpectedly passed. name=%s, type=%s, \n errorcode=%s\n", name[2], type, myErrorName(status)); 653 } 654 655 if(U_SUCCESS(status)){ 656 udata_close(result); 657 } 658 659 status=U_ZERO_ERROR; 660 type="typ"; 661 result=udata_openChoice(fullTestDataPath, type, name[3], isAcceptable1, NULL, &status); 662 if(status != U_INVALID_FORMAT_ERROR){ 663 log_err("FAIL: udata_openChoice() did not fail as expected. name=%s, type=%s, \n errorcode=%s\n", name[3], type, myErrorName(status)); 664 } 665 666 status=U_USELESS_COLLATOR_ERROR; 667 result=udata_openChoice(fullTestDataPath, type, name[3], isAcceptable1, NULL, &status); 668 if(status != U_USELESS_COLLATOR_ERROR){ 669 log_err("FAIL: udata_openChoice() did not fail as expected. name=%s, type=%s, \n errorcode=%s\n", name[3], type, myErrorName(status)); 670 } 671 } 672 673 static UBool U_CALLCONV 674 isAcceptable(void *context, 675 const char *type, const char *name, 676 const UDataInfo *pInfo){ 677 if( pInfo->size>=20 && 678 pInfo->isBigEndian==U_IS_BIG_ENDIAN && 679 pInfo->charsetFamily==U_CHARSET_FAMILY && 680 pInfo->dataFormat[0]==0x54 && /* dataFormat="test" */ 681 pInfo->dataFormat[1]==0x65 && 682 pInfo->dataFormat[2]==0x73 && 683 pInfo->dataFormat[3]==0x74 && 684 pInfo->formatVersion[0]==1 && 685 pInfo->dataVersion[0]==1 && 686 *((int*)context) == 2 ) { 687 log_verbose("The data from\"%s.%s\" IS acceptable using the verifing function isAcceptable()\n", name, type); 688 689 return TRUE; 690 } else { 691 log_verbose("The data from \"%s.%s\" IS NOT acceptable using the verifing function isAcceptable()\n", name, type); 692 return FALSE; 693 } 694 } 695 696 697 /* This test checks to see if the isAcceptable function is being called correctly. */ 698 699 static void TestUDataOpenChoiceDemo2() { 700 UDataMemory *result; 701 UErrorCode status=U_ZERO_ERROR; 702 int i; 703 int p=2; 704 705 const char* name="test"; 706 const char* type="icu"; 707 const char* path = loadTestData(&status); 708 if(U_FAILURE(status)) { 709 log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status)); 710 return; 711 } 712 713 result=udata_openChoice(path, type, name, isAcceptable, &p, &status); 714 if(U_FAILURE(status)){ 715 log_data_err("failed to load data at p=%s t=%s n=%s, isAcceptable", path, type, name); 716 } 717 if(U_SUCCESS(status) ) { 718 udata_close(result); 719 } 720 721 p=0; 722 for(i=0;i<2; i++){ 723 result=udata_openChoice(path, type, name, isAcceptable, &p, &status); 724 if(p<2) { 725 if(U_FAILURE(status) && status==U_INVALID_FORMAT_ERROR){ 726 log_verbose("Loads the data but rejects it as expected %s\n", myErrorName(status)); 727 status=U_ZERO_ERROR; 728 p++; 729 } 730 else { 731 log_data_err("FAIL: failed to either load the data or to reject the loaded data. ERROR=%s\n", myErrorName(status) ); 732 } 733 } 734 else if(p == 2) { 735 if(U_FAILURE(status)) { 736 log_data_err("FAIL: failed to load the data and accept it. ERROR=%s\n", myErrorName(status) ); 737 } 738 else { 739 log_verbose("Loads the data and accepts it for p==2 as expected\n"); 740 udata_close(result); 741 } 742 } 743 } 744 } 745 746 747 static void TestUDataGetInfo() { 748 749 UDataMemory *result; 750 /* UDataInfo cf. udata.h */ 751 static UDataInfo dataInfo={ 752 30, /*sizeof(UDataInfo),*/ 753 0, 754 755 U_IS_BIG_ENDIAN, 756 U_CHARSET_FAMILY, 757 sizeof(UChar), 758 0, 759 760 {0x54, 0x65, 0x73, 0x74}, /* dataFormat="Test" */ 761 {9, 0, 0, 0}, /* formatVersion */ 762 {4, 0, 0, 0} /* dataVersion */ 763 }; 764 UErrorCode status=U_ZERO_ERROR; 765 const char* name="cnvalias"; 766 const char* name2="test"; 767 const char* type="icu"; 768 769 const char* testPath=loadTestData(&status); 770 if(U_FAILURE(status)) { 771 log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status)); 772 return; 773 } 774 775 log_verbose("Testing udata_getInfo() for cnvalias.icu\n"); 776 result=udata_open(NULL, "icu", name, &status); 777 if(U_FAILURE(status)){ 778 log_data_err("FAIL: udata_open() failed for path = NULL, name=%s, type=%s, \n errorcode=%s\n", name, type, myErrorName(status)); 779 return; 780 } 781 udata_getInfo(result, &dataInfo); 782 if(dataInfo.size==20 && dataInfo.size!=30 && 783 dataInfo.isBigEndian==U_IS_BIG_ENDIAN && 784 dataInfo.charsetFamily==U_CHARSET_FAMILY && 785 dataInfo.dataFormat[0]==0x43 && dataInfo.dataFormat[0]!=0x54 && /* dataFormat="CvAl" and not "Test". The values are set for cnvalias.dat*/ 786 dataInfo.dataFormat[1]==0x76 && dataInfo.dataFormat[1]!=0x65 && 787 dataInfo.dataFormat[2]==0x41 && dataInfo.dataFormat[2]!=0x73 && 788 dataInfo.dataFormat[3]==0x6c && dataInfo.dataFormat[3]!=0x74 && 789 dataInfo.formatVersion[0]!=9 && /*formatVersion is also set to the one for cnvalias*/ 790 dataInfo.dataVersion[0]!=4 && /*dataVersion*/ 791 dataInfo.dataVersion[1]!=0 ){ 792 log_verbose("PASS: udata_getInfo() filled in the right values\n"); 793 } else { 794 log_err("FAIL: udata_getInfo() filled in the wrong values\n"); 795 } 796 udata_close(result); 797 798 799 log_verbose("Testing udata_getInfo() for test.icu\n"); 800 result=udata_open(testPath, type, name2, &status); 801 if(U_FAILURE(status)) { 802 log_data_err("FAIL: udata_open() failed for path=%s name2=%s, type=%s, \n errorcode=%s\n", testPath, name2, type, myErrorName(status)); 803 return; 804 } 805 udata_getInfo(result, &dataInfo); 806 if(dataInfo.size==20 && 807 dataInfo.isBigEndian==U_IS_BIG_ENDIAN && 808 dataInfo.charsetFamily==U_CHARSET_FAMILY && 809 dataInfo.dataFormat[0]==0x54 && /* dataFormat="Test". The values are set for test.dat*/ 810 dataInfo.dataFormat[1]==0x65 && 811 dataInfo.dataFormat[2]==0x73 && 812 dataInfo.dataFormat[3]==0x74 && 813 dataInfo.formatVersion[0]==1 && /*formatVersion is also set to the one for test*/ 814 dataInfo.dataVersion[0]==1 && /*dataVersion*/ 815 dataInfo.dataVersion[1]==0 ) 816 { 817 log_verbose("PASS: udata_getInfo() filled in the right values\n"); 818 } else { 819 log_err("FAIL: udata_getInfo() filled in the wrong values\n"); 820 } 821 udata_close(result); 822 } 823 824 static void TestUDataGetMemory() { 825 826 UDataMemory *result; 827 const int32_t *table=NULL; 828 uint16_t* intValue=0; 829 UErrorCode status=U_ZERO_ERROR; 830 const char* name="cnvalias"; 831 const char* type; 832 833 const char* name2="test"; 834 835 const char* testPath = loadTestData(&status); 836 if(U_FAILURE(status)) { 837 log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status)); 838 return; 839 } 840 841 type="icu"; 842 log_verbose("Testing udata_getMemory() for \"cnvalias.icu\"\n"); 843 result=udata_openChoice(NULL, type, name, isAcceptable1, NULL, &status); 844 if(U_FAILURE(status)){ 845 log_data_err("FAIL: udata_openChoice() failed for name=%s, type=%s, \n errorcode=%s\n", name, type, myErrorName(status)); 846 return; 847 } 848 table=(const int32_t *)udata_getMemory(result); 849 850 /* The alias table may list more converters than what's actually available now. [grhoten] */ 851 if(ucnv_countAvailable() > table[1]) /*???*/ 852 log_err("FAIL: udata_getMemory() failed ucnv_countAvailable returned = %d, expected = %d\n", ucnv_countAvailable(), table[1+2*(*table)]); 853 854 udata_close(result); 855 856 type="icu"; 857 log_verbose("Testing udata_getMemory for \"test.icu\"()\n"); 858 result=udata_openChoice(testPath, type, name2, isAcceptable3, NULL, &status); 859 if(U_FAILURE(status)){ 860 log_data_err("FAIL: udata_openChoice() failed for path=%s name=%s, type=%s, \n errorcode=%s\n", testPath, name2, type, myErrorName(status)); 861 return; 862 } 863 intValue=(uint16_t *)udata_getMemory(result); 864 /*printf("%d ..... %s", *(intValue), intValue+1));*/ 865 if( *intValue != 2000 || strcmp((char*)(intValue+1), "YEAR") != 0 ) 866 log_err("FAIL: udata_getMemory() failed: intValue :- Expected:2000 Got:%d \n\tstringValue:- Expected:YEAR Got:%s\n", *intValue, (intValue+1)); 867 868 udata_close(result); 869 870 } 871 872 static void TestErrorConditions(){ 873 874 UDataMemory *result=NULL; 875 UErrorCode status=U_ZERO_ERROR; 876 uint16_t* intValue=0; 877 static UDataInfo dataInfo={ 878 30, /*sizeof(UDataInfo),*/ 879 0, 880 881 U_IS_BIG_ENDIAN, 882 U_CHARSET_FAMILY, 883 sizeof(UChar), 884 0, 885 886 {0x54, 0x65, 0x73, 0x74}, /* dataFormat="Test" */ 887 {9, 0, 0, 0}, /* formatVersion */ 888 {4, 0, 0, 0} /* dataVersion */ 889 }; 890 891 const char* name = "test"; 892 const char* type="icu"; 893 894 const char *testPath = loadTestData(&status); 895 if(U_FAILURE(status)) { 896 log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status)); 897 return; 898 } 899 900 status = U_ILLEGAL_ARGUMENT_ERROR; 901 /*Try udata_open with status != U_ZERO_ERROR*/ 902 log_verbose("Testing udata_open() with status != U_ZERO_ERROR\n"); 903 result=udata_open(testPath, type, name, &status); 904 if(result != NULL){ 905 log_data_err("FAIL: udata_open() is supposed to fail for path = %s, name=%s, type=%s, \n errorcode !=U_ZERO_ERROR\n", testPath, name, type); 906 udata_close(result); 907 908 } else { 909 log_verbose("PASS: udata_open with errorCode != U_ZERO_ERROR failed as expected\n"); 910 } 911 912 /*Try udata_open with data name=NULL*/ 913 log_verbose("Testing udata_open() with data name=NULL\n"); 914 status=U_ZERO_ERROR; 915 result=udata_open(testPath, type, NULL, &status); 916 if(U_FAILURE(status)){ 917 if(status != U_ILLEGAL_ARGUMENT_ERROR || result != NULL){ 918 log_err("FAIL: udata_open() with name=NULL should return NULL and errocode U_ILLEGAL_ARGUMENT_ERROR, GOT: errorcode=%s\n", myErrorName(status)); 919 }else{ 920 log_verbose("PASS: udata_open with name=NULL failed as expected and errorcode = %s as expected\n", myErrorName(status)); 921 } 922 }else{ 923 log_err("FAIL: udata_open() with data name=NULL is supposed to fail for path = %s, name=NULL type=%s errorcode=U_ZERO_ERROR \n", testPath, type); 924 udata_close(result); 925 } 926 927 928 /*Try udata_openChoice with status != U_ZERO_ERROR*/ 929 log_verbose("Testing udata_openChoice() with status != U_ZERO_ERROR\n"); 930 status=U_ILLEGAL_ARGUMENT_ERROR; 931 result=udata_openChoice(testPath, type, name, isAcceptable3, NULL, &status); 932 if(result != NULL){ 933 log_err("FAIL: udata_openChoice() is supposed to fail for path = %s, name=%s, type=%s, \n errorcode != U_ZERO_ERROR\n", testPath, name, type); 934 udata_close(result); 935 } else { 936 log_verbose("PASS: udata_openChoice() with errorCode != U_ZERO_ERROR failed as expected\n"); 937 } 938 939 /*Try udata_open with data name=NULL*/ 940 log_verbose("Testing udata_openChoice() with data name=NULL\n"); 941 status=U_ZERO_ERROR; 942 result=udata_openChoice(testPath, type, NULL, isAcceptable3, NULL, &status); 943 if(U_FAILURE(status)){ 944 if(status != U_ILLEGAL_ARGUMENT_ERROR || result != NULL){ 945 log_err("FAIL: udata_openChoice() with name=NULL should return NULL and errocode U_ILLEGAL_ARGUMENT_ERROR, GOT: errorcode=%s\n", myErrorName(status)); 946 }else{ 947 log_verbose("PASS: udata_openChoice with name=NULL failed as expected and errorcode = %s as expected\n", myErrorName(status)); 948 } 949 }else{ 950 log_err("FAIL: udata_openChoice() with data name=NULL is supposed to fail for path = %s, name=NULL type=%s errorcode=U_ZERO_ERROR \n", testPath, type); 951 udata_close(result); 952 } 953 954 /*Try udata_getMemory with UDataMemory=NULL*/ 955 log_verbose("Testing udata_getMemory with UDataMemory=NULL\n"); 956 intValue=(uint16_t*)udata_getMemory(NULL); 957 if(intValue != NULL){ 958 log_err("FAIL: udata_getMemory with UDataMemory = NULL is supposed to fail\n"); 959 } 960 961 /*Try udata_getInfo with UDataMemory=NULL*/ 962 status=U_ZERO_ERROR; 963 udata_getInfo(NULL, &dataInfo); 964 if(dataInfo.size != 0){ 965 log_err("FAIL : udata_getInfo with UDataMemory = NULL us supposed to fail\n"); 966 } 967 968 /*Try udata_openChoice with a non existing binary file*/ 969 log_verbose("Testing udata_openChoice() with a non existing binary file\n"); 970 result=udata_openChoice(testPath, "tst", "nonexist", isAcceptable3, NULL, &status); 971 if(status==U_FILE_ACCESS_ERROR){ 972 log_verbose("Opening udata_openChoice with non-existing file handled correctly.\n"); 973 status=U_ZERO_ERROR; 974 } else { 975 log_err("calling udata_open with non-existing file not handled correctly\n. Expected: U_FILE_ACCESS_ERROR, Got: %s\n", myErrorName(status)); 976 if(U_SUCCESS(status)) { 977 udata_close(result); 978 } 979 } 980 981 if(result != NULL){ 982 log_err("calling udata_open with non-existing file didn't return a null value\n"); 983 } else { 984 log_verbose("calling udat_open with non-existing file returned null as expected\n"); 985 } 986 } 987 988 /* Test whether apps and ICU can each have their own root.res */ 989 static void TestAppData() 990 { 991 UResourceBundle *icu, *app; 992 UResourceBundle *tmp = NULL; 993 UResourceBundle *tmp2 = NULL; 994 995 const UChar *appString; 996 const UChar *icuString; 997 998 int32_t len; 999 1000 UErrorCode status = U_ZERO_ERROR; 1001 char testMsgBuf[256]; 1002 1003 const char* testPath=loadTestData(&status); 1004 if(U_FAILURE(status)) { 1005 log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status)); 1006 return; 1007 } 1008 1009 icu = ures_open(NULL, "root", &status); 1010 if(U_FAILURE(status)) 1011 { 1012 log_data_err("%s:%d: Couldn't open root ICU bundle- %s", __FILE__, __LINE__, u_errorName(status)); 1013 return; 1014 } 1015 /* log_info("Open icu root: %s size_%d\n", u_errorName(status), ures_getSize(icu)); */ 1016 status = U_ZERO_ERROR; 1017 1018 app = ures_open(testPath, "root", &status); 1019 if(U_FAILURE(status)) 1020 { 1021 log_data_err("%s:%d: Couldn't open app ICU bundle [%s]- %s", __FILE__, __LINE__, testPath, u_errorName(status)); 1022 return; 1023 } 1024 /* log_info("Open app: %s, size %d\n", u_errorName(status), ures_getSize(app)); */ 1025 1026 tmp = ures_getByKey(icu, "Version", tmp, &status); 1027 if(U_FAILURE(status)) 1028 { 1029 log_err("%s:%d: Couldn't get Version string from ICU root bundle- %s", __FILE__, __LINE__, u_errorName(status)); 1030 return; 1031 } 1032 1033 icuString = ures_getString(tmp, &len, &status); 1034 if(U_FAILURE(status)) 1035 { 1036 log_err("%s:%d: Couldn't get string from Version string from ICU root bundle- %s", __FILE__, __LINE__, u_errorName(status)); 1037 return; 1038 } 1039 /* log_info("icuString=%p - %s\n", icuString, austrdup(icuString)); */ 1040 1041 1042 tmp2 = ures_getByKey(app, "Version", tmp2, &status); 1043 if(U_FAILURE(status)) 1044 { 1045 log_err("%s:%d: Couldn't get Version string from App root bundle- %s", __FILE__, __LINE__, u_errorName(status)); 1046 return; 1047 } 1048 1049 appString = ures_getString(tmp2, &len, &status); 1050 if(U_FAILURE(status)) 1051 { 1052 log_err("%s:%d: Couldn't get string from Version string from App root bundle- %s", __FILE__, __LINE__, u_errorName(status)); 1053 return; 1054 } 1055 1056 /* log_info("appString=%p - %s\n", appString, austrdup(appString)); */ 1057 1058 1059 if(!u_strcmp(icuString, appString)) 1060 { 1061 log_err("%s:%d: Error! Expected ICU and App root version strings to be DIFFERENT but they are both %s and %s\n", __FILE__, __LINE__, austrdup(icuString), 1062 austrdup(appString)); 1063 } 1064 else 1065 { 1066 log_verbose("%s:%d: appstr=%s, icustr=%s\n", __FILE__, 1067 __LINE__, u_austrcpy(testMsgBuf, appString), u_austrcpy(testMsgBuf, icuString)); 1068 } 1069 1070 ures_close(tmp); 1071 ures_close(tmp2); 1072 ures_close(icu); 1073 ures_close(app); 1074 } 1075 1076 static void TestICUDataName() 1077 { 1078 UVersionInfo icuVersion; 1079 char expectDataName[20]; 1080 unsigned int expectLen = 8; 1081 1082 char typeChar = '?'; 1083 1084 /* Print out the version # we have .. */ 1085 log_verbose("utypes.h says U_ICUDATA_NAME = %s\n", U_ICUDATA_NAME); 1086 1087 /* Build up the version # we expect to get */ 1088 u_getVersion(icuVersion); 1089 1090 switch(U_CHARSET_FAMILY) 1091 { 1092 case U_ASCII_FAMILY: 1093 switch(U_IS_BIG_ENDIAN) 1094 { 1095 case 1: 1096 typeChar = 'b'; 1097 break; 1098 case 0: 1099 typeChar = 'l'; 1100 break; 1101 default: 1102 log_err("Expected 1 or 0 for U_IS_BIG_ENDIAN, got %d!\n", (int)U_IS_BIG_ENDIAN); 1103 /* return; */ 1104 } 1105 break; 1106 case U_EBCDIC_FAMILY: 1107 typeChar = 'e'; 1108 break; 1109 } 1110 1111 sprintf(expectDataName, "%s%d%d%c", 1112 "icudt", 1113 (int)icuVersion[0], 1114 (int)icuVersion[1], 1115 typeChar); 1116 1117 log_verbose("Expected: %s\n", expectDataName); 1118 if(uprv_strlen(expectDataName) != expectLen) 1119 { 1120 log_err("*Expected* length is wrong (test err?), should be %d is %d\n", 1121 expectLen, uprv_strlen(expectDataName)); 1122 } 1123 1124 if(uprv_strlen(U_ICUDATA_NAME) != expectLen) 1125 { 1126 log_err("U_ICUDATA_NAME length should be %d is %d\n", 1127 expectLen, uprv_strlen(U_ICUDATA_NAME)); 1128 } 1129 1130 if(uprv_strcmp(U_ICUDATA_NAME, expectDataName)) 1131 { 1132 log_err("U_ICUDATA_NAME should be %s but is %s\n", 1133 expectDataName, U_ICUDATA_NAME); 1134 } 1135 1136 /* ICUDATA_NAME comes from the build system on *nix */ 1137 #ifdef ICUDATA_NAME 1138 if(uprv_strcmp(U_ICUDATA_NAME, ICUDATA_NAME)) 1139 { 1140 log_err("ICUDATA_NAME and U_ICUDATA_NAME don't match: " 1141 "ICUDATA_NAME=%s, U_ICUDATA_NAME=%s. Check configure.in, icudefs.mk.in, utypes.h...\n", ICUDATA_NAME, U_ICUDATA_NAME); 1142 } 1143 else 1144 { 1145 log_verbose("ICUDATA_NAME=%s (from icudefs.mk), U_ICUDATA_NAME=%s (from utypes.h)\n", ICUDATA_NAME, U_ICUDATA_NAME); 1146 } 1147 #endif 1148 1149 } 1150 1151 /* test data swapping ------------------------------------------------------- */ 1152 1153 #ifdef OS400 1154 /* See comments in genccode.c on when this special implementation can be removed. */ 1155 static const struct { 1156 double bogus; 1157 const char *bytes; 1158 } gOffsetTOCAppDataItem1={ 0.0, /* alignment bytes */ 1159 "\x00\x14" /* sizeof(UDataInfo) *//* MappedData { */ 1160 "\xda" 1161 "\x27" /* } */ 1162 "\x00\x14" /* sizeof(UDataInfo) *//* UDataInfo { */ 1163 "\0\0" 1164 "\1" /* U_IS_BIG_ENDIAN */ 1165 "\1" /* U_CHARSET_FAMILY */ 1166 "\2" /* U_SIZEOF_WHAR_T */ 1167 "\0" 1168 "\x31\x31\x31\x31" 1169 "\0\0\0\0" 1170 "\0\0\0\0" /* } */ 1171 }; 1172 #else 1173 static const struct { 1174 double bogus; 1175 MappedData bytes1; 1176 UDataInfo bytes2; 1177 uint8_t bytes3; 1178 } gOffsetTOCAppDataItem1={ 1179 0.0, /* alignment bytes */ 1180 { sizeof(UDataInfo), 0xda, 0x27 }, /* MappedData */ 1181 1182 {sizeof(UDataInfo), 1183 0, 1184 1185 U_IS_BIG_ENDIAN, 1186 U_CHARSET_FAMILY, 1187 sizeof(UChar), 1188 0, 1189 1190 {0x31, 0x31, 0x31, 0x31}, /* dataFormat="1111" */ 1191 {0, 0, 0, 0}, /* formatVersion */ 1192 {0, 0, 0, 0}} /* dataVersion */ 1193 }; 1194 #endif 1195 1196 static const UChar gOffsetTOCGarbage[] = { /* "I have been very naughty!" */ 1197 0x49, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6E, 1198 0x20, 0x76, 0x65, 0x72, 0x79, 0x20, 0x6E, 0x61, 0x75, 0x67, 0x68, 0x74, 0x79, 0x21 1199 }; 1200 1201 /* Original source: icu/source/tools/genccode */ 1202 static const struct { 1203 uint16_t headerSize; 1204 uint8_t magic1, magic2; 1205 UDataInfo info; 1206 char padding[8]; 1207 uint32_t count, reserved; 1208 const struct { 1209 const char *const name; 1210 const void *const data; 1211 } toc[3]; 1212 } gOffsetTOCAppData_dat = { 1213 32, /* headerSize */ 1214 0xda, /* magic1, (see struct MappedData in udata.c) */ 1215 0x27, /* magic2 */ 1216 { /*UDataInfo */ 1217 sizeof(UDataInfo), /* size */ 1218 0, /* reserved */ 1219 U_IS_BIG_ENDIAN, 1220 U_CHARSET_FAMILY, 1221 sizeof(UChar), 1222 0, /* reserved */ 1223 { /* data format identifier */ 1224 0x54, 0x6f, 0x43, 0x50}, /* "ToCP" */ 1225 {1, 0, 0, 0}, /* format version major, minor, milli, micro */ 1226 {0, 0, 0, 0} /* dataVersion */ 1227 }, 1228 {0,0,0,0,0,0,0,0}, /* Padding[8] */ 1229 3, /* count */ 1230 0, /* Reserved */ 1231 { /* TOC structure */ 1232 { "OffsetTOCAppData/a/b", &gOffsetTOCAppDataItem1 }, 1233 { "OffsetTOCAppData/gOffsetTOCAppDataItem1", &gOffsetTOCAppDataItem1 }, 1234 { "OffsetTOCAppData/gOffsetTOCGarbage", &gOffsetTOCGarbage } 1235 } 1236 }; 1237 1238 /* Unfortunately, trie dictionaries are in a C++ header */ 1239 int32_t 1240 triedict_swap(const UDataSwapper *ds, 1241 const void *inData, int32_t length, void *outData, 1242 UErrorCode *pErrorCode); 1243 1244 /* test cases for maximum data swapping code coverage */ 1245 static const struct { 1246 const char *name, *type; 1247 UDataSwapFn *swapFn; 1248 } swapCases[]={ 1249 /* resource bundles */ 1250 1251 /* resource bundle with many data types */ 1252 {"*testtypes", "res", ures_swap}, 1253 /* resource bundle with collation data */ 1254 {"ja", "res", ures_swap}, 1255 /* resource bundle with options-only collation data */ 1256 {"ru", "res", ures_swap}, 1257 {"el", "res", ures_swap}, 1258 /* ICU's root */ 1259 {"root", "res", ures_swap}, 1260 /* Test a 32-bit key table. This is large. */ 1261 {"*testtable32", "res", ures_swap}, 1262 1263 /* ICU 4.2 resource bundle - data format 1.2 (little-endian ASCII) */ 1264 {"*old_l_testtypes", "res", ures_swap}, 1265 /* same for big-endian EBCDIC */ 1266 {"*old_e_testtypes", "res", ures_swap}, 1267 1268 #if !UCONFIG_NO_COLLATION 1269 /* standalone collation data files */ 1270 {"ucadata", "icu", ucol_swap}, 1271 {"invuca", "icu", ucol_swapInverseUCA}, 1272 #endif 1273 1274 #if !UCONFIG_NO_LEGACY_CONVERSION 1275 /* conversion table files */ 1276 1277 /* SBCS conversion table file without extension */ 1278 {"ibm-913_P100-2000", "cnv", ucnv_swap}, 1279 /* EBCDIC_STATEFUL conversion table file with extension */ 1280 {"ibm-1390_P110-2003", "cnv", ucnv_swap}, 1281 /* DBCS extension-only conversion table file */ 1282 {"ibm-16684_P110-2003", "cnv", ucnv_swap}, 1283 /* EUC-TW (3-byte) conversion table file without extension */ 1284 {"ibm-964_P110-1999", "cnv", ucnv_swap}, 1285 /* GB 18030 (4-byte) conversion table file without extension */ 1286 {"gb18030", "cnv", ucnv_swap}, 1287 /* MBCS conversion table file with extension */ 1288 {"*test4x", "cnv", ucnv_swap}, 1289 /* 1290 * MBCS conversion table file without extension, 1291 * to test swapping and preflighting of UTF-8-friendly mbcsIndex[]. 1292 */ 1293 {"jisx-212", "cnv", ucnv_swap}, 1294 #endif 1295 1296 #if !UCONFIG_NO_CONVERSION 1297 /* alias table */ 1298 {"cnvalias", "icu", ucnv_swapAliases}, 1299 #endif 1300 1301 #if !UCONFIG_NO_IDNA 1302 {"rfc3491", "spp", usprep_swap}, 1303 #endif 1304 1305 #if !UCONFIG_NO_BREAK_ITERATION 1306 {"char", "brk", ubrk_swap}, 1307 {"thaidict", "ctd", triedict_swap}, 1308 #endif 1309 1310 /* the last item should not be #if'ed so that it can reliably omit the last comma */ 1311 1312 /* Unicode properties */ 1313 {"pnames", "icu", upname_swap}, 1314 #if 0 1315 /* 1316 * Starting with ICU4C 3.4, the core Unicode properties files 1317 * (uprops.icu, ucase.icu, ubidi.icu, unorm.icu) 1318 * are hardcoded in the common DLL and therefore not included 1319 * in the data package any more. 1320 * Their swapping code is moved from the common DLL to the icuswap tool so that 1321 * we need not jump through hoops (like adding snapshots of these files 1322 * to testdata) for code coverage in tests. 1323 * See Jitterbug 4497. 1324 * 1325 * ICU4C 4.4 adds normalization data files again, e.g., nfc.nrm. 1326 */ 1327 {"uprops", "icu", uprops_swap}, 1328 {"ucase", "icu", ucase_swap}, 1329 {"ubidi", "icu", ubidi_swap}, 1330 #endif 1331 #if !UCONFIG_NO_NORMALIZATION 1332 {"nfc", "nrm", unorm2_swap}, 1333 #endif 1334 {"unames", "icu", uchar_swapNames} 1335 }; 1336 1337 /* Large enough for the largest swappable data item. */ 1338 #define SWAP_BUFFER_SIZE 1800000 1339 1340 static void U_CALLCONV 1341 printError(void *context, const char *fmt, va_list args) { 1342 vlog_info("[swap] ", fmt, args); 1343 log_err("\n"); /* Register error */ 1344 } 1345 1346 static void 1347 TestSwapCase(UDataMemory *pData, const char *name, 1348 UDataSwapFn *swapFn, 1349 uint8_t *buffer, uint8_t *buffer2) { 1350 UDataSwapper *ds; 1351 const void *inData, *inHeader; 1352 int32_t length, dataLength, length2, headerLength; 1353 1354 UErrorCode errorCode; 1355 UErrorCode badStatus; 1356 1357 UBool inEndian, oppositeEndian; 1358 uint8_t inCharset, oppositeCharset; 1359 1360 /* First we check that swapFn handles failures as expected. */ 1361 errorCode = U_UNSUPPORTED_ERROR; 1362 length = swapFn(NULL, NULL, 0, buffer, &errorCode); 1363 if (length != 0 || errorCode != U_UNSUPPORTED_ERROR) { 1364 log_err("%s() did not fail as expected - %s\n", name, u_errorName(errorCode)); 1365 } 1366 errorCode = U_ZERO_ERROR; 1367 length = swapFn(NULL, NULL, 0, buffer, &errorCode); 1368 if (length != 0 || errorCode != U_ILLEGAL_ARGUMENT_ERROR) { 1369 log_err("%s() did not fail as expected with bad arguments - %s\n", name, u_errorName(errorCode)); 1370 } 1371 1372 1373 /* Continue with the rest of the tests. */ 1374 errorCode = U_ZERO_ERROR; 1375 inData=udata_getMemory(pData); 1376 1377 /* 1378 * get the data length if possible, to verify that swapping and preflighting 1379 * handles the entire data 1380 */ 1381 dataLength=udata_getLength(pData); 1382 1383 /* 1384 * get the header and its length 1385 * all of the swap implementation functions require the header to be included 1386 */ 1387 inHeader=udata_getRawMemory(pData); 1388 headerLength=(int32_t)((const char *)inData-(const char *)inHeader); 1389 1390 /* first swap to opposite endianness but same charset family */ 1391 errorCode=U_ZERO_ERROR; 1392 ds=udata_openSwapperForInputData(inHeader, headerLength, 1393 !U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &errorCode); 1394 if(U_FAILURE(errorCode)) { 1395 log_err("udata_openSwapperForInputData(%s->!isBig+same charset) failed - %s\n", 1396 name, u_errorName(errorCode)); 1397 return; 1398 } 1399 1400 inEndian=ds->inIsBigEndian; 1401 inCharset=ds->inCharset; 1402 1403 oppositeEndian=!inEndian; 1404 oppositeCharset= inCharset==U_ASCII_FAMILY ? U_EBCDIC_FAMILY : U_ASCII_FAMILY; 1405 1406 /* make this test work with data files that are built for a different platform */ 1407 if(inEndian!=U_IS_BIG_ENDIAN || inCharset!=U_CHARSET_FAMILY) { 1408 udata_closeSwapper(ds); 1409 ds=udata_openSwapper(inEndian, inCharset, oppositeEndian, inCharset, &errorCode); 1410 if(U_FAILURE(errorCode)) { 1411 log_err("udata_openSwapper(%s->!isBig+same charset) failed - %s\n", 1412 name, u_errorName(errorCode)); 1413 return; 1414 } 1415 } 1416 1417 /* 1418 Check error checking of swappable data not specific to this swapper. 1419 This should always fail. 1420 */ 1421 badStatus = U_ZERO_ERROR; 1422 length=swapFn(ds, &gOffsetTOCAppData_dat, -1, NULL, &badStatus); 1423 if(badStatus != U_UNSUPPORTED_ERROR) { 1424 log_err("swapFn(%s->!isBig+same charset) unexpectedly succeeded on bad data - %s\n", 1425 name, u_errorName(errorCode)); 1426 udata_closeSwapper(ds); 1427 return; 1428 } 1429 1430 /* Now allow errors to be printed */ 1431 ds->printError=printError; 1432 1433 /* preflight the length */ 1434 length=swapFn(ds, inHeader, -1, NULL, &errorCode); 1435 if(U_FAILURE(errorCode)) { 1436 log_err("swapFn(preflight %s->!isBig+same charset) failed - %s\n", 1437 name, u_errorName(errorCode)); 1438 udata_closeSwapper(ds); 1439 return; 1440 } 1441 1442 /* compare the preflighted length against the data length */ 1443 if(dataLength>=0 && (length+15)<(headerLength+dataLength)) { 1444 log_err("swapFn(preflight %s->!isBig+same charset) length too small: %d < data length %d\n", 1445 name, length, (headerLength+dataLength)); 1446 udata_closeSwapper(ds); 1447 return; 1448 } 1449 1450 /* swap, not in-place */ 1451 length2=swapFn(ds, inHeader, length, buffer, &errorCode); 1452 udata_closeSwapper(ds); 1453 if(U_FAILURE(errorCode)) { 1454 log_err("swapFn(%s->!isBig+same charset) failed - %s\n", 1455 name, u_errorName(errorCode)); 1456 return; 1457 } 1458 1459 /* compare the swap length against the preflighted length */ 1460 if(length2!=length) { 1461 log_err("swapFn(%s->!isBig+same charset) length differs from preflighting: %d != preflighted %d\n", 1462 name, length2, length); 1463 return; 1464 } 1465 1466 /* next swap to opposite charset family */ 1467 ds=udata_openSwapper(oppositeEndian, inCharset, 1468 oppositeEndian, oppositeCharset, 1469 &errorCode); 1470 if(U_FAILURE(errorCode)) { 1471 log_err("udata_openSwapper(%s->!isBig+other charset) failed - %s\n", 1472 name, u_errorName(errorCode)); 1473 return; 1474 } 1475 ds->printError=printError; 1476 1477 /* swap in-place */ 1478 length2=swapFn(ds, buffer, length, buffer, &errorCode); 1479 udata_closeSwapper(ds); 1480 if(U_FAILURE(errorCode)) { 1481 log_err("swapFn(%s->!isBig+other charset) failed - %s\n", 1482 name, u_errorName(errorCode)); 1483 return; 1484 } 1485 1486 /* compare the swap length against the original length */ 1487 if(length2!=length) { 1488 log_err("swapFn(%s->!isBig+other charset) length differs from original: %d != original %d\n", 1489 name, length2, length); 1490 return; 1491 } 1492 1493 /* finally swap to original platform values */ 1494 ds=udata_openSwapper(oppositeEndian, oppositeCharset, 1495 inEndian, inCharset, 1496 &errorCode); 1497 if(U_FAILURE(errorCode)) { 1498 log_err("udata_openSwapper(%s->back to original) failed - %s\n", 1499 name, u_errorName(errorCode)); 1500 return; 1501 } 1502 ds->printError=printError; 1503 1504 /* swap, not in-place */ 1505 length2=swapFn(ds, buffer, length, buffer2, &errorCode); 1506 udata_closeSwapper(ds); 1507 if(U_FAILURE(errorCode)) { 1508 log_err("swapFn(%s->back to original) failed - %s\n", 1509 name, u_errorName(errorCode)); 1510 return; 1511 } 1512 1513 /* compare the swap length against the original length */ 1514 if(length2!=length) { 1515 log_err("swapFn(%s->back to original) length differs from original: %d != original %d\n", 1516 name, length2, length); 1517 return; 1518 } 1519 1520 /* compare the final contents with the original */ 1521 if(0!=uprv_memcmp(inHeader, buffer2, length)) { 1522 const uint8_t *original; 1523 uint8_t diff[8]; 1524 int32_t i, j; 1525 1526 log_err("swapFn(%s->back to original) contents differs from original\n", 1527 name); 1528 1529 /* find the first difference */ 1530 original=(const uint8_t *)inHeader; 1531 for(i=0; i<length && original[i]==buffer2[i]; ++i) {} 1532 1533 /* find the next byte that is the same */ 1534 for(j=i+1; j<length && original[j]!=buffer2[j]; ++j) {} 1535 log_info(" difference at index %d=0x%x, until index %d=0x%x\n", i, i, j, j); 1536 1537 /* round down to the last 4-boundary for better result output */ 1538 i&=~3; 1539 log_info("showing bytes from index %d=0x%x (length %d=0x%x):\n", i, i, length, length); 1540 1541 /* print 8 bytes but limit to the buffer contents */ 1542 length2=i+sizeof(diff); 1543 if(length2>length) { 1544 length2=length; 1545 } 1546 1547 /* print the original bytes */ 1548 uprv_memset(diff, 0, sizeof(diff)); 1549 for(j=i; j<length2; ++j) { 1550 diff[j-i]=original[j]; 1551 } 1552 log_info(" original: %02x %02x %02x %02x %02x %02x %02x %02x\n", 1553 diff[0], diff[1], diff[2], diff[3], diff[4], diff[5], diff[6], diff[7]); 1554 1555 /* print the swapped bytes */ 1556 uprv_memset(diff, 0, sizeof(diff)); 1557 for(j=i; j<length2; ++j) { 1558 diff[j-i]=buffer2[j]; 1559 } 1560 log_info(" swapped: %02x %02x %02x %02x %02x %02x %02x %02x\n", 1561 diff[0], diff[1], diff[2], diff[3], diff[4], diff[5], diff[6], diff[7]); 1562 } 1563 } 1564 1565 static void U_CALLCONV 1566 printErrorToString(void *context, const char *fmt, va_list args) { 1567 vsprintf((char *)context, fmt, args); 1568 } 1569 1570 static void 1571 TestSwapData() { 1572 char name[100]; 1573 UDataSwapper *ds; 1574 UDataMemory *pData; 1575 uint8_t *buffer; 1576 const char *pkg, *nm, *testPath; 1577 UErrorCode errorCode = U_ZERO_ERROR; 1578 int32_t i; 1579 1580 buffer=(uint8_t *)malloc(2*SWAP_BUFFER_SIZE); 1581 if(buffer==NULL) { 1582 log_err("unable to allocate %d bytes\n", 2*SWAP_BUFFER_SIZE); 1583 return; 1584 } 1585 1586 testPath=loadTestData(&errorCode); 1587 if(U_FAILURE(errorCode)) { 1588 log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(errorCode)); 1589 } 1590 1591 /* Test that printError works as expected. */ 1592 errorCode=U_USELESS_COLLATOR_ERROR; 1593 ds=udata_openSwapper(U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1594 !U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1595 &errorCode); 1596 if (ds != NULL || errorCode != U_USELESS_COLLATOR_ERROR) { 1597 log_err("udata_openSwapper should have returned NULL with bad argument\n", name); 1598 } 1599 errorCode=U_ZERO_ERROR; 1600 ds=udata_openSwapper(U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1601 !U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1602 &errorCode); 1603 ds->printError=printErrorToString; 1604 ds->printErrorContext=name; 1605 udata_printError(ds, "This %s a %s", "is", "test"); 1606 udata_closeSwapper(ds); 1607 if (strcmp(name, "This is a test") != 0) { 1608 log_err("udata_printError can't properly print error messages. Got = %s\n", name); 1609 } 1610 errorCode = U_USELESS_COLLATOR_ERROR; 1611 ds=udata_openSwapperForInputData(NULL, 0, 1612 !U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1613 &errorCode); 1614 if (ds != NULL || errorCode != U_USELESS_COLLATOR_ERROR) { 1615 log_err("udata_openSwapperForInputData should have returned NULL with bad argument\n", name); 1616 } 1617 errorCode=U_ZERO_ERROR; 1618 ds=udata_openSwapperForInputData(NULL, 0, 1619 !U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1620 &errorCode); 1621 if (ds != NULL || errorCode != U_ILLEGAL_ARGUMENT_ERROR) { 1622 log_err("udata_openSwapperForInputData should have returned NULL with bad argument\n", name); 1623 } 1624 errorCode=U_ZERO_ERROR; 1625 memset(buffer, 0, sizeof(2*SWAP_BUFFER_SIZE)); 1626 ds=udata_openSwapperForInputData(buffer, 2*SWAP_BUFFER_SIZE, 1627 !U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1628 &errorCode); 1629 if (ds != NULL || errorCode != U_UNSUPPORTED_ERROR) { 1630 log_err("udata_openSwapperForInputData should have returned NULL with bad argument\n", name); 1631 } 1632 errorCode=U_ZERO_ERROR; 1633 1634 /* Test argument checking. ucol_swapBinary is normally tested via ures_swap, and isn't normally called directly. */ 1635 #if !UCONFIG_NO_COLLATION 1636 ucol_swapBinary(NULL, NULL, -1, NULL, NULL); 1637 ucol_swapBinary(NULL, NULL, -1, NULL, &errorCode); 1638 if (errorCode != U_ILLEGAL_ARGUMENT_ERROR) { 1639 log_err("ucol_swapBinary did not fail as expected\n", name); 1640 } 1641 errorCode=U_ZERO_ERROR; 1642 #endif 1643 1644 for(i=0; i<LENGTHOF(swapCases); ++i) { 1645 /* build the name for logging */ 1646 errorCode=U_ZERO_ERROR; 1647 if(swapCases[i].name[0]=='*') { 1648 pkg=testPath; 1649 nm=swapCases[i].name+1; 1650 uprv_strcpy(name, "testdata"); 1651 } else if (uprv_strcmp(swapCases[i].type, "brk")==0 1652 || uprv_strcmp(swapCases[i].type, "ctd")==0) { 1653 pkg=U_ICUDATA_BRKITR; 1654 nm=swapCases[i].name; 1655 uprv_strcpy(name, U_ICUDATA_BRKITR); 1656 } else if (uprv_strcmp(swapCases[i].name, "ucadata")==0 1657 || uprv_strcmp(swapCases[i].name, "invuca")==0) { 1658 pkg=U_ICUDATA_COLL; 1659 nm=swapCases[i].name; 1660 uprv_strcpy(name, U_ICUDATA_COLL); 1661 } else { 1662 pkg=NULL; 1663 nm=swapCases[i].name; 1664 uprv_strcpy(name, "NULL"); 1665 } 1666 uprv_strcat(name, "/"); 1667 uprv_strcat(name, nm); 1668 uprv_strcat(name, "."); 1669 uprv_strcat(name, swapCases[i].type); 1670 1671 pData=udata_open(pkg, swapCases[i].type, nm, &errorCode); 1672 if(U_SUCCESS(errorCode)) { 1673 TestSwapCase(pData, name, swapCases[i].swapFn, buffer, buffer+SWAP_BUFFER_SIZE); 1674 udata_close(pData); 1675 } else { 1676 log_data_err("udata_open(%s) failed - %s\n", 1677 name, u_errorName(errorCode)); 1678 } 1679 } 1680 1681 free(buffer); 1682 } 1683 1684 1685 static void PointerTableOfContents() { 1686 UDataMemory *dataItem; 1687 UErrorCode status=U_ZERO_ERROR; 1688 1689 /* 1690 * Got testdata.dat into memory, now we try setAppData using the memory image. 1691 */ 1692 1693 status=U_ZERO_ERROR; 1694 udata_setAppData("OffsetTOCAppData", &gOffsetTOCAppData_dat, &status); 1695 if (status != U_ZERO_ERROR) { 1696 log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData1\", fileBuf, status) \n" 1697 " returned status of %s\n", u_errorName(status)); 1698 return; 1699 } 1700 1701 dataItem = udata_open("OffsetTOCAppData", "", "gOffsetTOCAppDataItem1", &status); 1702 if (U_FAILURE(status)) { 1703 log_err("FAIL: gOffsetTOCAppDataItem1 could not be opened. status = %s\n", u_errorName(status)); 1704 } 1705 if (udata_getMemory(dataItem) != NULL) { 1706 log_verbose("FAIL: udata_getMemory(dataItem) passed\n"); 1707 } 1708 else { 1709 log_err("FAIL: udata_getMemory returned NULL\n", u_errorName(status)); 1710 } 1711 udata_close(dataItem); 1712 1713 dataItem = udata_open("OffsetTOCAppData-a", "", "b", &status); 1714 if (U_FAILURE(status)) { 1715 log_err("FAIL: gOffsetTOCAppDataItem1 in tree \"a\" could not be opened. status = %s\n", u_errorName(status)); 1716 } 1717 if (udata_getMemory(dataItem) != NULL) { 1718 log_verbose("FAIL: udata_getMemory(dataItem) in tree \"a\" passed\n"); 1719 } 1720 else { 1721 log_err("FAIL: udata_getMemory returned NULL\n", u_errorName(status)); 1722 } 1723 udata_close(dataItem); 1724 1725 dataItem = udata_open("OffsetTOCAppData", "", "gOffsetTOCGarbage", &status); 1726 if (U_SUCCESS(status)) { 1727 log_err("FAIL: gOffsetTOCGarbage should not be opened. status = %s\n", u_errorName(status)); 1728 } 1729 dataItem = udata_open("OffsetTOCAppData", "", "gOffsetTOCNonExistent", &status); 1730 if (U_SUCCESS(status)) { 1731 log_err("FAIL: gOffsetTOCNonExistent should not be found. status = %s\n", u_errorName(status)); 1732 } 1733 1734 } 1735 1736 static void SetBadCommonData(void) { 1737 /* It's difficult to test that udata_setCommonData really works within the test framework. 1738 So we just test that foolish people can't do bad things. */ 1739 UErrorCode status; 1740 char badBuffer[sizeof(gOffsetTOCAppData_dat)]; 1741 1742 memset(badBuffer, 0, sizeof(badBuffer)); 1743 strcpy(badBuffer, "Hello! I'm not good data."); 1744 1745 /* Check that we don't do anything */ 1746 status = U_FILE_ACCESS_ERROR; 1747 udata_setCommonData(&gOffsetTOCAppData_dat, &status); 1748 if (status != U_FILE_ACCESS_ERROR) { 1749 log_err("FAIL: udata_setCommonData changed the failure code.\n"); 1750 } 1751 /* Check that we fail correctly */ 1752 status = U_ZERO_ERROR; 1753 udata_setCommonData(NULL, &status); 1754 if (status != U_ILLEGAL_ARGUMENT_ERROR) { 1755 log_err("FAIL: udata_setCommonData did not fail with bad arguments.\n"); 1756 } 1757 1758 /* Check that we verify that the data isn't bad */ 1759 status = U_ZERO_ERROR; 1760 udata_setAppData("invalid path", badBuffer, &status); 1761 if (status != U_INVALID_FORMAT_ERROR) { 1762 log_err("FAIL: udata_setAppData doesn't verify data validity.\n"); 1763 } 1764 } 1765 1766