ICU-3008 improve udata path name buffer overflow handling

X-SVN-Rev: 14098
This commit is contained in:
Andy Heninger 2003-12-11 07:21:36 +00:00
parent c5dda76d0a
commit f22ef10cc0
2 changed files with 88 additions and 19 deletions

View file

@ -313,6 +313,61 @@ static UDataMemory *udata_cacheDataItem(const char *path, UDataMemory *item, UEr
/*-------------------------------------------------------------------------------
*
* TinyString - a small set of really simple string functions, for
* the purpose of consolidating buffer overflow code in one place
*
* Use wherever you would otherwise declare a fixed sized char[xx] buffer.
* Do non-growing ops by accessing fields of struct directly
* Grow using the append function to automatically extend buffer
* as needed.
*
*-------------------------------------------------------------------------------*/
typedef struct TinyString {
char *s;
int32_t length;
char fStaticBuf[100];
int32_t fCapacity;
} TinyString;
static TinyString_init(TinyString *This) {
This->s = This->fStaticBuf;
*This->s = 0;
This->length = 0;
This->fCapacity = sizeof(This->fStaticBuf)-1;
}
static TinyString_append(TinyString *This, const char *what) {
int32_t newLen;
newLen = This->length + uprv_strlen(what);
if (newLen >= This->fCapacity) {
int32_t newCapacity = newLen * 2;
char *newBuf = (char *)uprv_malloc(newCapacity+1);
if (newBuf != NULL) {
uprv_strcpy(newBuf, This->s);
if (This->s != This->fStaticBuf) {
uprv_free(This->s);
}
This->s = newBuf;
This->fCapacity = newCapacity;
}
}
if (newLen < This->fCapacity) {
uprv_strcat(This->s, what);
This->length = newLen;
}
}
static TinyString_dt(TinyString *This) {
if (This->s != This->fStaticBuf) {
uprv_free(This->s);
}
TinyString_init(This);
}
/*----------------------------------------------------------------------*==============
* *
@ -930,15 +985,18 @@ doOpenChoice(const char *path, const char *type, const char *name,
UDataMemoryIsAcceptable *isAcceptable, void *context,
UErrorCode *pErrorCode)
{
UDataPathIterator iter;
const char *pathBuffer;
UDataMemory *retVal = NULL;
char tocEntryName[100];
UDataPathIterator iter;
const char *pathBuffer;
TinyString tocEntryName;
char oldStylePath[1024];
char oldStylePathBasename[100];
const char *dataPath;
const char *tocEntrySuffix;
int32_t tocEntrySuffixIndex;
UDataMemory dataMemory;
UDataMemory *pCommonData;
UDataMemory *pEntryData;
@ -951,20 +1009,21 @@ doOpenChoice(const char *path, const char *type, const char *name,
*/
/* prepend the package */
uprv_strcpy(tocEntryName, packageNameFromPath(path));
TinyString_init(&tocEntryName);
TinyString_append(&tocEntryName, packageNameFromPath(path));
tocEntrySuffix = tocEntryName+uprv_strlen(tocEntryName); /* suffix starts here */
tocEntrySuffixIndex = tocEntryName.length;
uprv_strcat(tocEntryName, "_");
uprv_strcat(tocEntryName, name);
TinyString_append(&tocEntryName, "_");
TinyString_append(&tocEntryName, name);
if(type!=NULL && *type!=0) {
uprv_strcat(tocEntryName, ".");
uprv_strcat(tocEntryName, type);
TinyString_append(&tocEntryName, ".");
TinyString_append(&tocEntryName, type);
}
tocEntrySuffix = tocEntryName.s+tocEntrySuffixIndex; /* suffix starts here */
#ifdef UDATA_DEBUG
fprintf(stderr, " tocEntryName = %s\n", tocEntryName);
fprintf(stderr, " tocEntryName = %s\n", tocEntryName->s);
#endif
@ -1006,7 +1065,8 @@ doOpenChoice(const char *path, const char *type, const char *name,
path = oldStylePath;
} else {
*pErrorCode = U_FILE_ACCESS_ERROR; /* hopelessly bad case */
return NULL;
retVal = NULL;
goto commonReturn;
}
}
/* End of dealing with a null basename */
@ -1037,7 +1097,8 @@ doOpenChoice(const char *path, const char *type, const char *name,
fprintf(stderr, "** Mapped file: %s\n", pathBuffer);
#endif
udata_pathiter_dt(&iter);
return pEntryData;
retVal = pEntryData;
goto commonReturn;
}
/* the data is not acceptable, or some error occured. Either way, unmap the memory */
@ -1046,7 +1107,8 @@ doOpenChoice(const char *path, const char *type, const char *name,
/* If we had a nasty error, bail out completely. */
if (U_FAILURE(*pErrorCode)) {
udata_pathiter_dt(&iter);
return NULL;
retVal = NULL;
goto commonReturn;
}
/* Otherwise remember that we found data but didn't like it for some reason */
@ -1076,7 +1138,7 @@ doOpenChoice(const char *path, const char *type, const char *name,
int32_t length;
/* look up the data piece in the common data */
pHeader=pCommonData->vFuncs->Lookup(pCommonData, tocEntryName, &length, &errorCode);
pHeader=pCommonData->vFuncs->Lookup(pCommonData, tocEntryName.s, &length, &errorCode);
#ifdef UDATA_DEBUG
fprintf(stderr, "pHeader=%p\n", pHeader);
#endif
@ -1086,11 +1148,13 @@ doOpenChoice(const char *path, const char *type, const char *name,
fprintf(stderr, "pEntryData=%p\n", pEntryData);
#endif
if (U_FAILURE(*pErrorCode)) {
return NULL;
retVal = NULL;
goto commonReturn;
}
if (pEntryData != NULL) {
pEntryData->length = length;
return pEntryData;
retVal = pEntryData;
goto commonReturn;
}
}
}
@ -1112,7 +1176,10 @@ doOpenChoice(const char *path, const char *type, const char *name,
*pErrorCode=errorCode;
}
}
return NULL;
commonReturn:
TinyString_dt(&tocEntryName);
return retVal;
}

View file

@ -109,6 +109,8 @@ static void TestUDataOpen(){
const char* name = "test";
const char* type = "icu";
const char dirSepString[] = {U_FILE_SEP_CHAR, 0};
const char pathSepString[] = {U_PATH_SEP_CHAR, 0};
char* path=(char*)malloc(sizeof(char) * (strlen(ctest_dataOutDir())
+ strlen(U_ICUDATA_NAME)
@ -278,7 +280,7 @@ static void TestUDataOpen(){
* overflow handling code.
*/
{
#if 0
#if 1
/* TODO: fix doOpenChoice(). Bug 3121. */
char longTestPath[1024]; /* Implementation goes to heap at length of 128. */
char longName[1024];