From 6348e128957a687792bb16cdee19db82f14bf53c Mon Sep 17 00:00:00 2001 From: GCL Shanghai Date: Sat, 6 Jul 2002 10:58:51 +0000 Subject: [PATCH] ICU-1953 test for buffer overflows X-SVN-Rev: 9044 --- icu4c/source/common/rbbinode.cpp | 4 ++ icu4c/source/common/rbbisetb.cpp | 4 ++ icu4c/source/common/rbbistbl.cpp | 5 ++- icu4c/source/common/rbbitblb.cpp | 9 ++++ icu4c/source/common/ubidiln.c | 8 ++++ icu4c/source/common/uchar.c | 13 ++++++ icu4c/source/common/ucmndata.c | 9 +++- icu4c/source/common/ucnv_bld.c | 5 +++ icu4c/source/common/ucnv_cb.c | 5 +++ icu4c/source/common/ucnv_u16.c | 16 +++++++ icu4c/source/common/ucnv_u32.c | 36 ++++++++++++++++ icu4c/source/common/ucnv_u7.c | 13 +++++- icu4c/source/common/ucnv_u8.c | 53 +++++++++++++++++++---- icu4c/source/common/ucnvhz.c | 21 +++++++-- icu4c/source/common/ucnvisci.c | 16 +++++++ icu4c/source/common/ucnvlat1.c | 12 ++++++ icu4c/source/common/ucnvmbcs.c | 63 ++++++++++++++++++++++++++- icu4c/source/common/ucnvscsu.c | 22 +++++++++- icu4c/source/common/udata.c | 8 ++++ icu4c/source/common/uloc.c | 4 ++ icu4c/source/common/unistr.cpp | 4 ++ icu4c/source/common/unorm.cpp | 28 ++++++++++++ icu4c/source/common/uresbund.c | 44 +++++++++++++++++++ icu4c/source/common/uresdata.c | 4 ++ icu4c/source/common/uset.cpp | 4 ++ icu4c/source/common/ushape.c | 20 +++++++++ icu4c/source/common/ustrcase.c | 8 ++++ icu4c/source/common/ustrtrns.c | 9 +++- icu4c/source/common/utrie.c | 5 +++ icu4c/source/common/uvector.cpp | 9 ++++ icu4c/source/i18n/anytrans.cpp | 29 ++++++++++++- icu4c/source/i18n/calendar.cpp | 20 +++++++++ icu4c/source/i18n/caniter.cpp | 12 ++++++ icu4c/source/i18n/choicfmt.cpp | 5 +++ icu4c/source/i18n/coll.cpp | 5 +++ icu4c/source/i18n/dcfmtsym.cpp | 10 ++++- icu4c/source/i18n/decimfmt.cpp | 13 ++++++ icu4c/source/i18n/dtfmtsym.cpp | 20 +++++++++ icu4c/source/i18n/gregocal.cpp | 36 ++++++++++++++++ icu4c/source/i18n/msgfmt.cpp | 13 ++++++ icu4c/source/i18n/nfrs.cpp | 4 ++ icu4c/source/i18n/nfrule.cpp | 47 ++++++++++++++++++++ icu4c/source/i18n/numfmt.cpp | 4 ++ icu4c/source/i18n/rbt_data.cpp | 14 ++++++ icu4c/source/i18n/rbt_set.cpp | 12 ++++++ icu4c/source/i18n/simpletz.cpp | 28 ++++++++++++ icu4c/source/i18n/smpdtfmt.cpp | 8 ++++ icu4c/source/i18n/stsearch.cpp | 18 +++++++- icu4c/source/i18n/tblcoll.cpp | 4 ++ icu4c/source/i18n/timezone.cpp | 4 ++ icu4c/source/i18n/titletrn.cpp | 4 ++ icu4c/source/i18n/translit.cpp | 4 ++ icu4c/source/i18n/transreg.cpp | 25 +++++++++++ icu4c/source/i18n/ucol.cpp | 73 +++++++++++++++++++++++++++++++- icu4c/source/i18n/ucol_bld.cpp | 22 +++++++++- icu4c/source/i18n/ucol_cnt.cpp | 28 ++++++++++++ icu4c/source/i18n/ucol_elm.cpp | 72 +++++++++++++++++++++++++++++++ icu4c/source/i18n/ucol_tok.cpp | 19 ++++++++- icu4c/source/i18n/umsg.cpp | 73 ++++++++++++++++++++++++++------ 59 files changed, 1047 insertions(+), 40 deletions(-) diff --git a/icu4c/source/common/rbbinode.cpp b/icu4c/source/common/rbbinode.cpp index c04891b2a39..36fbc132127 100644 --- a/icu4c/source/common/rbbinode.cpp +++ b/icu4c/source/common/rbbinode.cpp @@ -249,6 +249,10 @@ void RBBINode::flattenSets() { // //------------------------------------------------------------------------- void RBBINode::findNodes(UVector *dest, RBBINode::NodeType kind, UErrorCode &status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } if (fType == kind) { dest->addElement(this, status); } diff --git a/icu4c/source/common/rbbisetb.cpp b/icu4c/source/common/rbbisetb.cpp index d783ec96ff5..3cb55619d5f 100644 --- a/icu4c/source/common/rbbisetb.cpp +++ b/icu4c/source/common/rbbisetb.cpp @@ -517,6 +517,10 @@ RangeDescriptor::~RangeDescriptor() { // //------------------------------------------------------------------------------------- void RangeDescriptor::split(UChar32 where, UErrorCode &status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } assert(where>fStartChar && where<=fEndChar); RangeDescriptor *nr = new RangeDescriptor(*this, status); /* test for NULL */ diff --git a/icu4c/source/common/rbbistbl.cpp b/icu4c/source/common/rbbistbl.cpp index 3956af4dd37..087880155a8 100644 --- a/icu4c/source/common/rbbistbl.cpp +++ b/icu4c/source/common/rbbistbl.cpp @@ -180,7 +180,10 @@ RBBINode *RBBISymbolTable::lookupNode(const UnicodeString &key) const{ // void RBBISymbolTable::addEntry (const UnicodeString &key, RBBINode *val, UErrorCode &err) { RBBISymbolTableEntry *e; - + /* test for buffer overflows */ + if (U_FAILURE(err)) { + return; + } e = (RBBISymbolTableEntry *)uhash_get(fHashTable, &key); if (e != NULL) { err = U_BRK_VARIABLE_REDFINITION; diff --git a/icu4c/source/common/rbbitblb.cpp b/icu4c/source/common/rbbitblb.cpp index e8a071d2ff1..f586e5c7f14 100644 --- a/icu4c/source/common/rbbitblb.cpp +++ b/icu4c/source/common/rbbitblb.cpp @@ -721,7 +721,16 @@ RBBIStateDescriptor::RBBIStateDescriptor(int lastInputSymbol, UErrorCode *fStatu fLookAhead = 0; fTagVal = 0; fPositions = NULL; + /* test for buffer overflows */ + if (U_FAILURE(*fStatus)) { + return; + } fDtran = new UVector(lastInputSymbol+1, *fStatus); + /* test for NULL */ + if (fDtran == NULL) { + *fStatus = U_MEMORY_ALLOCATION_ERROR; + return; + } fDtran->setSize(lastInputSymbol+1); // fDtran needs to be pre-sized. // It is indexed by input symbols, and will // hold the next state number for each diff --git a/icu4c/source/common/ubidiln.c b/icu4c/source/common/ubidiln.c index 6680cc60248..790014c7681 100644 --- a/icu4c/source/common/ubidiln.c +++ b/icu4c/source/common/ubidiln.c @@ -915,6 +915,10 @@ U_CAPI void U_EXPORT2 ubidi_getLogicalMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode) { UBiDiLevel *levels; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* ubidi_getLevels() checks all of its and our arguments */ if((levels=(UBiDiLevel *)ubidi_getLevels(pBiDi, pErrorCode))==NULL) { /* no op */ @@ -927,6 +931,10 @@ ubidi_getLogicalMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode) { U_CAPI void U_EXPORT2 ubidi_getVisualMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode) { + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* ubidi_countRuns() checks all of its and our arguments */ if(ubidi_countRuns(pBiDi, pErrorCode)<=0) { /* no op */ diff --git a/icu4c/source/common/uchar.c b/icu4c/source/common/uchar.c index 4fbc9e1dbd7..aa49fb0309b 100644 --- a/icu4c/source/common/uchar.c +++ b/icu4c/source/common/uchar.c @@ -836,6 +836,7 @@ uprv_getMaxValues() { } } + /* string casing ------------------------------------------------------------ */ /* @@ -1363,6 +1364,10 @@ u_internalStrToLower(UChar *dest, int32_t destCapacity, int32_t srcIndex, destIndex; UChar32 c; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } /* test early, once, if there is a data file */ if(!HAVE_DATA) { *pErrorCode=U_FILE_ACCESS_ERROR; @@ -1560,6 +1565,10 @@ u_internalStrToUpper(UChar *dest, int32_t destCapacity, int32_t srcIndex, destIndex; UChar32 c; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } /* test early, once, if there is a data file */ if(!HAVE_DATA) { *pErrorCode=U_FILE_ACCESS_ERROR; @@ -1845,6 +1854,10 @@ u_internalStrFoldCase(UChar *dest, int32_t destCapacity, int32_t srcIndex, destIndex; UChar32 c; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } /* test early, once, if there is a data file */ if(!HAVE_DATA) { *pErrorCode=U_FILE_ACCESS_ERROR; diff --git a/icu4c/source/common/ucmndata.c b/icu4c/source/common/ucmndata.c index 412f8ba78d7..01933c7291e 100644 --- a/icu4c/source/common/ucmndata.c +++ b/icu4c/source/common/ucmndata.c @@ -80,8 +80,11 @@ static const DataHeader * offsetTOCLookupFn(const UDataMemory *pData, const char *tocEntryName, UErrorCode *pErrorCode) { - const OffsetTOC *toc = (OffsetTOC *)pData->toc; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return NULL; + } if(toc!=NULL) { const char *base=(const char *)pData->toc; uint32_t start, limit, number; @@ -136,6 +139,10 @@ static uint32_t pointerTOCEntryCount(const UDataMemory *pData) { static const DataHeader *pointerTOCLookupFn(const UDataMemory *pData, const char *name, UErrorCode *pErrorCode) { + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return NULL; + } if(pData->toc!=NULL) { const PointerTOC *toc = (PointerTOC *)pData->toc; uint32_t start, limit, number; diff --git a/icu4c/source/common/ucnv_bld.c b/icu4c/source/common/ucnv_bld.c index f3988d16bdd..76b43c2c6ae 100644 --- a/icu4c/source/common/ucnv_bld.c +++ b/icu4c/source/common/ucnv_bld.c @@ -312,6 +312,11 @@ parseConverterOptions(const char *inName, char c; int32_t len = 0; + /* test for buffer overflows*/ + if (U_FAILURE (*err)){ + return; + } + /* copy the converter name itself to cnvName */ while((c=*inName)!=0 && c!=UCNV_OPTION_SEP_CHAR) { if (++len>=UCNV_MAX_CONVERTER_NAME_LENGTH) { diff --git a/icu4c/source/common/ucnv_cb.c b/icu4c/source/common/ucnv_cb.c index 9cbf25e6072..951ae326c7b 100644 --- a/icu4c/source/common/ucnv_cb.c +++ b/icu4c/source/common/ucnv_cb.c @@ -39,6 +39,11 @@ ucnv_cbFromUWriteBytes (UConverterFromUnicodeArgs *args, int8_t toerr; int32_t i; + /* test for buffer overflows*/ + if (U_FAILURE (*err)){ + return; + } + if((args->targetLimit - args->target) >= length) /* If the buffer fits.. */ { uprv_memcpy(args->target, source, length); diff --git a/icu4c/source/common/ucnv_u16.c b/icu4c/source/common/ucnv_u16.c index 1090fe66a9d..48cfbeb4497 100644 --- a/icu4c/source/common/ucnv_u16.c +++ b/icu4c/source/common/ucnv_u16.c @@ -35,6 +35,10 @@ _UTF16PEToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs, int32_t count; int32_t sourceIndex = 0; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } if(length <= 0 && cnv->toUnicodeStatus == 0) { /* no input, nothing to do */ return; @@ -118,6 +122,10 @@ _UTF16PEFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs, int32_t count; int32_t sourceIndex = 0; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } if(length <= 0 && cnv->fromUnicodeStatus == 0) { /* no input, nothing to do */ return; @@ -199,6 +207,10 @@ _UTF16OEToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs, int32_t count; int32_t sourceIndex = 0; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } if(length <= 0 && cnv->toUnicodeStatus == 0) { /* no input, nothing to do */ return; @@ -291,6 +303,10 @@ _UTF16OEFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs, int32_t count; int32_t sourceIndex = 0; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } if(length <= 0 && cnv->fromUnicodeStatus == 0) { /* no input, nothing to do */ return; diff --git a/icu4c/source/common/ucnv_u32.c b/icu4c/source/common/ucnv_u32.c index dbbcc79d6a3..ace3778e145 100644 --- a/icu4c/source/common/ucnv_u32.c +++ b/icu4c/source/common/ucnv_u32.c @@ -104,6 +104,10 @@ T_UConverter_toUnicode_UTF32_BE(UConverterToUnicodeArgs * args, unsigned char *toUBytes = args->converter->toUBytes; uint32_t ch, i; + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } /* UTF-8 returns here for only non-offset, this needs to change.*/ if (args->converter->toUnicodeStatus && myTarget < targetLimit) { @@ -214,6 +218,10 @@ T_UConverter_toUnicode_UTF32_BE_OFFSET_LOGIC(UConverterToUnicodeArgs * args, uint32_t ch, i; int32_t offsetNum = 0; + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } if (args->converter->toUnicodeStatus && myTarget < targetLimit) { i = args->converter->toULength; /* restore # of bytes consumed */ @@ -331,6 +339,10 @@ T_UConverter_fromUnicode_UTF32_BE(UConverterFromUnicodeArgs * args, temp[0] = 0; + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } if (args->converter->fromUnicodeStatus) { ch = args->converter->fromUnicodeStatus; @@ -406,6 +418,10 @@ T_UConverter_fromUnicode_UTF32_BE_OFFSET_LOGIC(UConverterFromUnicodeArgs * args, temp[0] = 0; + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } if (args->converter->fromUnicodeStatus) { ch = args->converter->fromUnicodeStatus; @@ -585,6 +601,10 @@ T_UConverter_toUnicode_UTF32_LE(UConverterToUnicodeArgs * args, unsigned char *toUBytes = args->converter->toUBytes; uint32_t ch, i; + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } /* UTF-8 returns here for only non-offset, this needs to change.*/ if (args->converter->toUnicodeStatus && myTarget < targetLimit) { @@ -696,6 +716,10 @@ T_UConverter_toUnicode_UTF32_LE_OFFSET_LOGIC(UConverterToUnicodeArgs * args, uint32_t ch, i; int32_t offsetNum = 0; + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } /* UTF-8 returns here for only non-offset, this needs to change.*/ if (args->converter->toUnicodeStatus && myTarget < targetLimit) { @@ -815,6 +839,10 @@ T_UConverter_fromUnicode_UTF32_LE(UConverterFromUnicodeArgs * args, temp[3] = 0; + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } if (args->converter->fromUnicodeStatus) { ch = args->converter->fromUnicodeStatus; @@ -890,6 +918,10 @@ T_UConverter_fromUnicode_UTF32_LE_OFFSET_LOGIC(UConverterFromUnicodeArgs * args, temp[3] = 0; + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } if (args->converter->fromUnicodeStatus) { ch = args->converter->fromUnicodeStatus; @@ -1134,6 +1166,10 @@ _UTF32ToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs, */ offsetDelta=0; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } while(sourcefromUnicodeStatus=(options&0xf)<<28; _UTF7Reset(cnv, UCNV_RESET_BOTH); @@ -224,7 +228,10 @@ _UTF7ToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs, int32_t sourceIndex, nextSourceIndex; uint8_t b; - + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* set up the local pointers */ cnv=pArgs->converter; @@ -519,6 +526,10 @@ _UTF7FromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs, int8_t base64Counter; UBool inDirectMode; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* set up the local pointers */ cnv=pArgs->converter; diff --git a/icu4c/source/common/ucnv_u8.c b/icu4c/source/common/ucnv_u8.c index 7ab247cd0b2..8b3ee1460ec 100644 --- a/icu4c/source/common/ucnv_u8.c +++ b/icu4c/source/common/ucnv_u8.c @@ -156,7 +156,11 @@ U_CFUNC void T_UConverter_toUnicode_UTF8 (UConverterToUnicodeArgs * args, UBool isCESU8 = (UBool)(args->converter->sharedData == &_CESU8Data); uint32_t ch, ch2 = 0; int32_t i, inBytes; - + + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } /* Restore size of current sequence */ start: if (args->converter->toUnicodeStatus && myTarget < targetLimit) @@ -307,6 +311,10 @@ U_CFUNC void T_UConverter_toUnicode_UTF8_OFFSETS_LOGIC (UConverterToUnicodeArgs uint32_t ch, ch2 = 0; int32_t i, inBytes; + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } /* Restore size of current sequence */ start: if (args->converter->toUnicodeStatus && myTarget < targetLimit) @@ -325,7 +333,10 @@ start: if (ch < 0x80) /* Simple case */ { *(myTarget++) = (UChar) ch; - *(myOffsets++) = offsetNum++; + /* test for buffer overflows */ + if (myOffsets != NULL) { + *(myOffsets++) = offsetNum++; + } } else { @@ -390,7 +401,10 @@ morebytes: { /* fits in 16 bits */ *(myTarget++) = (UChar) ch; - *(myOffsets++) = offsetNum; + /* test for buffer overflows */ + if(myOffsets != NULL) { + *(myOffsets++) = offsetNum; + } } else { @@ -402,7 +416,10 @@ morebytes: if (myTarget < targetLimit) { *(myTarget++) = (UChar)ch; - *(myOffsets++) = offsetNum; + /* test for buffer overflows */ + if(myOffsets != NULL) { + *(myOffsets++) = offsetNum; + } } else { @@ -462,6 +479,10 @@ U_CFUNC void T_UConverter_fromUnicode_UTF8 (UConverterFromUnicodeArgs * args, int16_t indexToWrite; char temp[4]; + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } if (cnv->fromUSurrogateLead && myTarget < targetLimit) { ch = cnv->fromUSurrogateLead; @@ -627,6 +648,10 @@ U_CFUNC void T_UConverter_fromUnicode_UTF8_OFFSETS_LOGIC (UConverterFromUnicodeA int16_t indexToWrite; char temp[4]; + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } if (cnv->fromUSurrogateLead && myTarget < targetLimit) { ch = cnv->fromUSurrogateLead; @@ -644,16 +669,25 @@ U_CFUNC void T_UConverter_fromUnicode_UTF8_OFFSETS_LOGIC (UConverterFromUnicodeA if (ch < 0x80) /* Single byte */ { - *(myOffsets++) = offsetNum++; + /* test for buffer overflows */ + if(myOffsets != NULL) { + *(myOffsets++) = offsetNum++; + } *(myTarget++) = (char) ch; } else if (ch < 0x800) /* Double byte */ { - *(myOffsets++) = offsetNum; + /* test for buffer overflows */ + if(myOffsets != NULL) { + *(myOffsets++) = offsetNum; + } *(myTarget++) = (char) ((ch >> 6) | 0xc0); if (myTarget < targetLimit) { - *(myOffsets++) = offsetNum++; + /* test for buffer overflows */ + if(myOffsets != NULL) { + *(myOffsets++) = offsetNum++; + } *(myTarget++) = (char) ((ch & 0x3f) | 0x80); } else @@ -768,7 +802,10 @@ lowsurrogate: { if (myTarget < targetLimit) { - *(myOffsets++) = offsetNum; + /* test for buffer overflows */ + if(myOffsets != NULL) { + *(myOffsets++) = offsetNum; + } *(myTarget++) = temp[indexToWrite]; } else diff --git a/icu4c/source/common/ucnvhz.c b/icu4c/source/common/ucnvhz.c index 747d5ac82f6..a05e9747ef7 100644 --- a/icu4c/source/common/ucnvhz.c +++ b/icu4c/source/common/ucnvhz.c @@ -66,6 +66,10 @@ _HZOpen(UConverter *cnv, const char *name,const char *locale,uint32_t options, U cnv->fromUnicodeStatus= 0; cnv->mode=0; cnv->fromUSurrogateLead=0x0000; + /* test for buffer overflows */ + if (U_FAILURE(*errorCode)) { + return; + } cnv->extraInfo = uprv_malloc (sizeof (UConverterDataHZ)); if(cnv->extraInfo != NULL){ ((UConverterDataHZ*)cnv->extraInfo)->gbConverter = ucnv_open("ibm-1386",errorCode); @@ -145,7 +149,10 @@ UConverter_toUnicode_HZ_OFFSETS_LOGIC(UConverterToUnicodeArgs *args, UChar32 targetUniChar = 0x0000; UChar mySourceChar = 0x0000; UConverterDataHZ* myData=(UConverterDataHZ*)(args->converter->extraInfo); - + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } if ((args->converter == NULL) || (args->targetLimit < args->target) || (args->sourceLimit < args->source)){ *err = U_ILLEGAL_ARGUMENT_ERROR; return; @@ -357,7 +364,11 @@ UConverter_fromUnicode_HZ_OFFSETS_LOGIC (UConverterFromUnicodeArgs * args, UBool isEscapeAppended =FALSE; int len =0; const char* escSeq=NULL; - + + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } if ((args->converter == NULL) || (args->targetLimit < args->target) || (args->sourceLimit < args->source)){ *err = U_ILLEGAL_ARGUMENT_ERROR; return; @@ -578,7 +589,11 @@ _HZ_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorCode *e char *p; char buffer[4]; p = buffer; - + + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } if( convData->isTargetUCharDBCS){ *p++= UCNV_TILDE; *p++= UCNV_CLOSE_BRACE; diff --git a/icu4c/source/common/ucnvisci.c b/icu4c/source/common/ucnvisci.c index 6a5fcc15233..7d85a2b876b 100644 --- a/icu4c/source/common/ucnvisci.c +++ b/icu4c/source/common/ucnvisci.c @@ -130,6 +130,10 @@ static const uint16_t lookupInitialData[][3]={ static void _ISCIIOpen(UConverter *cnv, const char *name,const char *locale,uint32_t options, UErrorCode *errorCode){ + /* test for buffer overflows */ + if (U_FAILURE(*errorCode)) { + return; + } cnv->extraInfo = uprv_malloc (sizeof (UConverterDataISCII)); if(cnv->extraInfo != NULL) { @@ -810,6 +814,10 @@ UConverter_fromUnicode_ISCII_OFFSETS_LOGIC (UConverterFromUnicodeArgs * args, uint16_t range = 0; UBool deltaChanged = FALSE; + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } if ((args->converter == NULL) || (args->targetLimit < args->target) || (args->sourceLimit < args->source)){ *err = U_ILLEGAL_ARGUMENT_ERROR; return; @@ -1150,6 +1158,10 @@ UConverter_toUnicode_ISCII_OFFSETS_LOGIC(UConverterToUnicodeArgs *args, UChar32* toUnicodeStatus=NULL; UChar* contextCharToUnicode = NULL; + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } if ((args->converter == NULL) || (target < args->target) || (source < args->source)){ *err = U_ILLEGAL_ARGUMENT_ERROR; return; @@ -1235,6 +1247,10 @@ UConverter_toUnicode_ISCII_OFFSETS_LOGIC(UConverterToUnicodeArgs *args, *contextCharToUnicode=NO_CHAR_MARKER; } + /* test for buffer overflows */ + if (U_FAILURE(*err)) { + return; + } /* look at the pre-context and perform special processing */ switch(sourceChar){ case ISCII_INV: diff --git a/icu4c/source/common/ucnvlat1.c b/icu4c/source/common/ucnvlat1.c index e17a8180488..52f9888754d 100644 --- a/icu4c/source/common/ucnvlat1.c +++ b/icu4c/source/common/ucnvlat1.c @@ -36,6 +36,10 @@ _Latin1ToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs, int32_t sourceIndex; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* set up the local pointers */ source=(const uint8_t *)pArgs->source; target=pArgs->target; @@ -157,6 +161,10 @@ _Latin1FromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs, UConverterCallbackReason reason; int32_t i; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* set up the local pointers */ cnv=pArgs->converter; source=pArgs->source; @@ -474,6 +482,10 @@ _ASCIIToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs, int32_t sourceIndex; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* set up the local pointers */ source=(const uint8_t *)pArgs->source; sourceLimit=(const uint8_t *)pArgs->sourceLimit; diff --git a/icu4c/source/common/ucnvmbcs.c b/icu4c/source/common/ucnvmbcs.c index c851d475309..41ce01552df 100644 --- a/icu4c/source/common/ucnvmbcs.c +++ b/icu4c/source/common/ucnvmbcs.c @@ -362,6 +362,10 @@ _MBCSLoad(UConverterSharedData *sharedData, UConverterMBCSTable *mbcsTable=&sharedData->table->mbcs; _MBCSHeader *header=(_MBCSHeader *)raw; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } if(header->version[0]!=4) { *pErrorCode=U_INVALID_TABLE_FORMAT; return; @@ -429,6 +433,10 @@ _MBCSOpen(UConverter *cnv, const char *locale, uint32_t options, UErrorCode *pErrorCode) { + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } _MBCSReset(cnv, UCNV_RESET_BOTH); if(uprv_strstr(name, "gb18030")!=NULL || uprv_strstr(name, "GB18030")!=NULL) { /* set a flag for GB 18030 mode, which changes the callback behavior */ @@ -489,7 +497,10 @@ _MBCSToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs, UChar c; uint8_t action; UConverterCallbackReason reason; - + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* use optimized function if possible */ cnv=pArgs->converter; if(cnv->sharedData->table->mbcs.countStates==1) { @@ -790,6 +801,10 @@ _MBCSSingleToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs, uint8_t action; UConverterCallbackReason reason; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* set up the local pointers */ cnv=pArgs->converter; source=(const uint8_t *)pArgs->source; @@ -967,6 +982,10 @@ _MBCSSingleToBMPWithOffsets(UConverterToUnicodeArgs *pArgs, uint8_t action; UConverterCallbackReason reason; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* set up the local pointers */ cnv=pArgs->converter; source=(const uint8_t *)pArgs->source; @@ -1204,6 +1223,10 @@ _MBCSGetNextUChar(UConverterToUnicodeArgs *pArgs, uint8_t action; UConverterCallbackReason reason; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0xffff; + } /* use optimized function if possible */ cnv=pArgs->converter; if(cnv->sharedData->table->mbcs.unicodeMask&UCNV_HAS_SURROGATES) { @@ -1425,6 +1448,10 @@ _MBCSSingleGetNextUChar(UConverterToUnicodeArgs *pArgs, uint8_t action; UConverterCallbackReason reason; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0xffff; + } /* set up the local pointers */ cnv=pArgs->converter; source=(const uint8_t *)pArgs->source; @@ -1721,6 +1748,10 @@ _MBCSFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs, int32_t length, prevLength; uint8_t unicodeMask; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* use optimized function if possible */ cnv=pArgs->converter; outputType=cnv->sharedData->table->mbcs.outputType; @@ -2207,6 +2238,10 @@ _MBCSDoubleFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs, int32_t length, prevLength; uint8_t unicodeMask; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* use optimized function if possible */ cnv=pArgs->converter; unicodeMask=cnv->sharedData->table->mbcs.unicodeMask; @@ -2459,7 +2494,11 @@ _MBCSSingleFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs, UConverterCallbackReason reason; uint16_t value, minValue; UBool hasSupplementary; - + + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* set up the local pointers */ cnv=pArgs->converter; source=pArgs->source; @@ -2672,6 +2711,10 @@ _MBCSSingleFromBMPWithOffsets(UConverterFromUnicodeArgs *pArgs, UConverterCallbackReason reason; uint16_t value, minValue; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* set up the local pointers */ cnv=pArgs->converter; source=pArgs->source; @@ -3092,6 +3135,10 @@ _MBCSGetStarters(const UConverter* cnv, const int32_t *state0=cnv->sharedData->table->mbcs.stateTable[0]; int i; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } for(i=0; i<256; ++i) { /* all bytes that cause a state transition from state 0 are lead bytes */ starters[i]= (UBool)MBCS_ENTRY_IS_TRANSITION(state0[i]); @@ -3116,6 +3163,10 @@ _MBCSWriteSub(UConverterFromUnicodeArgs *pArgs, char buffer[4]; int32_t length; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* first, select between subChar and subChar1 */ if(cnv->subChar1!=0 && cnv->invalidUCharBuffer[0]<=0xff) { /* select subChar1 if it is set (not 0) and the unmappable Unicode code point is up to U+00ff (IBM MBCS behavior) */ @@ -3223,6 +3274,10 @@ fromUCallback(UConverter *cnv, UConverterCallbackReason reason, UErrorCode *pErrorCode) { int32_t i; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } if(cnv->extraInfo==gb18030Ranges && reason==UCNV_UNASSIGNED) { const uint32_t *range; @@ -3270,6 +3325,10 @@ toUCallback(UConverter *cnv, UConverterCallbackReason reason, UErrorCode *pErrorCode) { int32_t i; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } if(cnv->extraInfo==gb18030Ranges && reason==UCNV_UNASSIGNED && length==4) { const uint32_t *range; uint32_t linear; diff --git a/icu4c/source/common/ucnvscsu.c b/icu4c/source/common/ucnvscsu.c index 4b99a2bd679..7619e619e25 100644 --- a/icu4c/source/common/ucnvscsu.c +++ b/icu4c/source/common/ucnvscsu.c @@ -191,6 +191,10 @@ _SCSUOpen(UConverter *cnv, const char *locale, uint32_t options, UErrorCode *pErrorCode) { + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } cnv->extraInfo=uprv_malloc(sizeof(SCSUData)); if(cnv->extraInfo!=NULL) { if(locale!=NULL && locale[0]=='j' && locale[1]=='a' && (locale[2]==0 || locale[2]=='_')) { @@ -234,7 +238,10 @@ _SCSUToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs, int32_t sourceIndex, nextSourceIndex; uint8_t b; - + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* set up the local pointers */ cnv=pArgs->converter; scsu=(SCSUData *)cnv->extraInfo; @@ -625,7 +632,10 @@ _SCSUToUnicode(UConverterToUnicodeArgs *pArgs, int8_t quoteWindow, dynamicWindow; uint8_t b; - + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* set up the local pointers */ cnv=pArgs->converter; scsu=(SCSUData *)cnv->extraInfo; @@ -1104,6 +1114,10 @@ _SCSUFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs, int code; int8_t window; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* set up the local pointers */ cnv=pArgs->converter; scsu=(SCSUData *)cnv->extraInfo; @@ -1652,6 +1666,10 @@ _SCSUFromUnicode(UConverterFromUnicodeArgs *pArgs, int code; int8_t window; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } /* set up the local pointers */ cnv=pArgs->converter; scsu=(SCSUData *)cnv->extraInfo; diff --git a/icu4c/source/common/udata.c b/icu4c/source/common/udata.c index 92ad1217db1..80ee03846c8 100644 --- a/icu4c/source/common/udata.c +++ b/icu4c/source/common/udata.c @@ -493,6 +493,10 @@ static UBool extendICUData(UDataMemory *failedData, UErrorCode *pErr) UDataMemory *pData; UDataMemory copyPData; + /* test for buffer overflows */ + if (U_FAILURE(*pErr)) { + return FALSE; + } if (failedData->vFuncs->NumEntries(failedData) > MAX_STUB_ENTRIES) { /* Not the stub. We can't extend. */ return FALSE; @@ -696,6 +700,10 @@ doOpenChoice(const char *path, const char *type, const char *name, UErrorCode errorCode=U_ZERO_ERROR; UBool isICUData= (UBool)(path==NULL); + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return NULL; + } /* Make up a full mame by appending the type to the supplied * name, assuming that a type was supplied. diff --git a/icu4c/source/common/uloc.c b/icu4c/source/common/uloc.c index 02ad115007c..04b04eda441 100644 --- a/icu4c/source/common/uloc.c +++ b/icu4c/source/common/uloc.c @@ -865,6 +865,10 @@ _res_getTableItemWithFallback(const char *path, const char *locale, const char *defaultLocale; UBool lookedAtDefault; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return NULL; + } *pMainRB=NULL; lookedAtDefault=FALSE; defaultLocale=uloc_getDefault(); diff --git a/icu4c/source/common/unistr.cpp b/icu4c/source/common/unistr.cpp index f807343cf56..4bd471ccddc 100644 --- a/icu4c/source/common/unistr.cpp +++ b/icu4c/source/common/unistr.cpp @@ -680,6 +680,10 @@ UnicodeString::doCaseCompare(int32_t start, UErrorCode errorCode=U_ZERO_ERROR; int32_t result=unorm_cmpEquivFold(chars, length, srcChars, srcLength, options|U_COMPARE_IGNORE_CASE, &errorCode); + /* test for buffer overflows */ + if (U_FAILURE(errorCode)) { + return 0; + } if(result!=0) { return (int8_t)(result >> 24 | 1); } diff --git a/icu4c/source/common/unorm.cpp b/icu4c/source/common/unorm.cpp index db9240a042c..57b27ee28b4 100644 --- a/icu4c/source/common/unorm.cpp +++ b/icu4c/source/common/unorm.cpp @@ -1464,6 +1464,10 @@ unorm_decompose(UChar *dest, int32_t destCapacity, int32_t destIndex; uint8_t trailCC; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } if(!_haveData(*pErrorCode)) { return 0; } @@ -1647,6 +1651,10 @@ unorm_makeFCD(UChar *dest, int32_t destCapacity, uint16_t fcd16; int16_t prevCC, cc; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } if(!_haveData(*pErrorCode)) { return 0; } @@ -2211,6 +2219,10 @@ _composePart(UChar *stackBuffer, UChar *&buffer, int32_t &bufferCapacity, int32_ UChar minNoMaybe; uint8_t trailCC; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } decompQCMask=(qcMask<<2)&0xf; /* decomposition quick check mask */ if(!(decompQCMask&_NORM_QC_NFKD)) { @@ -2583,6 +2595,10 @@ unorm_compose(UChar *dest, int32_t destCapacity, UErrorCode *pErrorCode) { int32_t destIndex; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } if(!_haveData(*pErrorCode)) { return 0; } @@ -2786,6 +2802,10 @@ _findPreviousIterationBoundary(UCharIterator &src, UChar c, c2; UBool isBoundary; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } /* initialize */ stackBuffer=buffer; startIndex=bufferCapacity; /* fill the buffer from the end backwards */ @@ -3023,6 +3043,10 @@ _findNextIterationBoundary(UCharIterator &src, int32_t bufferIndex; UChar c, c2; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } if(!src.hasNext(&src)) { return 0; } @@ -3463,6 +3487,10 @@ unorm_cmpEquivFold(const UChar *s1, int32_t length1, // current code units, and code points for lookups int32_t c1, c2, cp1, cp2; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } // no argument error checking because this itself is not an API // assume that at least one of the options _COMPARE_EQUIV and U_COMPARE_IGNORE_CASE is set diff --git a/icu4c/source/common/uresbund.c b/icu4c/source/common/uresbund.c index 61f48f103a1..abac5d5665f 100644 --- a/icu4c/source/common/uresbund.c +++ b/icu4c/source/common/uresbund.c @@ -102,6 +102,10 @@ static const ResourceData *getFallbackData(const UResourceBundle* resBundle, con int32_t indexR = -1; int32_t i = 0; *res = RES_BOGUS; + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } if(resB != NULL) { if(resB->fBogus == U_ZERO_ERROR) { /* if this resource is real, */ *res = res_getTableItemByKey(&(resB->fData), resB->fData.rootRes, &indexR, resTag); /* try to get data from there */ @@ -139,6 +143,10 @@ static const ResourceData *getFallbackData(const UResourceBundle* resBundle, con /** INTERNAL: Initializes the cache for resources */ static void initCache(UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } if(cache == NULL) { UHashtable *newCache = uhash_open(hashEntry, compareEntries, status); if (U_FAILURE(*status)) { @@ -223,6 +231,10 @@ UBool ures_cleanup(void) /** INTERNAL: sets the name (locale) of the resource bundle to given name */ static void setEntryName(UResourceDataEntry *res, char *name, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } if(res->fName != NULL) { uprv_free(res->fName); } @@ -369,6 +381,10 @@ static UResourceDataEntry *findFirstExisting(const char* path, char* name, UBool const char *defaultLoc = uloc_getDefault(); UErrorCode intStatus = U_ZERO_ERROR; *hasChopped = TRUE; /* we're starting with a fresh name */ + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } while(*hasChopped && !hasRealData) { r = init_entry(name, path, &intStatus); @@ -412,6 +428,10 @@ static UResourceDataEntry *entryOpen(const char* path, const char* localeID, UEr } initCache(status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } uprv_strcpy(name, localeID); @@ -426,6 +446,10 @@ static UResourceDataEntry *entryOpen(const char* path, const char* localeID, UEr while (hasChopped && !isRoot && t1->fParent == NULL) { /* insert regular parents */ t2 = init_entry(name, r->fPath, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } t1->fParent = t2; t1 = t2; hasChopped = chopLocale(name); @@ -446,6 +470,10 @@ static UResourceDataEntry *entryOpen(const char* path, const char* localeID, UEr while (hasChopped && t1->fParent == NULL) { /* insert chopped defaults */ t2 = init_entry(name, r->fPath, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } t1->fParent = t2; t1 = t2; hasChopped = chopLocale(name); @@ -468,6 +496,10 @@ static UResourceDataEntry *entryOpen(const char* path, const char* localeID, UEr } else if(!isRoot && uprv_strcmp(t1->fName, kRootLocaleName) != 0 && t1->fParent == NULL) { /* insert root locale */ t2 = init_entry(kRootLocaleName, r->fPath, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } if(!hasRealData) { r->fBogus = U_USING_DEFAULT_ERROR; } @@ -548,6 +580,10 @@ static UResourceBundle *init_resb_result(const ResourceData *rdata, Resource r, /* first, open the bundle with real data */ UResourceBundle *main = ures_openDirect(path, locale, status); UResourceBundle *result = NULL; + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } if(keyPath == NULL) { /* no key path. This means that we are going to @@ -580,6 +616,10 @@ static UResourceBundle *init_resb_result(const ResourceData *rdata, Resource r, } if(r != RES_BOGUS) { result = init_resb_result(&(main->fResData), r, key, -1, main->fData, parent, noAlias+1, resB, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } } else { *status = U_MISSING_RESOURCE_ERROR; result = resB; @@ -601,6 +641,10 @@ static UResourceBundle *init_resb_result(const ResourceData *rdata, Resource r, break; } resB = init_resb_result(&(result->fResData), r, key, -1, result->fData, parent, noAlias+1, resB, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } result = resB; } } diff --git a/icu4c/source/common/uresdata.c b/icu4c/source/common/uresdata.c index 1cb2098836f..cba14d33fcf 100644 --- a/icu4c/source/common/uresdata.c +++ b/icu4c/source/common/uresdata.c @@ -199,6 +199,10 @@ isAcceptable(void *context, U_CFUNC UBool res_load(ResourceData *pResData, const char *path, const char *name, UErrorCode *errorCode) { + /* test for buffer overflows */ + if (U_FAILURE(*errorCode)) { + return FALSE; + } /* load the ResourceBundle file */ pResData->data=udata_openChoice(path, "res", name, isAcceptable, NULL, errorCode); if(U_FAILURE(*errorCode)) { diff --git a/icu4c/source/common/uset.cpp b/icu4c/source/common/uset.cpp index 816b0e4c832..00cd6fd31c4 100644 --- a/icu4c/source/common/uset.cpp +++ b/icu4c/source/common/uset.cpp @@ -35,6 +35,10 @@ uset_open(UChar32 start, UChar32 end) { U_CAPI USet* U_EXPORT2 uset_openPattern(const UChar* pattern, int32_t patternLength, UErrorCode* ec) { + /* test for buffer overflows */ + if (U_FAILURE(*ec)) { + return 0; + } UnicodeString pat(patternLength==-1, pattern, patternLength); UnicodeSet* set = new UnicodeSet(pat, *ec); /* test for NULL */ diff --git a/icu4c/source/common/ushape.c b/icu4c/source/common/ushape.c index d1d7fd0e863..b84216203f7 100644 --- a/icu4c/source/common/ushape.c +++ b/icu4c/source/common/ushape.c @@ -497,6 +497,10 @@ removeLamAlefSpaces(UChar *dest, int32_t sourceLength, int32_t i = 0, j = 0; int32_t count = 0; UChar *tempbuffer=NULL; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } switch(options&U_SHAPE_LENGTH_MASK) { case U_SHAPE_LENGTH_GROW_SHRINK : @@ -636,6 +640,10 @@ expandLamAlef(UChar *dest, int32_t sourceLength, int32_t inpsize = sourceLength; UChar lamalefChar; UChar *tempbuffer=NULL; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } switch(options&U_SHAPE_LENGTH_MASK) { @@ -801,6 +809,10 @@ shapeUnicode(UChar *dest, int32_t sourceLength, int32_t lamalef_found = 0; UChar prevLink = 0, lastLink = 0, currLink, nextLink = 0; UChar wLamalef; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } /* * Converts the input buffer from FExx Range into 06xx Range @@ -934,6 +946,10 @@ deShapeUnicode(UChar *dest, int32_t sourceLength, UErrorCode *pErrorCode) { int32_t i = 0; int32_t lamalef_found = 0; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } /* *This for loop changes the buffer from the Unicode FE range to @@ -1059,6 +1075,10 @@ u_shapeArabic(const UChar *source, int32_t sourceLength, outputSize = 0; break; } + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } if((options&U_SHAPE_TEXT_DIRECTION_MASK) == U_SHAPE_TEXT_DIRECTION_LOGICAL) { countSpaces(tempbuffer,outputSize,options,&spacesCountl,&spacesCountr); diff --git a/icu4c/source/common/ustrcase.c b/icu4c/source/common/ustrcase.c index fcb8fe342e1..df3cf65a4b4 100644 --- a/icu4c/source/common/ustrcase.c +++ b/icu4c/source/common/ustrcase.c @@ -44,6 +44,10 @@ u_internalStrToTitle(UChar *dest, int32_t destCapacity, int32_t prev, index, destIndex, length; UBool isFirstIndex; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } /* set up local variables */ uiter_setString(&iter, src, srcLength); destIndex=0; @@ -80,6 +84,10 @@ u_internalStrToTitle(UChar *dest, int32_t destCapacity, } destIndex+=length; } + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return 0; + } if(index>=srcLength) { break; diff --git a/icu4c/source/common/ustrtrns.c b/icu4c/source/common/ustrtrns.c index 893d174412e..f2a78a8169b 100644 --- a/icu4c/source/common/ustrtrns.c +++ b/icu4c/source/common/ustrtrns.c @@ -645,6 +645,10 @@ _strFromWCS( UChar *dest, const wchar_t* pSrc = src; const wchar_t* pSrcLimit = NULL; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return NULL; + } if(srcLength ==-1){ /* if the wchar_t source is null terminated we can safely * assume that there are no embedded nulls, this is a fast @@ -783,7 +787,10 @@ _strFromWCS( UChar *dest, /* convert to stack buffer*/ ucnv_toUnicode(conv,&pTarget,pTargetLimit,(const char**)&pCSrc,pCSrcLimit,NULL,(UBool)(pCSrc==pCSrcLimit),pErrorCode); - + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + goto cleanup; + } /* increment count to number written to stack */ count+= pTarget - target; diff --git a/icu4c/source/common/utrie.c b/icu4c/source/common/utrie.c index d4237382cc6..1525f1df834 100644 --- a/icu4c/source/common/utrie.c +++ b/icu4c/source/common/utrie.c @@ -379,6 +379,11 @@ utrie_fold(UNewTrie *trie, UNewTrieGetFoldedValue *getFoldedValue, UErrorCode *p UChar32 c; int32_t indexLength, block; + /* test for buffer overflows */ + if (U_FAILURE(*pErrorCode)) { + return; + } + index=trie->index; /* copy the lead surrogate indexes into a temporary array */ diff --git a/icu4c/source/common/uvector.cpp b/icu4c/source/common/uvector.cpp index 87a3e13da76..d5268960fd3 100644 --- a/icu4c/source/common/uvector.cpp +++ b/icu4c/source/common/uvector.cpp @@ -58,6 +58,10 @@ UVector::UVector(UObjectDeleter d, UKeyComparator c, int32_t initialCapacity, UE } void UVector::_init(int32_t initialCapacity, UErrorCode &status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } // Fix bogus initialCapacity values; avoid malloc(0) if (initialCapacity < 1) { initialCapacity = DEFUALT_CAPACITY; @@ -290,6 +294,11 @@ int32_t UVector::indexOf(UHashTok key, int32_t startIndex) const { } UBool UVector::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return FALSE; + } + if (capacity >= minimumCapacity) { return TRUE; } else { diff --git a/icu4c/source/i18n/anytrans.cpp b/icu4c/source/i18n/anytrans.cpp index 4ce4e90d832..529c5171d68 100644 --- a/icu4c/source/i18n/anytrans.cpp +++ b/icu4c/source/i18n/anytrans.cpp @@ -4,7 +4,7 @@ * and others. All Rights Reserved. ***************************************************************** * $Source: /xsrl/Nsvn/icu/icu/source/i18n/anytrans.cpp,v $ -* $Revision: 1.7 $ +* $Revision: 1.8 $ ***************************************************************** * Date Name Description * 06/06/2002 aliu Creation. @@ -161,6 +161,11 @@ UBool ScriptRunIterator::next() { } } + /* test for buffer overflows */ + if (U_FAILURE(ec)) { + return FALSE; + } + // Move limit ahead to include COMMON, INHERITED, and characters // of the current script. while (limit < textLimit) { @@ -176,6 +181,11 @@ UBool ScriptRunIterator::next() { ++limit; } + /* test for buffer overflows */ + if (U_FAILURE(ec)) { + return FALSE; + } + // Return TRUE even if the entire text is COMMON / INHERITED, in // which case scriptCode will be USCRIPT_INVALID_CODE. return TRUE; @@ -200,6 +210,12 @@ AnyTransliterator::AnyTransliterator(const UnicodeString& id, targetScript(theTargetScript) { cache = uhash_open(uhash_hashLong, uhash_compareLong, &ec); + + /* test for buffer overflows */ + if (U_FAILURE(ec)) { + return; + } + uhash_setValueDeleter(cache, _deleteTransliterator); target = theTarget; @@ -223,6 +239,12 @@ AnyTransliterator::AnyTransliterator(const AnyTransliterator& o) : // Don't copy the cache contents UErrorCode ec = U_ZERO_ERROR; cache = uhash_open(uhash_hashLong, uhash_compareLong, &ec); + + /* test for buffer overflows */ + if (U_FAILURE(ec)) { + return; + } + uhash_setValueDeleter(cache, _deleteTransliterator); } @@ -309,6 +331,11 @@ Transliterator* AnyTransliterator::getTransliterator(UScriptCode source) const { if (t != NULL) { uhash_iput(cache, (int32_t) source, t, &ec); + /* test for buffer overflows */ + if (U_FAILURE(ec)) { + delete t; + t = NULL; + } } } diff --git a/icu4c/source/i18n/calendar.cpp b/icu4c/source/i18n/calendar.cpp index f0b57722416..1a6009a8a90 100644 --- a/icu4c/source/i18n/calendar.cpp +++ b/icu4c/source/i18n/calendar.cpp @@ -96,6 +96,10 @@ Calendar::Calendar(UErrorCode& success) fLenient(TRUE), fZone(0) { + /* test for buffer overflows */ + if (U_FAILURE(success)) { + return; + } clear(); fZone = TimeZone::createDefault(); setWeekCountData(Locale::getDefault(), success); @@ -113,6 +117,10 @@ Calendar::Calendar(TimeZone* zone, const Locale& aLocale, UErrorCode& success) fLenient(TRUE), fZone(0) { + /* test for buffer overflows */ + if (U_FAILURE(success)) { + return; + } if(zone == 0) { success = U_ILLEGAL_ARGUMENT_ERROR; return; @@ -136,6 +144,10 @@ Calendar::Calendar(const TimeZone& zone, const Locale& aLocale, UErrorCode& succ fLenient(TRUE), fZone(0) { + /* test for buffer overflows */ + if (U_FAILURE(success)) { + return; + } clear(); fZone = zone.clone(); setWeekCountData(aLocale, success); @@ -719,6 +731,10 @@ Calendar::getMinimalDaysInFirstWeek() const int32_t Calendar::getActualMinimum(EDateFields field, UErrorCode& status) const { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return 0; + } int32_t fieldValue = getGreatestMinimum(field); int32_t endValue = getMinimum(field); @@ -762,6 +778,10 @@ Calendar::getActualMinimum(EDateFields field, UErrorCode& status) const int32_t Calendar::getActualMaximum(EDateFields field, UErrorCode& status) const { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return 0; + } int32_t fieldValue = getLeastMaximum(field); int32_t endValue = getMaximum(field); diff --git a/icu4c/source/i18n/caniter.cpp b/icu4c/source/i18n/caniter.cpp index 27438422e08..4b92b4a7f78 100644 --- a/icu4c/source/i18n/caniter.cpp +++ b/icu4c/source/i18n/caniter.cpp @@ -380,6 +380,10 @@ void CanonicalIterator::permute(UnicodeString &source, UBool skipZeros, Hashtabl UnicodeString* CanonicalIterator::getEquivalents(const UnicodeString &segment, int32_t &result_len, UErrorCode &status) { //private String[] getEquivalents(String segment) + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return 0; + } Hashtable *result = new Hashtable(FALSE, status); /* test for NULL */ if (result == 0) { @@ -485,6 +489,10 @@ UnicodeString* CanonicalIterator::getEquivalents(const UnicodeString &segment, i Hashtable *CanonicalIterator::getEquivalents2(const UChar *segment, int32_t segLen, UErrorCode &status) { //Hashtable *CanonicalIterator::getEquivalents2(const UnicodeString &segment, int32_t segLen, UErrorCode &status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return 0; + } Hashtable *result = new Hashtable(FALSE, status); /* test for NULL */ if (result == 0) { @@ -564,6 +572,10 @@ Hashtable *CanonicalIterator::extract(UChar32 comp, const UChar *segment, int32_ //if (PROGRESS) printf(" extract: %s, ", UToS(Tr(UnicodeString(comp)))); //if (PROGRESS) printf("%s, %i\n", UToS(Tr(segment)), segmentPos); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return 0; + } const int32_t bufSize = 256; int32_t bufLen = 0; UChar temp[bufSize]; diff --git a/icu4c/source/i18n/choicfmt.cpp b/icu4c/source/i18n/choicfmt.cpp index 14dfeee5991..ad79ea0546a 100644 --- a/icu4c/source/i18n/choicfmt.cpp +++ b/icu4c/source/i18n/choicfmt.cpp @@ -613,6 +613,11 @@ ChoiceFormat::format(const Formattable* objs, FieldPosition& pos, UErrorCode& status) const { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return toAppendTo; + } + if(cnt < 0) { status = U_ILLEGAL_ARGUMENT_ERROR; return toAppendTo; diff --git a/icu4c/source/i18n/coll.cpp b/icu4c/source/i18n/coll.cpp index 6789a1ab14b..c63e628e285 100644 --- a/icu4c/source/i18n/coll.cpp +++ b/icu4c/source/i18n/coll.cpp @@ -98,6 +98,11 @@ Collator * Collator::createInstance(const Locale &loc, UVersionInfo version, UErrorCode &status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return 0; + } + Collator *collator; UVersionInfo info; diff --git a/icu4c/source/i18n/dcfmtsym.cpp b/icu4c/source/i18n/dcfmtsym.cpp index 061aba956b9..4cb1a979d48 100644 --- a/icu4c/source/i18n/dcfmtsym.cpp +++ b/icu4c/source/i18n/dcfmtsym.cpp @@ -152,13 +152,21 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, currencyElements[i] = currencyElementsRes.getStringEx(i, status); } - if (U_FAILURE(status)) return; + if (U_FAILURE(status)) { + /* clean the memory */ + delete[] numberElements; + delete[] currencyElements; + return; + } // If the array size is too small, something is wrong with the resource // bundle, returns the failure error code. if (numberElementsLength < 11 || currencyElementsLength < 3) { status = U_INVALID_FORMAT_ERROR; + /* clean the memory */ + delete[] numberElements; + delete[] currencyElements; return; } diff --git a/icu4c/source/i18n/decimfmt.cpp b/icu4c/source/i18n/decimfmt.cpp index ab5dcba31e4..dd02791f66d 100644 --- a/icu4c/source/i18n/decimfmt.cpp +++ b/icu4c/source/i18n/decimfmt.cpp @@ -193,6 +193,10 @@ DecimalFormat::construct(UErrorCode& status, const UnicodeString* pattern, DecimalFormatSymbols* symbolsToAdopt) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } fSymbols = symbolsToAdopt; // Do this BEFORE aborting on status failure!!! // fDigitList = new DigitList(); // Do this BEFORE aborting on status failure!!! fRoundingIncrement = NULL; @@ -1440,11 +1444,20 @@ DecimalFormat::setCurrencyForSymbols() { UErrorCode ec = U_ZERO_ERROR; DecimalFormatSymbols def(fSymbols->getLocale(), ec); + /* test for buffer overflows */ + if (U_FAILURE(ec)) { + currency[0] = 0; // Use DFS currency info + } + if (fSymbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol) == def.getSymbol(DecimalFormatSymbols::kCurrencySymbol) && fSymbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) == def.getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)) { ucurr_forLocale(fSymbols->getLocale().getName(), currency, &ec); + /* test for buffer overflows */ + if (U_FAILURE(ec)) { + currency[0] = 0; // Use DFS currency info + } } else { currency[0] = 0; // Use DFS currency info } diff --git a/icu4c/source/i18n/dtfmtsym.cpp b/icu4c/source/i18n/dtfmtsym.cpp index 8b463a61703..7f1a4eb5040 100644 --- a/icu4c/source/i18n/dtfmtsym.cpp +++ b/icu4c/source/i18n/dtfmtsym.cpp @@ -578,6 +578,11 @@ DateFormatSymbols::initializeData(const Locale& locale, UErrorCode& status, UBoo ResourceBundle zoneArray = resource.get(fgZoneStringsTag, status); fZoneStringsRowCount = zoneArray.getSize(); ResourceBundle zoneRow = zoneArray.get((int32_t)0, status); + + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } /* TODO: Fix the case where the zoneStrings is not a perfect square array of information. */ fZoneStringsColCount = zoneRow.getSize(); fZoneStrings = new UnicodeString * [fZoneStringsRowCount]; @@ -601,6 +606,10 @@ DateFormatSymbols::initializeData(const Locale& locale, UErrorCode& status, UBoo // {sfb} fixed to handle 1-based weekdays ResourceBundle weekdaysData = resource.get(fgDayNamesTag, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } fWeekdaysCount = weekdaysData.getSize(); fWeekdays = new UnicodeString[fWeekdaysCount+1]; /* test for NULL */ @@ -614,11 +623,16 @@ DateFormatSymbols::initializeData(const Locale& locale, UErrorCode& status, UBoo } ResourceBundle lsweekdaysData = resource.get(fgDayAbbreviationsTag, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } fShortWeekdaysCount = lsweekdaysData.getSize(); fShortWeekdays = new UnicodeString[fShortWeekdaysCount+1]; /* test for NULL */ if (fShortWeekdays == 0) { status = U_MEMORY_ALLOCATION_ERROR; + delete [] fWeekdays; return; } fShortWeekdays[0] = UnicodeString(); @@ -626,6 +640,12 @@ DateFormatSymbols::initializeData(const Locale& locale, UErrorCode& status, UBoo fShortWeekdays[i+1] = lsweekdaysData.getStringEx(i, status); } + /* test for buffer overflows */ + if (U_FAILURE(status)) { + delete [] fWeekdays; + delete [] fShortWeekdays; + return; + } fWeekdaysCount = fShortWeekdaysCount = 8; // If the locale data does not include new pattern chars, use the defaults diff --git a/icu4c/source/i18n/gregocal.cpp b/icu4c/source/i18n/gregocal.cpp index 30d7daa4c39..644b65ef03e 100644 --- a/icu4c/source/i18n/gregocal.cpp +++ b/icu4c/source/i18n/gregocal.cpp @@ -204,6 +204,10 @@ GregorianCalendar::GregorianCalendar(int32_t year, int32_t month, int32_t date, fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } set(Calendar::ERA, AD); set(Calendar::YEAR, year); set(Calendar::MONTH, month); @@ -219,6 +223,10 @@ GregorianCalendar::GregorianCalendar(int32_t year, int32_t month, int32_t date, fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } set(Calendar::ERA, AD); set(Calendar::YEAR, year); set(Calendar::MONTH, month); @@ -237,6 +245,10 @@ GregorianCalendar::GregorianCalendar(int32_t year, int32_t month, int32_t date, fNormalizedGregorianCutover(fGregorianCutover), fGregorianCutoverYear(1582) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } set(Calendar::ERA, AD); set(Calendar::YEAR, year); set(Calendar::MONTH, month); @@ -643,6 +655,10 @@ GregorianCalendar::computeFields(UErrorCode& status) // Time to fields takes the wall millis (Standard or DST). timeToFields(localMillis, FALSE, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } uint8_t era = (uint8_t) internalGetEra(); int32_t year = internalGet(YEAR); @@ -682,6 +698,10 @@ GregorianCalendar::computeFields(UErrorCode& status) timeToFields(dstMillis, FALSE, status); } + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } // Fill in all time-related fields based on millisInDay. Call internalSet() // so as not to perturb flags. internalSet(MILLISECOND, millisInDay % 1000); @@ -776,6 +796,10 @@ GregorianCalendar::boundsCheck(int32_t value, EDateFields field) const UDate GregorianCalendar::getEpochDay(UErrorCode& status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return 0.0; + } complete(status); // Divide by 1000 (convert to seconds) in order to prevent overflow when // dealing with UDate(Long.MIN_VALUE) and UDate(Long.MAX_VALUE). @@ -950,6 +974,10 @@ GregorianCalendar::computeTime(UErrorCode& status) monthLength(internalGet(MONTH)), status) - zoneOffset; + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } // Note: Because we pass in wall millisInDay, rather than // standard millisInDay, we interpret "1:00 am" on the day // of cessation of DST as "1:00 am Std" (assuming the time @@ -1524,6 +1552,10 @@ GregorianCalendar::roll(EDateFields field, int32_t amount, UErrorCode& status) int32_t min = 0, max = 0, gap; if (field >= 0 && field < FIELD_COUNT) { complete(status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } min = getMinimum(field); max = getMaximum(field); } @@ -1577,6 +1609,10 @@ GregorianCalendar::roll(EDateFields field, int32_t amount, UErrorCode& status) { // Assume min == 0 in calculations below UDate start = getTime(status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } int32_t oldHour = internalGet(field); int32_t newHour = (oldHour + amount) % (max + 1); if(newHour < 0) diff --git a/icu4c/source/i18n/msgfmt.cpp b/icu4c/source/i18n/msgfmt.cpp index b1d99e19175..8dfd19be970 100644 --- a/icu4c/source/i18n/msgfmt.cpp +++ b/icu4c/source/i18n/msgfmt.cpp @@ -777,6 +777,10 @@ MessageFormat::format( const UnicodeString& pattern, UnicodeString& result, UErrorCode& success) { + /* test for buffer overflows */ + if (U_FAILURE(success)) { + return result; + } // {sfb} why does this use a local when so many other places use a static? MessageFormat *temp = new MessageFormat(pattern, success); /* test for NULL */ @@ -828,6 +832,11 @@ MessageFormat::format(const Formattable* arguments, int32_t recursionProtection, UErrorCode& success) const { + /* test for buffer overflows */ + if (U_FAILURE(success)) { + return result; + } + if(/*arguments == NULL ||*/ cnt < 0) { success = U_ILLEGAL_ARGUMENT_ERROR; return result; @@ -862,6 +871,10 @@ MessageFormat::format(const Formattable* arguments, // refers to a ChoiceFormat object. if (fFormats[i] != NULL) { fFormats[i]->format(obj, arg, success); + /* test for buffer overflows */ + if (U_FAILURE(success)) { + return result; + } tryRecursion = (fFormats[i]->getDynamicClassID() == ChoiceFormat::getStaticClassID()); } // If the obj data type if a number, use a NumberFormat instance. diff --git a/icu4c/source/i18n/nfrs.cpp b/icu4c/source/i18n/nfrs.cpp index 6adaca601c8..d7e2607dfe0 100644 --- a/icu4c/source/i18n/nfrs.cpp +++ b/icu4c/source/i18n/nfrs.cpp @@ -185,6 +185,10 @@ NFRuleSet::parseRules(UnicodeString& description, const RuleBasedNumberFormat* o } currentDescription.setTo(description, oldP, p - oldP); NFRule::makeRules(currentDescription, this, rules.last(), owner, rules, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } oldP = p + 1; } diff --git a/icu4c/source/i18n/nfrule.cpp b/icu4c/source/i18n/nfrule.cpp index 22457002158..8929198497a 100644 --- a/icu4c/source/i18n/nfrule.cpp +++ b/icu4c/source/i18n/nfrule.cpp @@ -97,6 +97,10 @@ NFRule::makeRules(UnicodeString& description, NFRuleList& rules, UErrorCode& status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } // we know we're making at least one rule, so go ahead and // new it up and initialize its basevalue and divisor // (this also strips the rule descriptor, if any, off the @@ -108,6 +112,10 @@ NFRule::makeRules(UnicodeString& description, return; } rule1->parseRuleDescriptor(description, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } // check the description to see whether there's text enclosed // in brackets @@ -123,6 +131,10 @@ NFRule::makeRules(UnicodeString& description, || rule1->getType() == kNegativeNumberRule) { rule1->ruleText = description; rule1->extractSubstitutions(ruleSet, predecessor, rbnf, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } rules.add(rule1); } else { // if the description does contain a matched pair of brackets, @@ -184,6 +196,10 @@ NFRule::makeRules(UnicodeString& description, } rule2->ruleText.setTo(sbuf); rule2->extractSubstitutions(ruleSet, predecessor, rbnf, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } } // rule1's text includes the text in the brackets but omits @@ -196,6 +212,10 @@ NFRule::makeRules(UnicodeString& description, } rule1->ruleText.setTo(sbuf); rule1->extractSubstitutions(ruleSet, predecessor, rbnf, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } // if we only have one rule, return it; if we have two, return // a two-element array containing them (notice that rule2 goes @@ -224,6 +244,10 @@ NFRule::makeRules(UnicodeString& description, void NFRule::parseRuleDescriptor(UnicodeString& description, UErrorCode& status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } // the description consists of a rule descriptor and a rule body, // separated by a colon. The rule descriptor is optional. If // it's omitted, just set the base value to 0. @@ -402,6 +426,10 @@ NFRule::extractSubstitution(const NFRuleSet* ruleSet, const RuleBasedNumberFormat* rbnf, UErrorCode& status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return 0; + } NFSubstitution* result = NULL; // search the rule's rule text for the first two characters of @@ -1137,6 +1165,12 @@ NFRule::prefixLength(const UnicodeString& str, const UnicodeString& prefix) cons // match collation elements between the strings int32_t oStr = strIter->next(err); int32_t oPrefix = prefixIter->next(err); + /* test for buffer overflows */ + if (U_FAILURE(err)) { + delete prefixIter; + delete strIter; + return 0; + } while (oPrefix != CollationElementIterator::NULLORDER) { // skip over ignorable characters in the target string @@ -1151,6 +1185,13 @@ NFRule::prefixLength(const UnicodeString& str, const UnicodeString& prefix) cons oPrefix = prefixIter->next(err); } + /* test for buffer overflows */ + if (U_FAILURE(err)) { + delete prefixIter; + delete strIter; + return 0; + } + // dlf: move this above following test, if we consume the // entire target, aren't we ok even if the source was also // entirely consumed? @@ -1184,6 +1225,12 @@ NFRule::prefixLength(const UnicodeString& str, const UnicodeString& prefix) cons } else { oStr = strIter->next(err); oPrefix = prefixIter->next(err); + /* test for buffer overflows */ + if (U_FAILURE(err)) { + delete prefixIter; + delete strIter; + return 0; + } } } diff --git a/icu4c/source/i18n/numfmt.cpp b/icu4c/source/i18n/numfmt.cpp index b08a46af07b..b4c6d231120 100644 --- a/icu4c/source/i18n/numfmt.cpp +++ b/icu4c/source/i18n/numfmt.cpp @@ -452,6 +452,10 @@ NumberFormat::createInstance(const Locale& desiredLocale, } ResourceBundle numberPatterns(resource.get(DecimalFormat::fgNumberPatterns, status)); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return NULL; + } // If not all the styled patterns exists for the NumberFormat in this locale, // sets the status code to failure and returns nil. //if (patternCount < fgNumberPatternsCount) status = U_INVALID_FORMAT_ERROR; diff --git a/icu4c/source/i18n/rbt_data.cpp b/icu4c/source/i18n/rbt_data.cpp index a90c6c8aee8..50be68da86d 100644 --- a/icu4c/source/i18n/rbt_data.cpp +++ b/icu4c/source/i18n/rbt_data.cpp @@ -43,6 +43,11 @@ TransliterationRuleData::TransliterationRuleData(const TransliterationRuleData& { UErrorCode status = U_ZERO_ERROR; variableNames = new Hashtable(status); + /* test for NULL*/ + if (variableNames == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } if (U_SUCCESS(status)) { variableNames->setValueDeleter(uhash_deleteUnicodeString); int32_t pos = -1; @@ -50,7 +55,16 @@ TransliterationRuleData::TransliterationRuleData(const TransliterationRuleData& while ((e = other.variableNames->nextElement(pos)) != 0) { UnicodeString* value = new UnicodeString(*(const UnicodeString*)e->value.pointer); + /* test for NULL */ + if (value == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } variableNames->put(*(UnicodeString*)e->key.pointer, value, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } } } diff --git a/icu4c/source/i18n/rbt_set.cpp b/icu4c/source/i18n/rbt_set.cpp index e971a5270fa..052a47fa2cb 100644 --- a/icu4c/source/i18n/rbt_set.cpp +++ b/icu4c/source/i18n/rbt_set.cpp @@ -156,6 +156,10 @@ const char TransliterationRuleSet::fgClassID=0; * Construct a new empty rule set. */ TransliterationRuleSet::TransliterationRuleSet(UErrorCode& status) : UObject() { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } ruleVector = new UVector(&_deleteRule, NULL, status); rules = NULL; maxContextLength = 0; @@ -233,6 +237,10 @@ void TransliterationRuleSet::addRule(TransliterationRule* adoptedRule, return; } ruleVector->addElement(adoptedRule, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } int32_t len; if ((len = adoptedRule->getContextLength()) > maxContextLength) { @@ -311,6 +319,10 @@ void TransliterationRuleSet::freeze(UParseError& parseError,UErrorCode& status) } } } + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } uprv_free(indexValue); index[256] = v.size(); diff --git a/icu4c/source/i18n/simpletz.cpp b/icu4c/source/i18n/simpletz.cpp index c0c20808066..d9034479675 100644 --- a/icu4c/source/i18n/simpletz.cpp +++ b/icu4c/source/i18n/simpletz.cpp @@ -168,6 +168,10 @@ void SimpleTimeZone::construct(int32_t rawOffsetGMT, int32_t savingsDST, UErrorCode& status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } this->rawOffset = rawOffsetGMT; this->startMonth = savingsStartMonth; this->startDay = savingsStartDay; @@ -315,6 +319,10 @@ void SimpleTimeZone::setStartRule(int32_t month, int32_t dayOfWeekInMonth, int32_t dayOfWeek, int32_t time, TimeMode mode, UErrorCode& status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } startMonth = (int8_t)month; startDay = (int8_t)dayOfWeekInMonth; startDayOfWeek = (int8_t)dayOfWeek; @@ -366,6 +374,10 @@ void SimpleTimeZone::setEndRule(int32_t month, int32_t dayOfWeekInMonth, int32_t dayOfWeek, int32_t time, TimeMode mode, UErrorCode& status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } endMonth = (int8_t)month; endDay = (int8_t)dayOfWeekInMonth; endDayOfWeek = (int8_t)dayOfWeek; @@ -409,6 +421,10 @@ int32_t SimpleTimeZone::getOffset(uint8_t era, int32_t year, int32_t month, int32_t day, uint8_t dayOfWeek, int32_t millis, UErrorCode& status) const { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return 0; + } // Check the month before indexing into staticMonthLength. This // duplicates the test that occurs in the 7-argument getOffset(), // however, this is unavoidable. We don't mind because this method, in @@ -428,6 +444,10 @@ int32_t SimpleTimeZone::getOffset(uint8_t era, int32_t year, int32_t month, int32_t day, uint8_t dayOfWeek, int32_t millis, int32_t monthLength, UErrorCode& status) const { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return 0; + } // Check the month before indexing into staticMonthLength. This // duplicates a test that occurs in the 9-argument getOffset(), // however, this is unavoidable. We don't mind because this method, in @@ -696,6 +716,10 @@ UBool SimpleTimeZone::inDaylightTime(UDate date, UErrorCode& status) const status = U_MEMORY_ALLOCATION_ERROR; return FALSE; } + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return FALSE; + } gc->setTime(date, status); UBool result = gc->inDaylightTime(status); delete gc; @@ -803,6 +827,10 @@ SimpleTimeZone::hasSameRules(const TimeZone& other) const void SimpleTimeZone::decodeRules(UErrorCode& status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } decodeStartRule(status); decodeEndRule(status); } diff --git a/icu4c/source/i18n/smpdtfmt.cpp b/icu4c/source/i18n/smpdtfmt.cpp index 6e68002654f..7a39645e3c2 100644 --- a/icu4c/source/i18n/smpdtfmt.cpp +++ b/icu4c/source/i18n/smpdtfmt.cpp @@ -510,6 +510,10 @@ SimpleDateFormat::subFormat(UnicodeString& result, Calendar& cal, UErrorCode& status) const { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return result; + } // this function gets called by format() to produce the appropriate substitution // text for an individual pattern symbol (e.g., "HH" or "yyyy") @@ -615,6 +619,10 @@ SimpleDateFormat::subFormat(UnicodeString& result, value = cal.get(Calendar::ZONE_OFFSET, status) + cal.get(Calendar::DST_OFFSET, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return result; + } if (value < 0) { zoneString += fgGmtMinus; diff --git a/icu4c/source/i18n/stsearch.cpp b/icu4c/source/i18n/stsearch.cpp index 2b67dc63c6d..197d85f4d17 100644 --- a/icu4c/source/i18n/stsearch.cpp +++ b/icu4c/source/i18n/stsearch.cpp @@ -214,7 +214,11 @@ StringSearch & StringSearch::operator=(const StringSearch &that) m_text_.length(), that.m_strsrch_->collator, NULL, &status); - int32_t length; + /* test for buffer overflows */ + if (U_SUCCESS(status)) { + return *this; + } + int32_t length; const UChar *rules = ucol_getRules(m_strsrch_->collator, &length); m_collation_rules_.setTo(rules, length); m_collator_.setUCollator((UCollator *)m_strsrch_->collator, @@ -315,6 +319,10 @@ SearchIterator * StringSearch::safeClone(void) const status = U_MEMORY_ALLOCATION_ERROR; return 0; } + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return NULL; + } result->setOffset(getOffset(), status); result->setMatchStart(m_strsrch_->search->matchedIndex); result->setMatchLength(m_strsrch_->search->matchedLength); @@ -337,6 +345,10 @@ int32_t StringSearch::handleNext(int32_t position, UErrorCode &status) m_search_->matchedLength = 0; ucol_setOffset(m_strsrch_->textIter, m_search_->matchedIndex, &status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return USEARCH_DONE; + } if (m_search_->matchedIndex == m_search_->textLength) { m_search_->matchedIndex = USEARCH_DONE; } @@ -390,6 +402,10 @@ int32_t StringSearch::handlePrev(int32_t position, UErrorCode &status) m_search_->matchedIndex --; ucol_setOffset(m_strsrch_->textIter, m_search_->matchedIndex, &status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return USEARCH_DONE; + } m_search_->matchedLength = 0; } } diff --git a/icu4c/source/i18n/tblcoll.cpp b/icu4c/source/i18n/tblcoll.cpp index 8e270e151db..2c567df1ef7 100644 --- a/icu4c/source/i18n/tblcoll.cpp +++ b/icu4c/source/i18n/tblcoll.cpp @@ -147,6 +147,10 @@ RuleBasedCollator::construct(const UnicodeString& rules, UColAttributeValue decompositionMode, UErrorCode& status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } ucollator = ucol_openRules(rules.getBuffer(), rules.length(), decompositionMode, collationStrength, NULL, &status); diff --git a/icu4c/source/i18n/timezone.cpp b/icu4c/source/i18n/timezone.cpp index b5cf7e0bfe8..40ae81ce1d2 100644 --- a/icu4c/source/i18n/timezone.cpp +++ b/icu4c/source/i18n/timezone.cpp @@ -750,6 +750,10 @@ TimeZone::createCustomTimeZone(const UnicodeString& id) UErrorCode success = U_ZERO_ERROR; numberFormat = NumberFormat::createInstance(success); + /* test for buffer overflows */ + if (U_FAILURE(success)) { + return 0; + } numberFormat->setParseIntegerOnly(TRUE); diff --git a/icu4c/source/i18n/titletrn.cpp b/icu4c/source/i18n/titletrn.cpp index 88acf9484cd..bfff9153361 100644 --- a/icu4c/source/i18n/titletrn.cpp +++ b/icu4c/source/i18n/titletrn.cpp @@ -101,6 +101,10 @@ void TitlecaseTransliterator::handleTransliterate( SKIP = new UnicodeSet(UNICODE_STRING_SIMPLE("[\\u00AD \\u2019 \\' [:Mn:] [:Me:] [:Cf:] [:Lm:] [:Sk:]]"), ec); CASED = new UnicodeSet(UNICODE_STRING_SIMPLE("[[:Lu:] [:Ll:] [:Lt:]]"), ec); ucln_i18n_registerCleanup(); + /* test for buffer overflows */ + if (U_FAILURE(ec)) { + return; + } } } diff --git a/icu4c/source/i18n/translit.cpp b/icu4c/source/i18n/translit.cpp index f477c0a6d94..87f37472584 100644 --- a/icu4c/source/i18n/translit.cpp +++ b/icu4c/source/i18n/translit.cpp @@ -712,6 +712,10 @@ UnicodeString& Transliterator::getDisplayName(const UnicodeString& id, UErrorCode status = U_ZERO_ERROR; ResourceBundle bundle(u_getDataDirectory(), inLocale, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return result; + } // Suspend checking status until later... diff --git a/icu4c/source/i18n/transreg.cpp b/icu4c/source/i18n/transreg.cpp index 710bf37e5fe..167be89467b 100644 --- a/icu4c/source/i18n/transreg.cpp +++ b/icu4c/source/i18n/transreg.cpp @@ -84,6 +84,11 @@ TransliteratorAlias::~TransliteratorAlias() { Transliterator* TransliteratorAlias::create(UParseError& pe, UErrorCode& ec) { + /* test for buffer overflows */ + if (U_FAILURE(ec)) { + return 0; + } + Transliterator *t; if (trans == 0) { t = Transliterator::createInstance(aliasID, UTRANS_FORWARD, pe, ec); @@ -466,6 +471,10 @@ TransliteratorRegistry::TransliteratorRegistry(UErrorCode& status) : specDAG(TRUE), availableIDs(status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } registry.setValueDeleter(deleteEntry); availableIDs.setDeleter(uhash_deleteUnicodeString); availableIDs.setComparer(uhash_compareCaselessUnicodeString); @@ -480,6 +489,10 @@ Transliterator* TransliteratorRegistry::get(const UnicodeString& ID, TransliteratorAlias*& aliasReturn, UParseError& parseError, UErrorCode& status) { + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return 0; + } Entry *entry = find(ID); return (entry == 0) ? 0 : instantiateEntry(ID, entry, aliasReturn, parseError,status); @@ -691,6 +704,10 @@ void TransliteratorRegistry::registerEntry(const UnicodeString& ID, UBool visible) { UErrorCode status = U_ZERO_ERROR; registry.put(ID, adopted, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } if (visible) { registerSTV(source, target, variant); if (!availableIDs.contains((void*) &ID)) { @@ -722,6 +739,10 @@ void TransliteratorRegistry::registerSTV(const UnicodeString& source, } targets->setValueDeleter(uhash_deleteUVector); specDAG.put(source, targets, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } } UVector *variants = (UVector*) targets->get(target); if (variants == 0) { @@ -731,6 +752,10 @@ void TransliteratorRegistry::registerSTV(const UnicodeString& source, return; } targets->put(target, variants, status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } } // assert(NO_VARIANT == ""); // We add the variant string. If it is the special "no variant" diff --git a/icu4c/source/i18n/ucol.cpp b/icu4c/source/i18n/ucol.cpp index 70ecd91b379..17ce99cb45d 100644 --- a/icu4c/source/i18n/ucol.cpp +++ b/icu4c/source/i18n/ucol.cpp @@ -1364,6 +1364,10 @@ void collPrevIterNormalize(collIterate *data) normLen = unorm_normalize(pStart, (pEnd - pStart) + 1, UNORM_NFD, 0, data->writableBuffer, 0, &status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } if (data->writableBufSize <= normLen) { freeHeapWritableBuffer(data); @@ -1382,6 +1386,10 @@ void collPrevIterNormalize(collIterate *data) *(pStartNorm - 1) = 0; unorm_normalize(pStart, (pEnd - pStart) + 1, UNORM_NFD, 0, pStartNorm, normLen, &status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } data->pos = data->writableBuffer + data->writableBufSize; data->origFlags = data->flags; @@ -1506,6 +1514,10 @@ static inline uint32_t ucol_IGetPrevCE(const UCollator *coll, collIterate *data, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } uint32_t result = UCOL_NULLORDER; if (data->CEpos > data->CEs) { data->toReturn --; @@ -1668,6 +1680,10 @@ ucol_getPrevCE(const UCollator *coll, collIterate *data, /* this should be connected to special Jamo handling */ U_CAPI uint32_t U_EXPORT2 ucol_getFirstCE(const UCollator *coll, UChar u, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } collIterate colIt; uint32_t order; IInit_collIterate(coll, &u, 1, &colIt); @@ -1787,6 +1803,10 @@ inline void normalizeNextContraction(collIterate *data) normLen = unorm_normalize(pStart, pEnd - pStart, UNORM_NFD, 0, buffer, 0, &status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } if (buffersize <= normLen + strsize) { uint32_t size = strsize + normLen + 1; @@ -1803,6 +1823,10 @@ inline void normalizeNextContraction(collIterate *data) /* null-termination will be added here */ unorm_normalize(pStart, pEnd - pStart, UNORM_NFD, 0, pStartNorm, normLen + 1, &status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } data->pos = data->writableBuffer + strsize; data->origFlags = data->flags; @@ -2093,7 +2117,10 @@ uint32_t ucol_prv_getSpecialCE(const UCollator *coll, UChar ch, uint32_t CE, col collIterateState entryState; backupState(source, &entryState); UChar32 cp = ch; - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } //UChar *entryPos = source->pos; for (;;) { // This loop will repeat only in the case of contractions, and only when a contraction @@ -2633,6 +2660,10 @@ inline void normalizePrevContraction(collIterate *data) normLen = unorm_normalize(pStart, pEnd - pStart, UNORM_NFD, 0, buffer, 0, &status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } if (nulltermsize <= normLen) { uint32_t size = buffersize - nulltermsize + normLen + 1; @@ -2654,6 +2685,10 @@ inline void normalizePrevContraction(collIterate *data) *(pStartNorm - 1) = 0; unorm_normalize(pStart, pEnd - pStart, UNORM_NFD, 0, pStartNorm, normLen, &status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return; + } data->pos = data->writableBuffer + nulltermsize; data->origFlags = data->flags; @@ -2784,6 +2819,10 @@ uint32_t ucol_prv_getSpecialPrevCE(const UCollator *coll, UChar ch, uint32_t CE, uint32_t *endCEBuffer; UChar *strbuffer; int32_t noChars = 0; + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } for(;;) { @@ -2997,6 +3036,10 @@ uint32_t ucol_prv_getSpecialPrevCE(const UCollator *coll, UChar ch, uint32_t CE, temp.flags &= ~UCOL_ITER_NORM; CE = ucol_IGetNextCE(coll, &temp, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } endCEBuffer = source->CEs + UCOL_EXPAND_CE_BUFFER_SIZE; while (CE != UCOL_NO_MORE_CES) { *(source->CEpos ++) = CE; @@ -3013,6 +3056,10 @@ uint32_t ucol_prv_getSpecialPrevCE(const UCollator *coll, UChar ch, uint32_t CE, return UCOL_NULLORDER; } CE = ucol_IGetNextCE(coll, &temp, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } } freeHeapWritableBuffer(&temp); if (strbuffer != buffer) { @@ -3195,6 +3242,10 @@ uint32_t ucol_prv_getSpecialPrevCE(const UCollator *coll, UChar ch, uint32_t CE, /* anyway */ static uint8_t *reallocateBuffer(uint8_t **secondaries, uint8_t *secStart, uint8_t *second, uint32_t *secSize, uint32_t newSize, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } #ifdef UCOL_DEBUG fprintf(stderr, "."); #endif @@ -3425,6 +3476,10 @@ int32_t ucol_getSortKeySize(const UCollator *coll, collIterate *s, int32_t curre for(;;) { order = ucol_IGetNextCE(coll, s, &status); + /* test for buffer overflows */ + if (U_FAILURE(status)) { + return 0; + } if(order == UCOL_NO_MORE_CES) { break; @@ -3854,6 +3909,10 @@ ucol_calcSortKey(const UCollator *coll, for(i=prevBuffSize; ifirst; uint32_t tokStrength = tok->strength; @@ -362,6 +365,10 @@ U_CFUNC uint32_t ucol_getSimpleCEGenerator(ucolCEGenerator *g, UColToken *tok, u /* TODO: rename to enum names */ uint32_t high, low, count=1; uint32_t maxByte = (strength == UCOL_TERTIARY)?0x3F:0xFF; + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } if(strength == UCOL_SECONDARY) { low = UCOL_COMMON_TOP2<<24; @@ -387,6 +394,10 @@ U_CFUNC uint32_t ucol_getSimpleCEGenerator(ucolCEGenerator *g, UColToken *tok, u } U_CFUNC uint32_t ucol_getCEGenerator(ucolCEGenerator *g, uint32_t* lows, uint32_t* highs, UColToken *tok, uint32_t fStrength, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } uint32_t strength = tok->strength; uint32_t low = lows[fStrength*3+strength]; uint32_t high = highs[fStrength*3+strength]; @@ -492,7 +503,10 @@ U_CFUNC void ucol_doCE(uint32_t *CEparts, UColToken *tok) { } U_CFUNC void ucol_initBuffers(UColTokenParser *src, UColTokListHeader *lh, UErrorCode *status) { - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } ucolCEGenerator Gens[UCOL_CE_STRENGTH_LIMIT]; uint32_t CEparts[UCOL_CE_STRENGTH_LIMIT]; @@ -525,6 +539,10 @@ U_CFUNC void ucol_initBuffers(UColTokenParser *src, UColTokListHeader *lh, UErro tok->toInsert = t[tok->strength]; ucol_inv_getGapPositions(src, lh, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } #if UCOL_DEBUG fprintf(stderr, "BaseCE: %08X %08X\n", lh->baseCE, lh->baseContCE); diff --git a/icu4c/source/i18n/ucol_cnt.cpp b/icu4c/source/i18n/ucol_cnt.cpp index 043c1c0ddbc..eb1db80f9ec 100644 --- a/icu4c/source/i18n/ucol_cnt.cpp +++ b/icu4c/source/i18n/ucol_cnt.cpp @@ -25,6 +25,10 @@ U_NAMESPACE_BEGIN void uprv_growTable(ContractionTable *tbl, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } if(tbl->position == tbl->size) { uint32_t *newData = (uint32_t *)uprv_realloc(tbl->CEs, 2*tbl->size*sizeof(uint32_t)); if(newData == NULL) { @@ -73,6 +77,10 @@ uprv_cnttab_open(UNewTrie *mapping, UErrorCode *status) { } ContractionTable *addATableElement(CntTable *table, uint32_t *key, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } ContractionTable *el = (ContractionTable *)uprv_malloc(sizeof(ContractionTable)); if(el == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; @@ -225,6 +233,10 @@ uprv_cnttab_constructTable(CntTable *table, uint32_t mainOffset, UErrorCode *sta } ContractionTable *uprv_cnttab_cloneContraction(ContractionTable *t, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } ContractionTable *r = (ContractionTable *)uprv_malloc(sizeof(ContractionTable)); if(r == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; @@ -278,6 +290,10 @@ uprv_cnttab_clone(CntTable *t, UErrorCode *status) { for(i = 0; isize; i++) { r->elements[i] = uprv_cnttab_cloneContraction(t->elements[i], status); } + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } if(t->CEs != NULL) { r->CEs = (uint32_t *)uprv_malloc(t->position*sizeof(uint32_t)); @@ -370,6 +386,10 @@ uprv_cnttab_insertContraction(CntTable *table, uint32_t element, UChar codePoint uprv_growTable(tbl, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } uint32_t offset = 0; @@ -410,6 +430,10 @@ uprv_cnttab_addContraction(CntTable *table, uint32_t element, UChar codePoint, u uprv_growTable(tbl, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } tbl->CEs[tbl->position] = value; tbl->codePoints[tbl->position] = codePoint; @@ -432,6 +456,10 @@ uprv_cnttab_setContraction(CntTable *table, uint32_t element, uint32_t offset, U if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) { tbl = addATableElement(table, &element, status); } + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } if(offset >= tbl->size) { *status = U_INDEX_OUTOFBOUNDS_ERROR; diff --git a/icu4c/source/i18n/ucol_elm.cpp b/icu4c/source/i18n/ucol_elm.cpp index 456aad4d830..223e3a143b6 100644 --- a/icu4c/source/i18n/ucol_elm.cpp +++ b/icu4c/source/i18n/ucol_elm.cpp @@ -126,6 +126,10 @@ uhash_freeBlockWrapper(void *obj) { U_CAPI tempUCATable* U_EXPORT2 uprv_uca_initTempTable(UCATableHeader *image, UColOptionSet *opts, const UCollator *UCA, UColCETags initTag, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } tempUCATable *t = (tempUCATable *)uprv_malloc(sizeof(tempUCATable)); /* test for NULL */ if (t == NULL) { @@ -166,9 +170,17 @@ uprv_uca_initTempTable(UCATableHeader *image, UColOptionSet *opts, const UCollat /*t->mapping = ucmpe32_open(UCOL_SPECIAL_FLAG | (initTag<<24), UCOL_SPECIAL_FLAG | (SURROGATE_TAG<<24), UCOL_SPECIAL_FLAG | (LEAD_SURROGATE_TAG<<24), status);*/ t->mapping = utrie_open(NULL, NULL, 0x100000, UCOL_SPECIAL_FLAG | (initTag<<24), TRUE); // Do your own mallocs for the structure, array and have linear Latin 1 t->prefixLookup = uhash_open(prefixLookupHash, prefixLookupComp, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } uhash_setValueDeleter(t->prefixLookup, uhash_freeBlock); t->contractions = uprv_cnttab_open(t->mapping, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } /* copy UCA's maxexpansion and merge as we go along */ t->maxExpansions = maxet; @@ -279,6 +291,10 @@ uprv_uca_cloneTempTable(tempUCATable *t, UErrorCode *status) { if(t->contractions != NULL) { r->contractions = uprv_cnttab_clone(t->contractions, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } r->contractions->mapping = r->mapping; } @@ -421,6 +437,10 @@ int uprv_uca_setMaxExpansion(uint32_t endexpansion, MaxExpansionTable *maxexpansion, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } if (maxexpansion->size == 0) { /* we'll always make the first element 0, for easier manipulation */ maxexpansion->endExpansionCE = @@ -564,6 +584,10 @@ int uprv_uca_setMaxJamoExpansion(UChar ch, MaxJamoExpansionTable *maxexpansion, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } UBool isV = TRUE; if (((uint32_t)ch - 0x1100) <= (0x1112 - 0x1100)) { /* determines L for Jamo, doesn't need to store this since it is never @@ -721,6 +745,10 @@ uint32_t uprv_uca_addPrefix(tempUCATable *t, uint32_t CE, // long. Although this table could quite easily mimic complete contraction stuff // there is no good reason to make a general solution, as it would require some // error prone messing. + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } CntTable *contractions = t->contractions; UChar32 cp; uint32_t cpsize = 0; @@ -852,6 +880,10 @@ uint32_t uprv_uca_addPrefix(tempUCATable *t, uint32_t CE, // would complicate code way too much. uint32_t uprv_uca_addContraction(tempUCATable *t, uint32_t CE, UCAElements *element, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } CntTable *contractions = t->contractions; UChar32 cp; uint32_t cpsize = 0; @@ -942,6 +974,10 @@ static uint32_t uprv_uca_processContraction(CntTable *contractions, UCAElements return element->mapCE; /*can't do just that. existingCe might be a contraction, meaning that we need to do another step */ } } + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return UCOL_NOT_FOUND; + } /* this recursion currently feeds on the only element we have... We will have to copy it in order to accomodate */ /* for both backward and forward cycles */ @@ -976,6 +1012,10 @@ static uint32_t uprv_uca_processContraction(CntTable *contractions, UCAElements } static uint32_t uprv_uca_finalizeAddition(tempUCATable *t, UCAElements *element, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } uint32_t CE = UCOL_NOT_FOUND; // This should add a completely ignorable element to the // unsafe table, so that backward iteration will skip @@ -1101,6 +1141,10 @@ uprv_uca_addAnElement(tempUCATable *t, UCAElements *element, UErrorCode *status) } } + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } // here we want to add the prefix structure. // I will try to process it as a reverse contraction, if possible. // prefix buffer is already reversed. @@ -1154,6 +1198,10 @@ uprv_uca_addAnElement(tempUCATable *t, UCAElements *element, UErrorCode *status) if(element->cSize > 1 && !(element->cSize==2 && UTF16_IS_LEAD(element->cPoints[0]) && UTF16_IS_TRAIL(element->cPoints[1]))) { // this is a contraction, we should check whether a composed form should also be included UnicodeString source(element->cPoints, element->cSize); CanonicalIterator it(source, *status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } source = it.next(); while(source.length() > 0) { if(Normalizer::quickCheck(source, UNORM_FCD, *status) != UNORM_NO) { @@ -1186,12 +1234,20 @@ void uprv_uca_getMaxExpansionJamo(UNewTrie *mapping, uint32_t v = VBASE + VCOUNT - 1; uint32_t t = TBASE + TCOUNT - 1; uint32_t ce; + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } while (v >= VBASE) { /*ce = ucmpe32_get(mapping, v);*/ ce = utrie_get32(mapping, v, NULL); if (ce < UCOL_SPECIAL_FLAG) { uprv_uca_setMaxExpansion(ce, 2, maxexpansion, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } } v --; } @@ -1202,6 +1258,10 @@ void uprv_uca_getMaxExpansionJamo(UNewTrie *mapping, ce = utrie_get32(mapping, t, NULL); if (ce < UCOL_SPECIAL_FLAG) { uprv_uca_setMaxExpansion(ce, 3, maxexpansion, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } } t --; } @@ -1315,6 +1375,10 @@ uprv_uca_assembleTable(tempUCATable *t, UErrorCode *status) { // After setting the jamo expansions, compact the trie and get the needed size int32_t mappingSize = utrie_serialize(mapping, NULL, 0, getFoldedValue /*getFoldedValue*/, FALSE, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } uint32_t tableOffset = 0; uint8_t *dataStart; @@ -1396,6 +1460,10 @@ uprv_uca_assembleTable(tempUCATable *t, UErrorCode *status) { myData->mappingPosition = tableOffset; utrie_serialize(mapping, dataStart+tableOffset, toAllocate-tableOffset, getFoldedValue, FALSE, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } #ifdef UCOL_DEBUG // This is debug code to dump the contents of the trie. It needs two functions defined above { @@ -1436,6 +1504,10 @@ uprv_uca_assembleTable(tempUCATable *t, UErrorCode *status) { /* Unsafe chars table. Finish it off, then copy it. */ uprv_uca_unsafeCPAddCCNZ(t, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } if (t->UCA != 0) { /* Or in unsafebits from UCA, making a combined table. */ for (i=0; iunsafeCP[i] |= t->UCA->unsafeCP[i]; diff --git a/icu4c/source/i18n/ucol_tok.cpp b/icu4c/source/i18n/ucol_tok.cpp index 2ddc58f506a..1c3b1b3cf36 100644 --- a/icu4c/source/i18n/ucol_tok.cpp +++ b/icu4c/source/i18n/ucol_tok.cpp @@ -639,7 +639,10 @@ ucol_tok_parseNextToken(UColTokenParser *src, UParseError *parseError, UErrorCode *status) { /* parsing part */ - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } UBool variableTop = FALSE; UBool top = FALSE; UBool inChars = TRUE; @@ -1008,6 +1011,11 @@ Processing Description static UColToken *ucol_tok_initAReset(UColTokenParser *src, UChar *expand, uint32_t *expandNext, UParseError *parseError, UErrorCode *status) { + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } + if(src->resultLen == src->listCapacity) { // Unfortunately, this won't work, as we store addresses of lhs in token src->listCapacity *= 2; @@ -1101,6 +1109,10 @@ inline UColToken *getVirginBefore(UColTokenParser *src, UColToken *sourceToken, baseCE = ucol_getNextCE(src->UCA, &s, status) & 0xFFFFFF3F; baseContCE = ucol_getNextCE(src->UCA, &s, status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return NULL; + } if(baseContCE == UCOL_NO_MORE_CES) { baseContCE = 0; } @@ -1170,7 +1182,10 @@ uint32_t ucol_tok_assembleTokenList(UColTokenParser *src, UParseError *parseErro UBool variableTop = FALSE; UBool top = FALSE; uint16_t specs = 0; - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } UColTokListHeader *ListList = NULL; src->parsedToken.strength = UCOL_TOK_UNSET; diff --git a/icu4c/source/i18n/umsg.cpp b/icu4c/source/i18n/umsg.cpp index 497b7ada61e..6ff55ce6d58 100644 --- a/icu4c/source/i18n/umsg.cpp +++ b/icu4c/source/i18n/umsg.cpp @@ -39,14 +39,20 @@ u_formatMessage(const char *locale, { va_list ap; int32_t actLen; - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } //argument checking defered to subsequent method calls // start vararg processing va_start(ap, status); actLen = u_vformatMessage(locale,pattern,patternLength,result,resultLength,ap,status); - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } // end vararg processing va_end(ap); @@ -64,7 +70,10 @@ u_vformatMessage( const char *locale, { //argument checking defered to subsequent method calls - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } UMessageFormat *fmt = umsg_open(pattern,patternLength,locale,NULL,status); int32_t retVal = umsg_vformat(fmt,result,resultLength,ap,status); umsg_close(fmt); @@ -84,12 +93,18 @@ u_formatMessageWithError(const char *locale, va_list ap; int32_t actLen; //argument checking defered to subsequent method calls - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } // start vararg processing va_start(ap, status); actLen = u_vformatMessageWithError(locale,pattern,patternLength,result,resultLength,parseError,ap,status); - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } // end vararg processing va_end(ap); @@ -108,7 +123,10 @@ u_vformatMessageWithError( const char *locale, { //argument checking defered to subsequent method calls - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } UMessageFormat *fmt = umsg_open(pattern,patternLength,locale,parseError,status); int32_t retVal = umsg_vformat(fmt,result,resultLength,ap,status); umsg_close(fmt); @@ -130,14 +148,20 @@ u_parseMessage( const char *locale, ...) { va_list ap; - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } //argument checking defered to subsequent method calls // start vararg processing va_start(ap, status); u_vparseMessage(locale,pattern,patternLength,source,sourceLength,ap,status); - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } // end vararg processing va_end(ap); } @@ -152,7 +176,10 @@ u_vparseMessage(const char *locale, UErrorCode *status) { //argument checking defered to subsequent method calls - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } UMessageFormat *fmt = umsg_open(pattern,patternLength,locale,NULL,status); int32_t count = 0; umsg_vparse(fmt,source,sourceLength,&count,ap,status); @@ -172,12 +199,19 @@ u_parseMessageWithError(const char *locale, va_list ap; //argument checking defered to subsequent method calls + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } // start vararg processing va_start(ap, status); u_vparseMessageWithError(locale,pattern,patternLength,source,sourceLength,ap,error,status); - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } // end vararg processing va_end(ap); } @@ -192,7 +226,10 @@ u_vparseMessageWithError(const char *locale, UErrorCode* status) { //argument checking defered to subsequent method calls - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } UMessageFormat *fmt = umsg_open(pattern,patternLength,locale,error,status); int32_t count = 0; umsg_vparse(fmt,source,sourceLength,&count,ap,status); @@ -351,7 +388,10 @@ umsg_format( UMessageFormat *fmt, { va_list ap; int32_t actLen; - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return 0; + } //argument checking defered to last method call umsg_vformat which //saves time when arguments are valid and we dont care when arguments are not //since we return an error anyway @@ -454,7 +494,10 @@ umsg_parse( UMessageFormat *fmt, ...) { va_list ap; - + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } //argument checking defered to last method call umsg_vparse which //saves time when arguments are valid and we dont care when arguments are not //since we return an error anyway @@ -491,6 +534,10 @@ umsg_vparse(UMessageFormat *fmt, UnicodeString srcString(source,sourceLength); Formattable *args = ((MessageFormat*)fmt)->parse(source,*count,*status); + /* test for buffer overflows */ + if (U_FAILURE(*status)) { + return; + } UDate *aDate; double *aDouble; UChar *aString;