ICU-5172 Fix memory alignment issues of safeCloning

X-SVN-Rev: 19742
This commit is contained in:
George Rhoten 2006-06-20 22:27:15 +00:00
parent 9d9a907133
commit 8806712450
2 changed files with 52 additions and 63 deletions

View File

@ -172,17 +172,17 @@ typedef struct ISO2022State {
#define UCNV_2022_MAX_CONVERTERS 10
typedef struct{
UConverterSharedData *myConverterArray[UCNV_2022_MAX_CONVERTERS];
UConverter *currentConverter;
Cnv2022Type currentType;
ISO2022State toU2022State, fromU2022State;
uint32_t key;
uint32_t version;
#ifdef U_ENABLE_GENERIC_ISO_2022
UBool isFirstBuffer;
#endif
Cnv2022Type currentType;
ISO2022State toU2022State, fromU2022State;
UConverterSharedData *myConverterArray[UCNV_2022_MAX_CONVERTERS];
uint32_t key;
uint32_t version;
char locale[3];
char name[30];
char locale[3];
}UConverterDataISO2022;
/* Protos */
@ -378,7 +378,7 @@ static const UConverterSharedData _ISO2022CNData;
/*************** Converter implementations ******************/
static void
static U_INLINE void
setInitialStateToUnicodeKR(UConverter* converter, UConverterDataISO2022 *myConverterData){
if(myConverterData->version == 1) {
UConverter *cnv = myConverterData->currentConverter;
@ -389,7 +389,7 @@ setInitialStateToUnicodeKR(UConverter* converter, UConverterDataISO2022 *myConve
}
}
static void
static U_INLINE void
setInitialStateFromUnicodeKR(UConverter* converter,UConverterDataISO2022 *myConverterData){
/* in ISO-2022-KR the designator sequence appears only once
* in a file so we append it only once
@ -421,20 +421,16 @@ _ISO2022Open(UConverter *cnv, const char *name, const char *locale,uint32_t opti
uint32_t version;
uprv_memset(myConverterData, 0, sizeof(UConverterDataISO2022));
myConverterData->currentConverter = NULL;
myConverterData->currentType = ASCII1;
myConverterData->key =0;
#ifdef U_ENABLE_GENERIC_ISO_2022
myConverterData->isFirstBuffer = TRUE;
#endif
cnv->fromUnicodeStatus =FALSE;
if(locale){
uprv_strncpy(myLocale, locale, sizeof(myLocale));
}
myConverterData->version= 0;
version = options & UCNV_OPTIONS_VERSION_MASK;
myConverterData->version = version;
if(myLocale[0]=='j' && (myLocale[1]=='a'|| myLocale[1]=='p') &&
(myLocale[2]=='_' || myLocale[2]=='\0')){
(myLocale[2]=='_' || myLocale[2]=='\0'))
{
size_t len=0;
/* open the required converters and cache them */
if(jpCharsetMasks[version]&CSM(ISO8859_7)) {
@ -456,50 +452,49 @@ _ISO2022Open(UConverter *cnv, const char *name, const char *locale,uint32_t opti
cnv->sharedData=(UConverterSharedData*)(&_ISO2022JPData);
uprv_strcpy(myConverterData->locale,"ja");
myConverterData->version = version;
uprv_strcpy(myConverterData->name,"ISO_2022,locale=ja,version=");
len = uprv_strlen(myConverterData->name);
myConverterData->name[len]=(char)(myConverterData->version+(int)'0');
myConverterData->name[len+1]='\0';
}
else if(myLocale[0]=='k' && (myLocale[1]=='o'|| myLocale[1]=='r') &&
(myLocale[2]=='_' || myLocale[2]=='\0')){
(myLocale[2]=='_' || myLocale[2]=='\0'))
{
if (version==1){
myConverterData->currentConverter=
ucnv_open("icu-internal-25546",errorCode);
if ((options & UCNV_OPTIONS_VERSION_MASK)==1){
myConverterData->version = 1;
myConverterData->currentConverter=
ucnv_open("icu-internal-25546",errorCode);
if (U_FAILURE(*errorCode)) {
_ISO2022Close(cnv);
return;
}
if (U_FAILURE(*errorCode)) {
_ISO2022Close(cnv);
return;
}
uprv_strcpy(myConverterData->name,"ISO_2022,locale=ko,version=1");
uprv_memcpy(cnv->subChar, myConverterData->currentConverter->subChar, 4);
cnv->subCharLen = myConverterData->currentConverter->subCharLen;
uprv_strcpy(myConverterData->name,"ISO_2022,locale=ko,version=1");
uprv_memcpy(cnv->subChar, myConverterData->currentConverter->subChar, 4);
cnv->subCharLen = myConverterData->currentConverter->subCharLen;
}else{
myConverterData->currentConverter=ucnv_open("ibm-949",errorCode);
myConverterData->currentConverter=ucnv_open("ibm-949",errorCode);
if (U_FAILURE(*errorCode)) {
_ISO2022Close(cnv);
return;
}
if (U_FAILURE(*errorCode)) {
_ISO2022Close(cnv);
return;
}
myConverterData->version = 0;
uprv_strcpy(myConverterData->name,"ISO_2022,locale=ko,version=0");
myConverterData->version = 0;
uprv_strcpy(myConverterData->name,"ISO_2022,locale=ko,version=0");
}
/* initialize the state variables */
setInitialStateToUnicodeKR(cnv, myConverterData);
setInitialStateFromUnicodeKR(cnv,myConverterData);
setInitialStateFromUnicodeKR(cnv, myConverterData);
/* set the function pointers to appropriate funtions */
cnv->sharedData=(UConverterSharedData*)&_ISO2022KRData;
uprv_strcpy(myConverterData->locale,"ko");
}
else if(((myLocale[0]=='z' && myLocale[1]=='h') || (myLocale[0]=='c'&& myLocale[1]=='n'))&&
(myLocale[2]=='_' || myLocale[2]=='\0')){
(myLocale[2]=='_' || myLocale[2]=='\0'))
{
/* open the required converters and cache them */
myConverterData->myConverterArray[GB2312_1] = ucnv_loadSharedData("ibm-5478", NULL, errorCode);
@ -513,16 +508,17 @@ _ISO2022Open(UConverter *cnv, const char *name, const char *locale,uint32_t opti
cnv->sharedData=(UConverterSharedData*)&_ISO2022CNData;
uprv_strcpy(myConverterData->locale,"cn");
if ((options & UCNV_OPTIONS_VERSION_MASK)==1){
myConverterData->version = 1;
if (version==1){
uprv_strcpy(myConverterData->name,"ISO_2022,locale=zh,version=1");
}else{
uprv_strcpy(myConverterData->name,"ISO_2022,locale=zh,version=0");
myConverterData->version = 0;
uprv_strcpy(myConverterData->name,"ISO_2022,locale=zh,version=0");
}
}
else{
#ifdef U_ENABLE_GENERIC_ISO_2022
myConverterData->isFirstBuffer = TRUE;
/* append the UTF-8 escape sequence */
cnv->charErrorBufferLength = 3;
cnv->charErrorBuffer[0] = 0x1b;
@ -2963,14 +2959,15 @@ _ISO_2022_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorC
struct cloneStruct
{
UConverter cnv;
UConverterDataISO2022 mydata;
UAlignedMemory deadSpace1;
UConverter currentConverter;
UAlignedMemory deadSpace2;
UConverterDataISO2022 mydata;
/*
* currentConverter may be aligned to a higher address.
* Ensure that there is enough space for that, and do not use
* the currentConverter address itself after cloning.
* Last item may be aligned to a higher address.
* Ensure that there is enough space for that.
*/
UAlignedMemory padding;
UAlignedMemory deadSpace3;
};
@ -3001,27 +2998,14 @@ _ISO_2022_SafeClone(
if(cnvData->currentConverter != NULL) {
UConverter *currentConverter;
/* distinguish local U_SAFECLONE_ALLOCATED_WARNING from one that is already set */
UErrorCode localStatus = U_ZERO_ERROR;
size = (int32_t)(sizeof(UConverter) + sizeof(UAlignedMemory)); /* include size of padding */
currentConverter =
localClone->mydata.currentConverter =
ucnv_safeClone(cnvData->currentConverter,
&localClone->currentConverter,
&size, &localStatus);
if(U_FAILURE(localStatus)) {
*status = localStatus;
&size, status);
if(U_FAILURE(*status)) {
return NULL;
}
if(localStatus == U_SAFECLONE_ALLOCATED_WARNING) {
/*
* We think we know that localClone->currentConverter is large enough.
* Check for alignment problems (see j5172).
*/
*status = U_INTERNAL_PROGRAM_ERROR;
ucnv_close(currentConverter);
return NULL;
}
localClone->mydata.currentConverter = currentConverter;
}
for(i=0; i<UCNV_2022_MAX_CONVERTERS; ++i) {

View File

@ -475,6 +475,11 @@ struct cloneHZStruct
UConverter subCnv;
UAlignedMemory deadSpace2;
UConverterDataHZ mydata;
/*
* Last item may be aligned to a higher address.
* Ensure that there is enough space for that.
*/
UAlignedMemory deadSpace3;
};
@ -504,7 +509,7 @@ _HZ_SafeClone(const UConverter *cnv,
localClone->cnv.isExtraLocal = TRUE;
/* deep-clone the sub-converter */
size = (int32_t)sizeof(UConverter);
size = (int32_t)(sizeof(UConverter) + sizeof(UAlignedMemory)); /* include size of padding */
((UConverterDataHZ*)localClone->cnv.extraInfo)->gbConverter =
ucnv_safeClone(((UConverterDataHZ*)cnv->extraInfo)->gbConverter, &localClone->subCnv, &size, status);