From 6f094669a285019799314ac3c1d29743d31b0df1 Mon Sep 17 00:00:00 2001 From: Syn Wee Quek Date: Tue, 9 Sep 2003 23:51:17 +0000 Subject: [PATCH] ICU-2092 error status checks added X-SVN-Rev: 13050 --- icu4c/source/common/brkiter.cpp | 59 +++++++++++++++---------- icu4c/source/common/dbbi.cpp | 38 +++++++++++++--- icu4c/source/common/rbbi.cpp | 4 +- icu4c/source/common/rbbirb.cpp | 36 +++++++++------- icu4c/source/common/rbbiscan.cpp | 7 ++- icu4c/source/common/rbbisetb.cpp | 31 ++++++++++++- icu4c/source/common/rbbistbl.cpp | 5 ++- icu4c/source/common/rbbitblb.cpp | 74 ++++++++++++++++++++++++++++++-- 8 files changed, 196 insertions(+), 58 deletions(-) diff --git a/icu4c/source/common/brkiter.cpp b/icu4c/source/common/brkiter.cpp index a8ed306abd..7aa5042d96 100644 --- a/icu4c/source/common/brkiter.cpp +++ b/icu4c/source/common/brkiter.cpp @@ -80,15 +80,17 @@ BreakIterator::makeWordInstance(const Locale& key, UErrorCode& status) else { result = new RuleBasedBreakIterator(file, status); } + if (U_FAILURE(status)) { // Sometimes redundant check, but simple. + if (result != NULL) { + delete result; + } + return NULL; + } if (result == NULL) { udata_close(file); status = U_MEMORY_ALLOCATION_ERROR; } - if (U_FAILURE(status)) { // Sometimes redundant check, but simple. - delete result; - result = NULL; - } - + return result; } @@ -131,14 +133,16 @@ BreakIterator::makeLineInstance(const Locale& key, UErrorCode& status) else { result = new RuleBasedBreakIterator(file, status); } + if (U_FAILURE(status)) { // Sometimes redundant check, but simple. + if (result != NULL) { + delete result; + } + return NULL; + } if (result == NULL) { udata_close(file); status = U_MEMORY_ALLOCATION_ERROR; } - if (U_FAILURE(status)) { // Sometimes redundant check, but simple. - delete result; - result = NULL; - } return result; } @@ -169,14 +173,17 @@ BreakIterator::makeCharacterInstance(const Locale& /* key */, UErrorCode& status // The UDataMemory is adopted by the break iterator. result = new RuleBasedBreakIterator(file, status); + + if (U_FAILURE(status)) { // Sometimes redundant check, but simple. + if (result != NULL) { + delete result; + } + return NULL; + } if (result == NULL) { udata_close(file); status = U_MEMORY_ALLOCATION_ERROR; } - if (U_FAILURE(status)) { // Sometimes redundant check, but simple. - delete result; - result = NULL; - } return result; } @@ -207,14 +214,16 @@ BreakIterator::makeSentenceInstance(const Locale& /*key */, UErrorCode& status) // The UDataMemory is adopted by the break iterator. result = new RuleBasedBreakIterator(file, status); + if (U_FAILURE(status)) { // Sometimes redundant check, but simple. + if (result != NULL) { + delete result; + } + return NULL; + } if (result == NULL) { udata_close(file); status = U_MEMORY_ALLOCATION_ERROR; } - if (U_FAILURE(status)) { // Sometimes redundant check, but simple. - delete result; - result = NULL; - } return result; } @@ -246,14 +255,16 @@ BreakIterator::makeTitleInstance(const Locale& /* key */, UErrorCode& status) // The UDataMemory is adopted by the break iterator. result = new RuleBasedBreakIterator(file, status); + if (U_FAILURE(status)) { // Sometimes redundant check, but simple. + if (result != NULL) { + delete result; + } + return NULL; + } if (result == NULL) { udata_close(file); status = U_MEMORY_ALLOCATION_ERROR; } - if (U_FAILURE(status)) { // Sometimes redundant check, but simple. - delete result; - result = NULL; - } return result; } @@ -437,8 +448,10 @@ BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status) case UBRK_SENTENCE: return BreakIterator::makeSentenceInstance(loc, status); case UBRK_TITLE: return BreakIterator::makeTitleInstance(loc, status); default: - status = U_ILLEGAL_ARGUMENT_ERROR; - return NULL; + if (U_SUCCESS(status)) { + status = U_ILLEGAL_ARGUMENT_ERROR; + } + return NULL; } } diff --git a/icu4c/source/common/dbbi.cpp b/icu4c/source/common/dbbi.cpp index 8f77a5b8d5..11f593a66d 100644 --- a/icu4c/source/common/dbbi.cpp +++ b/icu4c/source/common/dbbi.cpp @@ -43,17 +43,18 @@ DictionaryBasedBreakIterator::DictionaryBasedBreakIterator(UDataMemory* rbbiData init(); if (U_FAILURE(status)) {return;}; fTables = new DictionaryBasedBreakIteratorTables(dictionaryFilename, status); + if (U_FAILURE(status)) { + if (fTables != NULL) { + fTables->removeReference(); + fTables = NULL; + } + return; + } /* test for NULL */ if(fTables == 0) { status = U_MEMORY_ALLOCATION_ERROR; return; } - - if (U_FAILURE(status)) { - fTables->removeReference(); - fTables = NULL; - return; - } } @@ -396,6 +397,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t c = fText->next(); } + if (U_FAILURE(status)) { + return; // UStack below overwrites the status error codes + } // initialize. We maintain two stacks: currentBreakPositions contains // the list of break positions that will be returned if we successfully @@ -412,7 +416,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t // further, this saves us from having to follow each possible path // through the text all the way to the error (hopefully avoiding many // future recursive calls as well). - UStack currentBreakPositions(status); + // there can be only one kind of error in UStack and UVector, so we'll + // just let the error fall through + UStack currentBreakPositions(status); UStack possibleBreakPositions(status); UVector wrongBreakPositions(status); @@ -445,6 +451,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t // the possible-break-positions stack if (fTables->fDictionary->at(state, (int32_t)0) == -1) { possibleBreakPositions.push(fText->getIndex(), status); + if (U_FAILURE(status)) { + return; + } } // look up the new state to transition to in the dictionary @@ -456,6 +465,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t // of the loop. if (state == -1) { currentBreakPositions.push(fText->getIndex(), status); + if (U_FAILURE(status)) { + return; + } break; } @@ -501,6 +513,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t currentBreakPositions.removeAllElements(); for (int32_t i = 0; i < bestBreakPositions.size(); i++) { currentBreakPositions.push(bestBreakPositions.elementAti(i), status); + if (U_FAILURE(status)) { + return; + } } bestBreakPositions.removeAllElements(); if (farthestEndPoint < endPos) { @@ -515,9 +530,15 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t || currentBreakPositions.peeki() != fText->getIndex()) && fText->getIndex() != startPos) { currentBreakPositions.push(fText->getIndex(), status); + if (U_FAILURE(status)) { + return; + } } fText->next(); currentBreakPositions.push(fText->getIndex(), status); + if (U_FAILURE(status)) { + return; + } } } @@ -561,6 +582,9 @@ DictionaryBasedBreakIterator::divideUpDictionaryRange(int32_t startPos, int32_t currentBreakPositions.popi(); } currentBreakPositions.push(endPos, status); + if (U_FAILURE(status)) { + return; + } // create a regular array to hold the break positions and copy // the break positions from the stack to the array (in addition, diff --git a/icu4c/source/common/rbbi.cpp b/icu4c/source/common/rbbi.cpp index c72cc717fb..bfac688828 100644 --- a/icu4c/source/common/rbbi.cpp +++ b/icu4c/source/common/rbbi.cpp @@ -46,8 +46,8 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedBreakIterator) RuleBasedBreakIterator::RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode &status) { init(); + fData = new RBBIDataWrapper(data, status); // status checked in constructor if (U_FAILURE(status)) {return;} - fData = new RBBIDataWrapper(data, status); if(fData == 0) { status = U_MEMORY_ALLOCATION_ERROR; return; @@ -63,8 +63,8 @@ RuleBasedBreakIterator::RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode RuleBasedBreakIterator::RuleBasedBreakIterator(UDataMemory* udm, UErrorCode &status) { init(); + fData = new RBBIDataWrapper(udm, status); // status checked in constructor if (U_FAILURE(status)) {return;} - fData = new RBBIDataWrapper(udm, status); if(fData == 0) { status = U_MEMORY_ALLOCATION_ERROR; return; diff --git a/icu4c/source/common/rbbirb.cpp b/icu4c/source/common/rbbirb.cpp index 409c5ab0e9..01d175f2a1 100644 --- a/icu4c/source/common/rbbirb.cpp +++ b/icu4c/source/common/rbbirb.cpp @@ -47,7 +47,7 @@ RBBIRuleBuilder::RBBIRuleBuilder(const UnicodeString &rules, UErrorCode &status) : fRules(rules) { - fStatus = &status; + fStatus = &status; // status is checked below fParseError = &parseErr; fDebugEnv = NULL; #ifdef RBBI_DEBUG @@ -59,9 +59,18 @@ RBBIRuleBuilder::RBBIRuleBuilder(const UnicodeString &rules, fReverseTree = NULL; fForwardTables = NULL; fReverseTables = NULL; - fUSetNodes = new UVector(status); + + UErrorCode oldstatus = status; + + fUSetNodes = new UVector(status); // bcos status gets overwritten here fScanner = new RBBIRuleScanner(this); fSetBuilder = new RBBISetBuilder(this); + if (U_FAILURE(oldstatus)) { + status = oldstatus; + } + if (U_FAILURE(status)) { + return; + } if(fSetBuilder == 0 || fScanner == 0 || fUSetNodes == 0) { status = U_MEMORY_ALLOCATION_ERROR; } @@ -176,9 +185,7 @@ RBBIRuleBuilder::createRuleBasedBreakIterator( const UnicodeString &rules, UParseError &parseError, UErrorCode &status) { - if (U_FAILURE(status)) { - return NULL; - } + // status checked below // // Read the input rules, generate a parse tree, symbol table, @@ -186,7 +193,7 @@ RBBIRuleBuilder::createRuleBasedBreakIterator( const UnicodeString &rules, // RBBIRuleBuilder builder(rules, parseError, status); builder.fScanner->parse(); - if (U_FAILURE(status)) { + if (U_FAILURE(status)) { // status checked here bcos build below doesn't return NULL; } @@ -204,7 +211,9 @@ RBBIRuleBuilder::createRuleBasedBreakIterator( const UnicodeString &rules, // builder.fForwardTables = new RBBITableBuilder(&builder, &builder.fForwardTree); builder.fReverseTables = new RBBITableBuilder(&builder, &builder.fReverseTree); - if(builder.fForwardTables == NULL || builder.fReverseTables == NULL) { + if (U_SUCCESS(status) + && (builder.fForwardTables == NULL || builder.fReverseTables == NULL)) + { status = U_MEMORY_ALLOCATION_ERROR; return NULL; } @@ -220,8 +229,7 @@ RBBIRuleBuilder::createRuleBasedBreakIterator( const UnicodeString &rules, // Package up the compiled data into a memory image // in the run-time format. // - RBBIDataHeader *data; - data = builder.flattenData(); + RBBIDataHeader *data = builder.flattenData(); // returns NULL if error // @@ -233,16 +241,14 @@ RBBIRuleBuilder::createRuleBasedBreakIterator( const UnicodeString &rules, // Create a break iterator from the compiled rules. // (Identical to creation from stored pre-compiled rules) // + // status is checked after init in construction. RuleBasedBreakIterator *This = new RuleBasedBreakIterator(data, status); - /* test for NULL */ - if(This == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } - if (U_FAILURE(status)) { delete This; This = NULL; + } + else if(This == NULL) { // test for NULL + status = U_MEMORY_ALLOCATION_ERROR; } return This; } diff --git a/icu4c/source/common/rbbiscan.cpp b/icu4c/source/common/rbbiscan.cpp index c5f15635fa..ccc3455cb4 100644 --- a/icu4c/source/common/rbbiscan.cpp +++ b/icu4c/source/common/rbbiscan.cpp @@ -88,6 +88,9 @@ U_NAMESPACE_BEGIN //---------------------------------------------------------------------------------------- RBBIRuleScanner::RBBIRuleScanner(RBBIRuleBuilder *rb) { + if (U_FAILURE(*rb->fStatus)) { + return; + } fRB = rb; fStackPtr = 0; fStack[fStackPtr] = 0; @@ -113,10 +116,6 @@ RBBIRuleScanner::RBBIRuleScanner(RBBIRuleBuilder *rb) fCharNum = 0; fQuoteMode = FALSE; - if (U_FAILURE(*rb->fStatus)) { - return; - } - // // Set up the constant Unicode Sets. // Note: These could be made static, lazily initialized, and shared among diff --git a/icu4c/source/common/rbbisetb.cpp b/icu4c/source/common/rbbisetb.cpp index 41c442ab26..5f4933550b 100644 --- a/icu4c/source/common/rbbisetb.cpp +++ b/icu4c/source/common/rbbisetb.cpp @@ -135,10 +135,13 @@ void RBBISetBuilder::build() { // Initialize the process by creating a single range encompassing all characters // that is in no sets. // - fRangeList = new RangeDescriptor(*fStatus); + fRangeList = new RangeDescriptor(*fStatus); // will check for status here fRangeList->fStartChar = 0; fRangeList->fEndChar = 0x10ffff; + if (U_FAILURE(*fStatus)) { + return; + } // // Find the set of non-overlapping ranges of characters @@ -176,6 +179,9 @@ void RBBISetBuilder::build() { // over if (rlRange->fStartChar < inputSetRangeBegin) { rlRange->split(inputSetRangeBegin, *fStatus); + if (U_FAILURE(*fStatus)) { + return; + } continue; } @@ -186,12 +192,18 @@ void RBBISetBuilder::build() { // wholly inside the Unicode set. if (rlRange->fEndChar > inputSetRangeEnd) { rlRange->split(inputSetRangeEnd+1, *fStatus); + if (U_FAILURE(*fStatus)) { + return; + } } // The current rlRange is now entirely within the UnicodeSet range. // Add this unicode set to the list of sets for this rlRange if (rlRange->fIncludesSets->indexOf(usetNode) == -1) { rlRange->fIncludesSets->addElement(usetNode, *fStatus); + if (U_FAILURE(*fStatus)) { + return; + } } // Advance over ranges that we are finished with. @@ -475,7 +487,14 @@ RangeDescriptor::RangeDescriptor(const RangeDescriptor &other, UErrorCode &statu this->fEndChar = other.fEndChar; this->fNum = other.fNum; this->fNext = NULL; + UErrorCode oldstatus = status; this->fIncludesSets = new UVector(status); + if (U_FAILURE(oldstatus)) { + status = oldstatus; + } + if (U_FAILURE(status)) { + return; + } /* test for NULL */ if (this->fIncludesSets == 0) { status = U_MEMORY_ALLOCATION_ERROR; @@ -498,7 +517,14 @@ RangeDescriptor::RangeDescriptor(UErrorCode &status) { this->fEndChar = 0; this->fNum = 0; this->fNext = NULL; + UErrorCode oldstatus = status; this->fIncludesSets = new UVector(status); + if (U_FAILURE(oldstatus)) { + status = oldstatus; + } + if (U_FAILURE(status)) { + return; + } /* test for NULL */ if(this->fIncludesSets == 0) { status = U_MEMORY_ALLOCATION_ERROR; @@ -526,6 +552,9 @@ RangeDescriptor::~RangeDescriptor() { void RangeDescriptor::split(UChar32 where, UErrorCode &status) { U_ASSERT(where>fStartChar && where<=fEndChar); RangeDescriptor *nr = new RangeDescriptor(*this, status); + if (U_FAILURE(status)) { + return; + } /* test for NULL */ if(nr == 0) { status = U_MEMORY_ALLOCATION_ERROR; diff --git a/icu4c/source/common/rbbistbl.cpp b/icu4c/source/common/rbbistbl.cpp index 99e22123da..26261b1380 100644 --- a/icu4c/source/common/rbbistbl.cpp +++ b/icu4c/source/common/rbbistbl.cpp @@ -43,11 +43,12 @@ RBBISymbolTable::RBBISymbolTable(RBBIRuleScanner *rs, const UnicodeString &rules { fHashTable = NULL; fCachedSetLookup = NULL; + + fHashTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, &status); + // uhash_open checks status if (U_FAILURE(status)) { return; } - - fHashTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, &status); uhash_setValueDeleter(fHashTable, RBBISymbolTableEntry_deleter); } diff --git a/icu4c/source/common/rbbitblb.cpp b/icu4c/source/common/rbbitblb.cpp index 2fd1063a8e..f1add55666 100644 --- a/icu4c/source/common/rbbitblb.cpp +++ b/icu4c/source/common/rbbitblb.cpp @@ -27,7 +27,18 @@ RBBITableBuilder::RBBITableBuilder(RBBIRuleBuilder *rb, RBBINode **rootNode) : fTree(*rootNode) { fRB = rb; fStatus = fRB->fStatus; - fDStates = new UVector(*fStatus); + UErrorCode status = U_ZERO_ERROR; + fDStates = new UVector(status); + if (U_FAILURE(*fStatus)) { + return; + } + if (U_FAILURE(status)) { + *fStatus = status; + return; + } + if (fDStates == NULL) { + *fStatus = U_MEMORY_ALLOCATION_ERROR;; + } } @@ -309,19 +320,37 @@ void RBBITableBuilder::calcFollowPos(RBBINode *n) { // //----------------------------------------------------------------------------- void RBBITableBuilder::buildStateTable() { + if (U_FAILURE(*fStatus)) { + return; + } // // Add a dummy state 0 - the stop state. Not from Aho. int lastInputSymbol = fRB->fSetBuilder->getNumCharCategories() - 1; RBBIStateDescriptor *failState = new RBBIStateDescriptor(lastInputSymbol, fStatus); failState->fPositions = new UVector(*fStatus); + if (U_FAILURE(*fStatus)) { + return; + } fDStates->addElement(failState, *fStatus); + if (U_FAILURE(*fStatus)) { + return; + } // initially, the only unmarked state in Dstates is firstpos(root), // where toot is the root of the syntax tree for (r)#; RBBIStateDescriptor *initialState = new RBBIStateDescriptor(lastInputSymbol, fStatus); + if (U_FAILURE(*fStatus)) { + return; + } initialState->fPositions = new UVector(*fStatus); + if (U_FAILURE(*fStatus)) { + return; + } setAdd(initialState->fPositions, fTree->fFirstPosSet); fDStates->addElement(initialState, *fStatus); + if (U_FAILURE(*fStatus)) { + return; + } // while there is an unmarked state T in Dstates do begin for (;;) { @@ -383,8 +412,14 @@ void RBBITableBuilder::buildStateTable() { if (!UinDstates) { RBBIStateDescriptor *newState = new RBBIStateDescriptor(lastInputSymbol, fStatus); + if (U_FAILURE(*fStatus)) { + return; + } newState->fPositions = U; fDStates->addElement(newState, *fStatus); + if (U_FAILURE(*fStatus)) { + return; + } ux = fDStates->size()-1; } @@ -407,12 +442,22 @@ void RBBITableBuilder::buildStateTable() { // //----------------------------------------------------------------------------- void RBBITableBuilder::flagAcceptingStates() { + if (U_FAILURE(*fStatus)) { + return; + } UVector endMarkerNodes(*fStatus); RBBINode *endMarker; int32_t i; int32_t n; + if (U_FAILURE(*fStatus)) { + return; + } + fTree->findNodes(&endMarkerNodes, RBBINode::endMark, *fStatus); + if (U_FAILURE(*fStatus)) { + return; + } for (i=0; ifindNodes(&lookAheadNodes, RBBINode::lookAhead, *fStatus); + if (U_FAILURE(*fStatus)) { + return; + } for (i=0; ifindNodes(&tagNodes, RBBINode::tag, *fStatus); + if (U_FAILURE(*fStatus)) { + return; + } for (i=0; isize(); int32_t si, di; - for (si=0; sielementAt(si); for (di=0; dielementAt(di) == elToAdd) { @@ -515,7 +575,7 @@ void RBBITableBuilder::setAdd(UVector *dest, UVector *source) { } } dest->addElement(elToAdd, *fStatus); - elementAlreadyInDest: ; + elementAlreadyInDest: ; } } @@ -730,10 +790,16 @@ RBBIStateDescriptor::RBBIStateDescriptor(int lastInputSymbol, UErrorCode *fStatu fTagVal = 0; fPositions = NULL; fDtran = NULL; + + UErrorCode status = U_ZERO_ERROR; + fDtran = new UVector(lastInputSymbol+1, status); if (U_FAILURE(*fStatus)) { return; } - fDtran = new UVector(lastInputSymbol+1, *fStatus); + if (U_FAILURE(status)) { + *fStatus = status; + return; + } if (fDtran == NULL) { *fStatus = U_MEMORY_ALLOCATION_ERROR; return;