ICU-7035 stop support for ICU resource bundle formatVersion 1.0 [predates ICU 2.8] in swapper code

X-SVN-Rev: 27294
This commit is contained in:
Markus Scherer 2010-01-16 05:15:30 +00:00
parent 0e375461b0
commit 0a48da9893
7 changed files with 56 additions and 212 deletions

4
.gitattributes vendored
View file

@ -62,10 +62,10 @@ icu4c/source/test/intltest/selfmts.cpp -text
icu4c/source/test/intltest/selfmts.h -text
icu4c/source/test/perf/README -text
icu4c/source/test/testdata/TestFont1.otf -text
icu4c/source/test/testdata/icu26_testtypes.res -text
icu4c/source/test/testdata/icu26e_testtypes.res -text
icu4c/source/test/testdata/importtest.bin -text
icu4c/source/test/testdata/iscii.bin -text
icu4c/source/test/testdata/old_e_testtypes.res -text
icu4c/source/test/testdata/old_l_testtypes.res -text
icu4c/source/test/testdata/uni-text.bin -text
icu4c/source/tools/icuinfo/icuinfo.vcproj -text
icu4c/source/tools/icuinfo/icuplugins_windows_sample.txt -text

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
* *
* Copyright (C) 1999-2009, International Business Machines Corporation *
* Copyright (C) 1999-2010, International Business Machines Corporation *
* and others. All Rights Reserved. *
* *
*******************************************************************************
@ -668,145 +668,8 @@ static const UChar gCollationBinKey[]={
0
};
/*
* preflight one resource item and set bottom and top values;
* length, bottom, and top count Resource item offsets (4 bytes each), not bytes
*
* Preflighting is only necessary for formatVersion 1.0:
* 1.1 adds these values to the data format.
*/
static void
ures_preflightResource(const UDataSwapper *ds,
const Resource *inBundle, int32_t length,
Resource res,
int32_t *pBottom, int32_t *pTop, int32_t *pMaxTableLength,
UErrorCode *pErrorCode) {
const Resource *p;
int32_t offset;
if(res==0 || RES_GET_TYPE(res)==URES_INT) {
/* empty string or integer, nothing to do */
return;
}
/* all other types use an offset to point to their data */
offset=(int32_t)RES_GET_OFFSET(res);
if(0<=length && length<=offset) {
udata_printError(ds, "ures_preflightResource(res=%08x) resource offset exceeds bundle length %d\n",
res, length);
*pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
return;
} else if(offset<*pBottom) {
*pBottom=offset;
}
p=inBundle+offset;
switch(RES_GET_TYPE(res)) {
case URES_ALIAS:
/* physically same value layout as string, fall through */
case URES_STRING:
/* top=offset+1+(string length +1)/2 rounded up */
offset+=1+((udata_readInt32(ds, (int32_t)*p)+1)+1)/2;
break;
case URES_BINARY:
/* top=offset+1+(binary length)/4 rounded up */
offset+=1+(udata_readInt32(ds, (int32_t)*p)+3)/4;
break;
case URES_TABLE:
case URES_TABLE32:
{
Resource item;
int32_t i, count;
if(RES_GET_TYPE(res)==URES_TABLE) {
/* get table item count */
const uint16_t *pKey16=(const uint16_t *)p;
count=ds->readUInt16(*pKey16++);
/* top=((1+ table item count)/2 rounded up)+(table item count) */
offset+=((1+count)+1)/2;
} else {
/* get table item count */
const int32_t *pKey32=(const int32_t *)p;
count=udata_readInt32(ds, *pKey32++);
/* top=(1+ table item count)+(table item count) */
offset+=1+count;
}
if(count>*pMaxTableLength) {
*pMaxTableLength=count;
}
p=inBundle+offset; /* pointer to table resources */
offset+=count;
/* recurse */
if(offset<=length) {
for(i=0; i<count; ++i) {
item=ds->readUInt32(*p++);
ures_preflightResource(ds, inBundle, length, item,
pBottom, pTop, pMaxTableLength,
pErrorCode);
if(U_FAILURE(*pErrorCode)) {
udata_printError(ds, "ures_preflightResource(table res=%08x)[%d].recurse(%08x) failed\n",
res, i, item);
break;
}
}
}
}
break;
case URES_ARRAY:
{
Resource item;
int32_t i, count;
/* top=offset+1+(array length) */
count=udata_readInt32(ds, (int32_t)*p++);
offset+=1+count;
/* recurse */
if(offset<=length) {
for(i=0; i<count; ++i) {
item=ds->readUInt32(*p++);
ures_preflightResource(ds, inBundle, length, item,
pBottom, pTop, pMaxTableLength,
pErrorCode);
if(U_FAILURE(*pErrorCode)) {
udata_printError(ds, "ures_preflightResource(array res=%08x)[%d].recurse(%08x) failed\n",
res, i, item);
break;
}
}
}
}
break;
case URES_INT_VECTOR:
/* top=offset+1+(vector length) */
offset+=1+udata_readInt32(ds, (int32_t)*p);
break;
default:
/* also catches RES_BOGUS */
udata_printError(ds, "ures_preflightResource(res=%08x) unknown resource type\n", res);
*pErrorCode=U_UNSUPPORTED_ERROR;
break;
}
if(U_FAILURE(*pErrorCode)) {
/* nothing to do */
} else if(0<=length && length<offset) {
udata_printError(ds, "ures_preflightResource(res=%08x) resource limit exceeds bundle length %d\n",
res, length);
*pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
} else if(offset>*pTop) {
*pTop=offset;
}
}
/*
* swap one resource item
* since preflighting succeeded, we need not check offsets against length any more
*/
static void
ures_swapResource(const UDataSwapper *ds,
@ -1094,6 +957,8 @@ ures_swap(const UDataSwapper *ds,
int32_t resort[STACK_ROW_CAPACITY];
TempTable tempTable;
const int32_t *inIndexes;
/* the following integers count Resource item offsets (4 bytes each), not bytes */
int32_t bundleLength, indexLength, keysBottom, keysTop, resBottom, top;
@ -1110,12 +975,13 @@ ures_swap(const UDataSwapper *ds,
pInfo->dataFormat[1]==0x65 &&
pInfo->dataFormat[2]==0x73 &&
pInfo->dataFormat[3]==0x42 &&
(pInfo->formatVersion[0]==1 || pInfo->formatVersion[0]==2)
((pInfo->formatVersion[0]==1 && pInfo->formatVersion[1]>=1) || /* formatVersion 1.1+ or 2.x */
pInfo->formatVersion[0]==2)
)) {
udata_printError(ds, "ures_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not a resource bundle\n",
udata_printError(ds, "ures_swap(): data format %02x.%02x.%02x.%02x (format version %02x.%02x) is not a resource bundle\n",
pInfo->dataFormat[0], pInfo->dataFormat[1],
pInfo->dataFormat[2], pInfo->dataFormat[3],
pInfo->formatVersion[0]);
pInfo->formatVersion[0], pInfo->formatVersion[1]);
*pErrorCode=U_UNSUPPORTED_ERROR;
return 0;
}
@ -1128,9 +994,7 @@ ures_swap(const UDataSwapper *ds,
bundleLength=(length-headerSize)/4;
/* formatVersion 1.1 must have a root item and at least 5 indexes */
if( bundleLength<
((pInfo->formatVersion[0]==1 && pInfo->formatVersion[1]==0) ? 1 : 1+5)
) {
if(bundleLength<(1+5)) {
udata_printError(ds, "ures_swap(): too few bytes (%d after header) for a resource bundle\n",
length-headerSize);
*pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
@ -1141,55 +1005,35 @@ ures_swap(const UDataSwapper *ds,
inBundle=(const Resource *)((const char *)inData+headerSize);
rootRes=ds->readUInt32(*inBundle);
if(pInfo->formatVersion[0]==1 && pInfo->formatVersion[1]==0) {
/* preflight to get the bottom, top and maxTableLength values */
indexLength=0;
keysBottom=1; /* just past root */
keysTop=0x7fffffff;
top=maxTableLength=0;
ures_preflightResource(ds, inBundle, bundleLength, rootRes,
&keysTop, &top, &maxTableLength,
pErrorCode);
resBottom=keysTop;
tempTable.localKeyLimit=keysTop<<2;
if(U_FAILURE(*pErrorCode)) {
udata_printError(ds, "ures_preflightResource(root res=%08x) failed\n",
rootRes);
return 0;
}
/* formatVersion 1.1 adds the indexes[] array */
inIndexes=(const int32_t *)(inBundle+1);
indexLength=udata_readInt32(ds, inIndexes[URES_INDEX_LENGTH])&0xff;
if(indexLength<=URES_INDEX_MAX_TABLE_LENGTH) {
udata_printError(ds, "ures_swap(): too few indexes for a 1.1+ resource bundle\n");
*pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
return 0;
}
keysBottom=1+indexLength;
keysTop=udata_readInt32(ds, inIndexes[URES_INDEX_KEYS_TOP]);
if(indexLength>URES_INDEX_16BIT_TOP) {
resBottom=udata_readInt32(ds, inIndexes[URES_INDEX_16BIT_TOP]);
} else {
/* formatVersion 1.1 adds the indexes[] array */
const int32_t *inIndexes;
resBottom=keysTop;
}
top=udata_readInt32(ds, inIndexes[URES_INDEX_BUNDLE_TOP]);
maxTableLength=udata_readInt32(ds, inIndexes[URES_INDEX_MAX_TABLE_LENGTH]);
inIndexes=(const int32_t *)(inBundle+1);
indexLength=udata_readInt32(ds, inIndexes[URES_INDEX_LENGTH])&0xff;
if(indexLength<=URES_INDEX_MAX_TABLE_LENGTH) {
udata_printError(ds, "ures_swap(): too few indexes for a 1.1+ resource bundle\n");
*pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
return 0;
}
keysBottom=1+indexLength;
keysTop=udata_readInt32(ds, inIndexes[URES_INDEX_KEYS_TOP]);
if(indexLength>URES_INDEX_16BIT_TOP) {
resBottom=udata_readInt32(ds, inIndexes[URES_INDEX_16BIT_TOP]);
} else {
resBottom=keysTop;
}
top=udata_readInt32(ds, inIndexes[URES_INDEX_BUNDLE_TOP]);
maxTableLength=udata_readInt32(ds, inIndexes[URES_INDEX_MAX_TABLE_LENGTH]);
if(0<=bundleLength && bundleLength<top) {
udata_printError(ds, "ures_swap(): resource top %d exceeds bundle length %d\n",
top, bundleLength);
*pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
return 0;
}
if(keysTop>(1+indexLength)) {
tempTable.localKeyLimit=keysTop<<2;
} else {
tempTable.localKeyLimit=0;
}
if(0<=bundleLength && bundleLength<top) {
udata_printError(ds, "ures_swap(): resource top %d exceeds bundle length %d\n",
top, bundleLength);
*pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
return 0;
}
if(keysTop>(1+indexLength)) {
tempTable.localKeyLimit=keysTop<<2;
} else {
tempTable.localKeyLimit=0;
}
if(length>=0) {

View file

@ -1255,10 +1255,10 @@ static const struct {
/* Test a 32-bit key table. This is large. */
{"*testtable32", "res", ures_swap},
/* ICU 2.6 resource bundle - data format 1.0, without indexes[] (little-endian ASCII) */
{"*icu26_testtypes", "res", ures_swap},
/* ICU 4.2 resource bundle - data format 1.2 (little-endian ASCII) */
{"*old_l_testtypes", "res", ures_swap},
/* same for big-endian EBCDIC */
{"*icu26e_testtypes", "res", ures_swap},
{"*old_e_testtypes", "res", ures_swap},
#if !UCONFIG_NO_COLLATION
/* standalone collation data files */

View file

@ -1,6 +1,6 @@
#******************************************************************************
#
# Copyright (C) 1998-2009, International Business Machines
# Copyright (C) 1998-2010, International Business Machines
# Corporation and others. All Rights Reserved.
#
#******************************************************************************
@ -129,7 +129,7 @@ include $(TESTSRCDATADIR)/tstfiles.mk
# TEST_RES_SOURCE comes from tstfiles.mk
TEST_RES = $(TEST_RES_SOURCE) $(TEST_RES_LOCAL) casing.txt mc.txt root.txt sh.txt sh_YU.txt te.txt te_IN.txt te_IN_REVISED.txt testtypes.txt testaliases.txt testempty.txt structLocale.txt idna_rules.txt conversion.txt icuio.txt testtable32.txt
TEST_RES_FILES=$(TEST_RES:%.txt=$(TESTBUILDDIR)/%.res) $(TESTBUILDDIR)/iscii.res $(TESTBUILDDIR)/icu26_testtypes.res $(TESTBUILDDIR)/icu26e_testtypes.res
TEST_RES_FILES=$(TEST_RES:%.txt=$(TESTBUILDDIR)/%.res) $(TESTBUILDDIR)/iscii.res $(TESTBUILDDIR)/old_l_testtypes.res $(TESTBUILDDIR)/old_e_testtypes.res
ALL_TEST_FILES = $(TEST_DAT_FILES) $(TEST_SPP_FILES) $(TEST_BRK_FILES) $(TEST_CNV_FILES) $(TEST_RES_FILES) $(TESTOUTDIR)/$(TESTDT)/nam.typ
@ -204,9 +204,9 @@ $(TESTBUILDDIR)/iscii.res: $(TESTSRCDATADIR)/iscii.bin $(TOOLBINDIR)/genrb$(EXE
$(TESTOUTDIR)/$(TESTDT)/nam.typ: $(TESTBUILDDIR)/te_IN.res
cp $< $@
$(TESTBUILDDIR)/icu26_testtypes.res: $(TESTSRCDATADIR)/icu26_testtypes.res
$(TESTBUILDDIR)/old_l_testtypes.res: $(TESTSRCDATADIR)/old_l_testtypes.res
cp $< $@
$(TESTBUILDDIR)/icu26e_testtypes.res: $(TESTSRCDATADIR)/icu26e_testtypes.res
$(TESTBUILDDIR)/old_e_testtypes.res: $(TESTSRCDATADIR)/old_e_testtypes.res
cp $< $@
testdata: build-dir $(ALL_TEST_FILES) $(UNPACKAGEDTESTDATA)

View file

@ -1,5 +1,5 @@
#**********************************************************************
#* Copyright (C) 1999-2009, International Business Machines Corporation
#* Copyright (C) 1999-2010, International Business Machines Corporation
#* and others. All Rights Reserved.
#**********************************************************************
#
@ -14,14 +14,14 @@ TESTDT=$(TESTPKG)
ALL : "$(TESTDATAOUT)\testdata.dat"
@echo Test data is built.
# icu26_testtypes.res is there for cintltst/udatatst.c/TestSwapData()
# I generated it with an ICU 2.6.1 build on Windows after removing
# testincludeUTF (which made it large, unnecessarily for this test)
# and CollationElements (which will not work with a newer swapper)
# markus 2003nov19
# old_l_testtypes.res is there for cintltst/udatatst.c/TestSwapData()
# I generated it with an ICU 4.2.1 build on Linux after removing
# testincludeUTF (which would make it large, unnecessarily for this test)
# and renaming the collations element to avoid build CollationElements
# (which will not work with a newer swapper)
# markus 2010jan15
# icu26e_testtypes.res is the same, but icuswapped to big-endian EBCDIC
# markus 2003nov21
# old_e_testtypes.res is the same, but icuswapped to big-endian EBCDIC
# the following file has $(TEST_RES_SOURCE)
!INCLUDE "$(TESTDATA)\tstfiles.mk"
@ -31,8 +31,8 @@ TEST_RES_FILES = $(TEST_RES_SOURCE:.txt=.res)
"$(TESTDATAOUT)\testdata.dat" : $(TEST_RES_FILES) "$(TESTDATABLD)\casing.res" "$(TESTDATABLD)\conversion.res" "$(TESTDATABLD)\icuio.res" "$(TESTDATABLD)\mc.res" "$(TESTDATABLD)\structLocale.res" "$(TESTDATABLD)\root.res" "$(TESTDATABLD)\sh.res" "$(TESTDATABLD)\sh_YU.res" "$(TESTDATABLD)\te.res" "$(TESTDATABLD)\te_IN.res" "$(TESTDATABLD)\te_IN_REVISED.res" "$(TESTDATABLD)\testaliases.res" "$(TESTDATABLD)\testtypes.res" "$(TESTDATABLD)\testempty.res" "$(TESTDATABLD)\iscii.res" "$(TESTDATABLD)\idna_rules.res" "$(TESTDATABLD)\DataDrivenCollationTest.res" "$(TESTDATABLD)\test.icu" "$(TESTDATABLD)\testtable32.res" "$(TESTDATABLD)\test1.cnv" "$(TESTDATABLD)\test1bmp.cnv" "$(TESTDATABLD)\test3.cnv" "$(TESTDATABLD)\test4.cnv" "$(TESTDATABLD)\test4x.cnv" "$(TESTDATABLD)\test5.cnv" "$(TESTDATABLD)\ibm9027.cnv" "$(TESTDATABLD)\nfscsi.spp" "$(TESTDATABLD)\nfscss.spp" "$(TESTDATABLD)\nfscis.spp" "$(TESTDATABLD)\nfsmxs.spp" "$(TESTDATABLD)\nfsmxp.spp"
@echo Building test data
@copy "$(TESTDATABLD)\te.res" "$(TESTDATAOUT)\$(TESTDT)\nam.typ"
@copy "$(TESTDATA)\icu26_testtypes.res" "$(TESTDATABLD)"
@copy "$(TESTDATA)\icu26e_testtypes.res" "$(TESTDATABLD)"
@copy "$(TESTDATA)\old_l_testtypes.res" "$(TESTDATABLD)"
@copy "$(TESTDATA)\old_e_testtypes.res" "$(TESTDATABLD)"
"$(ICUPBIN)\pkgdata" -f -v -m common -c -p"$(TESTPKG)" -d "$(TESTDATAOUT)" -T "$(TESTDATABLD)" -s "$(TESTDATABLD)" <<
casing.res
conversion.res
@ -45,8 +45,8 @@ te.res
te_IN.res
te_IN_REVISED.res
testtypes.res
icu26_testtypes.res
icu26e_testtypes.res
old_l_testtypes.res
old_e_testtypes.res
testempty.res
testaliases.res
structLocale.res