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